From a3ed03bcaddf8bb17a0e7bc2d0ed440e328a2380 Mon Sep 17 00:00:00 2001 From: benjamyn Date: Sat, 29 Dec 2018 10:09:18 +1100 Subject: [PATCH] Initial commit --- PyGeoIP.py | 62 + cc.csv | 249 + .../__pycache__/ipwhois_cli.cpython-37.pyc | Bin 0 -> 29564 bytes .../ipwhois_utils_cli.cpython-37.pyc | Bin 0 -> 4445 bytes env/bin/activate | 78 + env/bin/activate.csh | 36 + env/bin/activate.fish | 76 + env/bin/activate_this.py | 34 + env/bin/easy_install | 11 + env/bin/easy_install-3.7 | 11 + env/bin/ipwhois_cli.py | 1517 +++ env/bin/ipwhois_utils_cli.py | 269 + env/bin/pip | 11 + env/bin/pip3 | 11 + env/bin/pip3.7 | 11 + env/bin/python | Bin 0 -> 14096 bytes env/bin/python-config | 78 + env/bin/python3 | 1 + env/bin/python3.7 | 1 + env/bin/wheel | 11 + env/include/python3.7m | 1 + env/lib/python3.7/__future__.py | 1 + .../__pycache__/__future__.cpython-37.pyc | Bin 0 -> 4157 bytes .../__pycache__/_bootlocale.cpython-37.pyc | Bin 0 -> 1274 bytes .../_collections_abc.cpython-37.pyc | Bin 0 -> 28967 bytes .../__pycache__/_weakrefset.cpython-37.pyc | Bin 0 -> 7487 bytes .../python3.7/__pycache__/abc.cpython-37.pyc | Bin 0 -> 6476 bytes .../__pycache__/base64.cpython-37.pyc | Bin 0 -> 17013 bytes .../__pycache__/bisect.cpython-37.pyc | Bin 0 -> 2723 bytes .../__pycache__/codecs.cpython-37.pyc | Bin 0 -> 33923 bytes .../python3.7/__pycache__/copy.cpython-37.pyc | Bin 0 -> 7126 bytes .../__pycache__/copyreg.cpython-37.pyc | Bin 0 -> 4269 bytes .../python3.7/__pycache__/enum.cpython-37.pyc | Bin 0 -> 23963 bytes .../__pycache__/fnmatch.cpython-37.pyc | Bin 0 -> 3362 bytes .../__pycache__/functools.cpython-37.pyc | Bin 0 -> 23974 bytes .../__pycache__/genericpath.cpython-37.pyc | Bin 0 -> 3773 bytes .../__pycache__/hashlib.cpython-37.pyc | Bin 0 -> 6616 bytes .../__pycache__/heapq.cpython-37.pyc | Bin 0 -> 14387 bytes .../python3.7/__pycache__/hmac.cpython-37.pyc | Bin 0 -> 6138 bytes .../python3.7/__pycache__/imp.cpython-37.pyc | Bin 0 -> 9778 bytes .../python3.7/__pycache__/io.cpython-37.pyc | Bin 0 -> 3434 bytes .../__pycache__/keyword.cpython-37.pyc | Bin 0 -> 1834 bytes .../__pycache__/linecache.cpython-37.pyc | Bin 0 -> 3814 bytes .../__pycache__/locale.cpython-37.pyc | Bin 0 -> 34580 bytes .../__pycache__/operator.cpython-37.pyc | Bin 0 -> 13925 bytes .../python3.7/__pycache__/os.cpython-37.pyc | Bin 0 -> 29718 bytes .../__pycache__/posixpath.cpython-37.pyc | Bin 0 -> 10421 bytes .../__pycache__/random.cpython-37.pyc | Bin 0 -> 19419 bytes .../python3.7/__pycache__/re.cpython-37.pyc | Bin 0 -> 13829 bytes .../__pycache__/reprlib.cpython-37.pyc | Bin 0 -> 5375 bytes .../__pycache__/shutil.cpython-37.pyc | Bin 0 -> 30570 bytes .../python3.7/__pycache__/site.cpython-37.pyc | Bin 0 -> 20653 bytes .../__pycache__/sre_compile.cpython-37.pyc | Bin 0 -> 15228 bytes .../__pycache__/sre_constants.cpython-37.pyc | Bin 0 -> 6316 bytes .../__pycache__/sre_parse.cpython-37.pyc | Bin 0 -> 21382 bytes .../python3.7/__pycache__/stat.cpython-37.pyc | Bin 0 -> 3898 bytes .../__pycache__/struct.cpython-37.pyc | Bin 0 -> 359 bytes .../__pycache__/tarfile.cpython-37.pyc | Bin 0 -> 61866 bytes .../__pycache__/tempfile.cpython-37.pyc | Bin 0 -> 22170 bytes .../__pycache__/token.cpython-37.pyc | Bin 0 -> 3624 bytes .../__pycache__/tokenize.cpython-37.pyc | Bin 0 -> 17856 bytes .../__pycache__/types.cpython-37.pyc | Bin 0 -> 8999 bytes .../__pycache__/warnings.cpython-37.pyc | Bin 0 -> 13791 bytes .../__pycache__/weakref.cpython-37.pyc | Bin 0 -> 19135 bytes env/lib/python3.7/_bootlocale.py | 1 + env/lib/python3.7/_collections_abc.py | 1 + env/lib/python3.7/_dummy_thread.py | 1 + env/lib/python3.7/_weakrefset.py | 1 + env/lib/python3.7/abc.py | 1 + env/lib/python3.7/base64.py | 1 + env/lib/python3.7/bisect.py | 1 + env/lib/python3.7/codecs.py | 1 + env/lib/python3.7/collections | 1 + .../python3.7/config-3.7m-x86_64-linux-gnu | 1 + env/lib/python3.7/copy.py | 1 + env/lib/python3.7/copyreg.py | 1 + env/lib/python3.7/distutils/__init__.py | 101 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2856 bytes env/lib/python3.7/distutils/distutils.cfg | 6 + env/lib/python3.7/encodings | 1 + env/lib/python3.7/enum.py | 1 + env/lib/python3.7/fnmatch.py | 1 + env/lib/python3.7/functools.py | 1 + env/lib/python3.7/genericpath.py | 1 + env/lib/python3.7/hashlib.py | 1 + env/lib/python3.7/heapq.py | 1 + env/lib/python3.7/hmac.py | 1 + env/lib/python3.7/imp.py | 1 + env/lib/python3.7/importlib | 1 + env/lib/python3.7/io.py | 1 + env/lib/python3.7/keyword.py | 1 + env/lib/python3.7/lib-dynload | 1 + env/lib/python3.7/linecache.py | 1 + env/lib/python3.7/locale.py | 1 + env/lib/python3.7/no-global-site-packages.txt | 0 env/lib/python3.7/ntpath.py | 1 + env/lib/python3.7/operator.py | 1 + env/lib/python3.7/orig-prefix.txt | 1 + env/lib/python3.7/os.py | 1 + env/lib/python3.7/posixpath.py | 1 + env/lib/python3.7/random.py | 1 + env/lib/python3.7/re.py | 1 + env/lib/python3.7/reprlib.py | 1 + env/lib/python3.7/rlcompleter.py | 1 + env/lib/python3.7/shutil.py | 1 + .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 281 bytes .../python3.7/site-packages/dns/__init__.py | 56 + .../dns/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 610 bytes .../dns/__pycache__/_compat.cpython-37.pyc | Bin 0 -> 1733 bytes .../dns/__pycache__/dnssec.cpython-37.pyc | Bin 0 -> 12003 bytes .../dns/__pycache__/e164.cpython-37.pyc | Bin 0 -> 3208 bytes .../dns/__pycache__/edns.cpython-37.pyc | Bin 0 -> 7212 bytes .../dns/__pycache__/entropy.cpython-37.pyc | Bin 0 -> 3306 bytes .../dns/__pycache__/exception.cpython-37.pyc | Bin 0 -> 4119 bytes .../dns/__pycache__/flags.cpython-37.pyc | Bin 0 -> 2226 bytes .../dns/__pycache__/grange.cpython-37.pyc | Bin 0 -> 999 bytes .../dns/__pycache__/hash.cpython-37.pyc | Bin 0 -> 645 bytes .../dns/__pycache__/inet.cpython-37.pyc | Bin 0 -> 2410 bytes .../dns/__pycache__/ipv4.cpython-37.pyc | Bin 0 -> 1382 bytes .../dns/__pycache__/ipv6.cpython-37.pyc | Bin 0 -> 3057 bytes .../dns/__pycache__/message.cpython-37.pyc | Bin 0 -> 30487 bytes .../dns/__pycache__/name.cpython-37.pyc | Bin 0 -> 28440 bytes .../dns/__pycache__/namedict.cpython-37.pyc | Bin 0 -> 3002 bytes .../dns/__pycache__/node.cpython-37.pyc | Bin 0 -> 5757 bytes .../dns/__pycache__/opcode.cpython-37.pyc | Bin 0 -> 2174 bytes .../dns/__pycache__/query.cpython-37.pyc | Bin 0 -> 17205 bytes .../dns/__pycache__/rcode.cpython-37.pyc | Bin 0 -> 2675 bytes .../dns/__pycache__/rdata.cpython-37.pyc | Bin 0 -> 13710 bytes .../dns/__pycache__/rdataclass.cpython-37.pyc | Bin 0 -> 2427 bytes .../dns/__pycache__/rdataset.cpython-37.pyc | Bin 0 -> 9418 bytes .../dns/__pycache__/rdatatype.cpython-37.pyc | Bin 0 -> 5027 bytes .../dns/__pycache__/renderer.cpython-37.pyc | Bin 0 -> 7968 bytes .../dns/__pycache__/resolver.cpython-37.pyc | Bin 0 -> 33613 bytes .../__pycache__/reversename.cpython-37.pyc | Bin 0 -> 2526 bytes .../dns/__pycache__/rrset.cpython-37.pyc | Bin 0 -> 5376 bytes .../dns/__pycache__/set.cpython-37.pyc | Bin 0 -> 7444 bytes .../dns/__pycache__/tokenizer.cpython-37.pyc | Bin 0 -> 14095 bytes .../dns/__pycache__/tsig.cpython-37.pyc | Bin 0 -> 6223 bytes .../__pycache__/tsigkeyring.cpython-37.pyc | Bin 0 -> 1080 bytes .../dns/__pycache__/ttl.cpython-37.pyc | Bin 0 -> 1346 bytes .../dns/__pycache__/update.cpython-37.pyc | Bin 0 -> 7374 bytes .../dns/__pycache__/version.cpython-37.pyc | Bin 0 -> 475 bytes .../dns/__pycache__/wiredata.cpython-37.pyc | Bin 0 -> 2267 bytes .../dns/__pycache__/zone.cpython-37.pyc | Bin 0 -> 31027 bytes .../python3.7/site-packages/dns/_compat.py | 59 + env/lib/python3.7/site-packages/dns/dnssec.py | 519 ++ env/lib/python3.7/site-packages/dns/e164.py | 105 + env/lib/python3.7/site-packages/dns/edns.py | 269 + .../python3.7/site-packages/dns/entropy.py | 148 + .../python3.7/site-packages/dns/exception.py | 128 + env/lib/python3.7/site-packages/dns/flags.py | 130 + env/lib/python3.7/site-packages/dns/grange.py | 69 + env/lib/python3.7/site-packages/dns/hash.py | 37 + env/lib/python3.7/site-packages/dns/inet.py | 124 + env/lib/python3.7/site-packages/dns/ipv4.py | 63 + env/lib/python3.7/site-packages/dns/ipv6.py | 181 + .../python3.7/site-packages/dns/message.py | 1175 +++ env/lib/python3.7/site-packages/dns/name.py | 994 ++ .../python3.7/site-packages/dns/namedict.py | 108 + env/lib/python3.7/site-packages/dns/node.py | 182 + env/lib/python3.7/site-packages/dns/opcode.py | 119 + env/lib/python3.7/site-packages/dns/py.typed | 0 env/lib/python3.7/site-packages/dns/query.py | 683 ++ env/lib/python3.7/site-packages/dns/rcode.py | 144 + env/lib/python3.7/site-packages/dns/rdata.py | 456 + .../python3.7/site-packages/dns/rdataclass.py | 122 + .../python3.7/site-packages/dns/rdataset.py | 347 + .../python3.7/site-packages/dns/rdatatype.py | 287 + .../site-packages/dns/rdtypes/ANY/AFSDB.py | 55 + .../site-packages/dns/rdtypes/ANY/AVC.py | 25 + .../site-packages/dns/rdtypes/ANY/CAA.py | 75 + .../site-packages/dns/rdtypes/ANY/CDNSKEY.py | 27 + .../site-packages/dns/rdtypes/ANY/CDS.py | 23 + .../site-packages/dns/rdtypes/ANY/CERT.py | 123 + .../site-packages/dns/rdtypes/ANY/CNAME.py | 27 + .../site-packages/dns/rdtypes/ANY/CSYNC.py | 126 + .../site-packages/dns/rdtypes/ANY/DLV.py | 23 + .../site-packages/dns/rdtypes/ANY/DNAME.py | 26 + .../site-packages/dns/rdtypes/ANY/DNSKEY.py | 27 + .../site-packages/dns/rdtypes/ANY/DS.py | 23 + .../site-packages/dns/rdtypes/ANY/EUI48.py | 29 + .../site-packages/dns/rdtypes/ANY/EUI64.py | 29 + .../site-packages/dns/rdtypes/ANY/GPOS.py | 162 + .../site-packages/dns/rdtypes/ANY/HINFO.py | 86 + .../site-packages/dns/rdtypes/ANY/HIP.py | 115 + .../site-packages/dns/rdtypes/ANY/ISDN.py | 99 + .../site-packages/dns/rdtypes/ANY/LOC.py | 327 + .../site-packages/dns/rdtypes/ANY/MX.py | 23 + .../site-packages/dns/rdtypes/ANY/NS.py | 23 + .../site-packages/dns/rdtypes/ANY/NSEC.py | 128 + .../site-packages/dns/rdtypes/ANY/NSEC3.py | 196 + .../dns/rdtypes/ANY/NSEC3PARAM.py | 90 + .../dns/rdtypes/ANY/OPENPGPKEY.py | 60 + .../site-packages/dns/rdtypes/ANY/PTR.py | 23 + .../site-packages/dns/rdtypes/ANY/RP.py | 82 + .../site-packages/dns/rdtypes/ANY/RRSIG.py | 158 + .../site-packages/dns/rdtypes/ANY/RT.py | 23 + .../site-packages/dns/rdtypes/ANY/SOA.py | 116 + .../site-packages/dns/rdtypes/ANY/SPF.py | 25 + .../site-packages/dns/rdtypes/ANY/SSHFP.py | 79 + .../site-packages/dns/rdtypes/ANY/TLSA.py | 84 + .../site-packages/dns/rdtypes/ANY/TXT.py | 23 + .../site-packages/dns/rdtypes/ANY/URI.py | 82 + .../site-packages/dns/rdtypes/ANY/X25.py | 66 + .../site-packages/dns/rdtypes/ANY/__init__.py | 57 + .../ANY/__pycache__/AFSDB.cpython-37.pyc | Bin 0 -> 1124 bytes .../ANY/__pycache__/AVC.cpython-37.pyc | Bin 0 -> 475 bytes .../ANY/__pycache__/CAA.cpython-37.pyc | Bin 0 -> 2125 bytes .../ANY/__pycache__/CDNSKEY.cpython-37.pyc | Bin 0 -> 507 bytes .../ANY/__pycache__/CDS.cpython-37.pyc | Bin 0 -> 384 bytes .../ANY/__pycache__/CERT.cpython-37.pyc | Bin 0 -> 3075 bytes .../ANY/__pycache__/CNAME.cpython-37.pyc | Bin 0 -> 595 bytes .../ANY/__pycache__/CSYNC.cpython-37.pyc | Bin 0 -> 3239 bytes .../ANY/__pycache__/DLV.cpython-37.pyc | Bin 0 -> 384 bytes .../ANY/__pycache__/DNAME.cpython-37.pyc | Bin 0 -> 552 bytes .../ANY/__pycache__/DNSKEY.cpython-37.pyc | Bin 0 -> 504 bytes .../rdtypes/ANY/__pycache__/DS.cpython-37.pyc | Bin 0 -> 381 bytes .../ANY/__pycache__/EUI48.cpython-37.pyc | Bin 0 -> 567 bytes .../ANY/__pycache__/EUI64.cpython-37.pyc | Bin 0 -> 567 bytes .../ANY/__pycache__/GPOS.cpython-37.pyc | Bin 0 -> 4181 bytes .../ANY/__pycache__/HINFO.cpython-37.pyc | Bin 0 -> 2087 bytes .../ANY/__pycache__/HIP.cpython-37.pyc | Bin 0 -> 3265 bytes .../ANY/__pycache__/ISDN.cpython-37.pyc | Bin 0 -> 2315 bytes .../ANY/__pycache__/LOC.cpython-37.pyc | Bin 0 -> 8286 bytes .../rdtypes/ANY/__pycache__/MX.cpython-37.pyc | Bin 0 -> 381 bytes .../rdtypes/ANY/__pycache__/NS.cpython-37.pyc | Bin 0 -> 381 bytes .../ANY/__pycache__/NSEC.cpython-37.pyc | Bin 0 -> 3304 bytes .../ANY/__pycache__/NSEC3.cpython-37.pyc | Bin 0 -> 4581 bytes .../ANY/__pycache__/NSEC3PARAM.cpython-37.pyc | Bin 0 -> 2382 bytes .../ANY/__pycache__/OPENPGPKEY.cpython-37.pyc | Bin 0 -> 1711 bytes .../ANY/__pycache__/PTR.cpython-37.pyc | Bin 0 -> 384 bytes .../rdtypes/ANY/__pycache__/RP.cpython-37.pyc | Bin 0 -> 2348 bytes .../ANY/__pycache__/RRSIG.cpython-37.pyc | Bin 0 -> 4484 bytes .../rdtypes/ANY/__pycache__/RT.cpython-37.pyc | Bin 0 -> 399 bytes .../ANY/__pycache__/SOA.cpython-37.pyc | Bin 0 -> 3333 bytes .../ANY/__pycache__/SPF.cpython-37.pyc | Bin 0 -> 407 bytes .../ANY/__pycache__/SSHFP.cpython-37.pyc | Bin 0 -> 2176 bytes .../ANY/__pycache__/TLSA.cpython-37.pyc | Bin 0 -> 2307 bytes .../ANY/__pycache__/TXT.cpython-37.pyc | Bin 0 -> 387 bytes .../ANY/__pycache__/URI.cpython-37.pyc | Bin 0 -> 2296 bytes .../ANY/__pycache__/X25.cpython-37.pyc | Bin 0 -> 1775 bytes .../ANY/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 579 bytes .../site-packages/dns/rdtypes/CH/A.py | 70 + .../site-packages/dns/rdtypes/CH/__init__.py | 22 + .../rdtypes/CH/__pycache__/A.cpython-37.pyc | Bin 0 -> 2211 bytes .../CH/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 209 bytes .../site-packages/dns/rdtypes/IN/A.py | 54 + .../site-packages/dns/rdtypes/IN/AAAA.py | 55 + .../site-packages/dns/rdtypes/IN/APL.py | 165 + .../site-packages/dns/rdtypes/IN/DHCID.py | 61 + .../site-packages/dns/rdtypes/IN/IPSECKEY.py | 150 + .../site-packages/dns/rdtypes/IN/KX.py | 23 + .../site-packages/dns/rdtypes/IN/NAPTR.py | 127 + .../site-packages/dns/rdtypes/IN/NSAP.py | 60 + .../site-packages/dns/rdtypes/IN/NSAP_PTR.py | 23 + .../site-packages/dns/rdtypes/IN/PX.py | 89 + .../site-packages/dns/rdtypes/IN/SRV.py | 83 + .../site-packages/dns/rdtypes/IN/WKS.py | 107 + .../site-packages/dns/rdtypes/IN/__init__.py | 33 + .../rdtypes/IN/__pycache__/A.cpython-37.pyc | Bin 0 -> 1548 bytes .../IN/__pycache__/AAAA.cpython-37.pyc | Bin 0 -> 1603 bytes .../rdtypes/IN/__pycache__/APL.cpython-37.pyc | Bin 0 -> 3880 bytes .../IN/__pycache__/DHCID.cpython-37.pyc | Bin 0 -> 1717 bytes .../IN/__pycache__/IPSECKEY.cpython-37.pyc | Bin 0 -> 3646 bytes .../rdtypes/IN/__pycache__/KX.cpython-37.pyc | Bin 0 -> 388 bytes .../IN/__pycache__/NAPTR.cpython-37.pyc | Bin 0 -> 3344 bytes .../IN/__pycache__/NSAP.cpython-37.pyc | Bin 0 -> 1750 bytes .../IN/__pycache__/NSAP_PTR.cpython-37.pyc | Bin 0 -> 406 bytes .../rdtypes/IN/__pycache__/PX.cpython-37.pyc | Bin 0 -> 2373 bytes .../rdtypes/IN/__pycache__/SRV.cpython-37.pyc | Bin 0 -> 2327 bytes .../rdtypes/IN/__pycache__/WKS.cpython-37.pyc | Bin 0 -> 2786 bytes .../IN/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 322 bytes .../site-packages/dns/rdtypes/__init__.py | 27 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 255 bytes .../__pycache__/dnskeybase.cpython-37.pyc | Bin 0 -> 3659 bytes .../rdtypes/__pycache__/dsbase.cpython-37.pyc | Bin 0 -> 2369 bytes .../__pycache__/euibase.cpython-37.pyc | Bin 0 -> 2180 bytes .../rdtypes/__pycache__/mxbase.cpython-37.pyc | Bin 0 -> 3512 bytes .../rdtypes/__pycache__/nsbase.cpython-37.pyc | Bin 0 -> 2710 bytes .../__pycache__/txtbase.cpython-37.pyc | Bin 0 -> 2470 bytes .../site-packages/dns/rdtypes/dnskeybase.py | 138 + .../site-packages/dns/rdtypes/dsbase.py | 85 + .../site-packages/dns/rdtypes/euibase.py | 71 + .../site-packages/dns/rdtypes/mxbase.py | 103 + .../site-packages/dns/rdtypes/nsbase.py | 83 + .../site-packages/dns/rdtypes/txtbase.py | 97 + .../python3.7/site-packages/dns/renderer.py | 291 + .../python3.7/site-packages/dns/resolver.py | 1383 +++ .../site-packages/dns/reversename.py | 96 + env/lib/python3.7/site-packages/dns/rrset.py | 189 + env/lib/python3.7/site-packages/dns/set.py | 261 + .../python3.7/site-packages/dns/tokenizer.py | 571 ++ env/lib/python3.7/site-packages/dns/tsig.py | 236 + .../site-packages/dns/tsigkeyring.py | 50 + env/lib/python3.7/site-packages/dns/ttl.py | 70 + env/lib/python3.7/site-packages/dns/update.py | 279 + .../python3.7/site-packages/dns/version.py | 43 + .../python3.7/site-packages/dns/wiredata.py | 103 + env/lib/python3.7/site-packages/dns/zone.py | 1127 +++ .../DESCRIPTION.rst | 9 + .../dnspython-1.16.0.dist-info/INSTALLER | 1 + .../dnspython-1.16.0.dist-info/LICENSE.txt | 35 + .../dnspython-1.16.0.dist-info/METADATA | 44 + .../dnspython-1.16.0.dist-info/RECORD | 201 + .../dnspython-1.16.0.dist-info/WHEEL | 6 + .../dnspython-1.16.0.dist-info/metadata.json | 1 + .../dnspython-1.16.0.dist-info/top_level.txt | 1 + .../python3.7/site-packages/easy_install.py | 5 + .../ipwhois-1.0.0.dist-info/DESCRIPTION.rst | 495 + .../ipwhois-1.0.0.dist-info/INSTALLER | 1 + .../ipwhois-1.0.0.dist-info/METADATA | 526 ++ .../ipwhois-1.0.0.dist-info/RECORD | 35 + .../ipwhois-1.0.0.dist-info/WHEEL | 6 + .../ipwhois-1.0.0.dist-info/metadata.json | 1 + .../ipwhois-1.0.0.dist-info/top_level.txt | 1 + .../site-packages/ipwhois/__init__.py | 29 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 263 bytes .../ipwhois/__pycache__/asn.cpython-37.pyc | Bin 0 -> 22422 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 3781 bytes .../__pycache__/experimental.cpython-37.pyc | Bin 0 -> 8730 bytes .../ipwhois/__pycache__/hr.cpython-37.pyc | Bin 0 -> 7387 bytes .../__pycache__/ipwhois.cpython-37.pyc | Bin 0 -> 12476 bytes .../ipwhois/__pycache__/net.cpython-37.pyc | Bin 0 -> 19747 bytes .../ipwhois/__pycache__/nir.cpython-37.pyc | Bin 0 -> 14963 bytes .../ipwhois/__pycache__/rdap.cpython-37.pyc | Bin 0 -> 17420 bytes .../ipwhois/__pycache__/utils.cpython-37.pyc | Bin 0 -> 12535 bytes .../ipwhois/__pycache__/whois.cpython-37.pyc | Bin 0 -> 16922 bytes .../python3.7/site-packages/ipwhois/asn.py | 955 ++ .../site-packages/ipwhois/data/iso_3166-1.csv | 252 + .../ipwhois/data/iso_3166-1_list_en.xml | 1003 ++ .../site-packages/ipwhois/exceptions.py | 121 + .../site-packages/ipwhois/experimental.py | 457 + env/lib/python3.7/site-packages/ipwhois/hr.py | 509 + .../site-packages/ipwhois/ipwhois.py | 346 + .../python3.7/site-packages/ipwhois/net.py | 954 ++ .../python3.7/site-packages/ipwhois/nir.py | 682 ++ .../python3.7/site-packages/ipwhois/rdap.py | 898 ++ .../python3.7/site-packages/ipwhois/utils.py | 631 ++ .../python3.7/site-packages/ipwhois/whois.py | 809 ++ .../pip-18.1.dist-info/INSTALLER | 1 + .../pip-18.1.dist-info/LICENSE.txt | 20 + .../site-packages/pip-18.1.dist-info/METADATA | 70 + .../site-packages/pip-18.1.dist-info/RECORD | 614 ++ .../site-packages/pip-18.1.dist-info/WHEEL | 6 + .../pip-18.1.dist-info/entry_points.txt | 5 + .../pip-18.1.dist-info/top_level.txt | 1 + .../python3.7/site-packages/pip/__init__.py | 1 + .../python3.7/site-packages/pip/__main__.py | 19 + .../pip/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 152 bytes .../pip/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 406 bytes .../site-packages/pip/_internal/__init__.py | 78 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1798 bytes .../__pycache__/build_env.cpython-37.pyc | Bin 0 -> 5007 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 6792 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 9791 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 20859 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 11512 bytes .../__pycache__/index.cpython-37.pyc | Bin 0 -> 23121 bytes .../__pycache__/locations.cpython-37.pyc | Bin 0 -> 4188 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7247 bytes .../__pycache__/pyproject.cpython-37.pyc | Bin 0 -> 2671 bytes .../__pycache__/resolve.cpython-37.pyc | Bin 0 -> 8438 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 20800 bytes .../site-packages/pip/_internal/build_env.py | 142 + .../site-packages/pip/_internal/cache.py | 202 + .../pip/_internal/cli/__init__.py | 4 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 229 bytes .../__pycache__/autocompletion.cpython-37.pyc | Bin 0 -> 5042 bytes .../__pycache__/base_command.cpython-37.pyc | Bin 0 -> 6267 bytes .../cli/__pycache__/cmdoptions.cpython-37.pyc | Bin 0 -> 14988 bytes .../__pycache__/main_parser.cpython-37.pyc | Bin 0 -> 2189 bytes .../cli/__pycache__/parser.cpython-37.pyc | Bin 0 -> 8893 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 358 bytes .../pip/_internal/cli/autocompletion.py | 152 + .../pip/_internal/cli/base_command.py | 278 + .../pip/_internal/cli/cmdoptions.py | 714 ++ .../pip/_internal/cli/main_parser.py | 96 + .../site-packages/pip/_internal/cli/parser.py | 261 + .../pip/_internal/cli/status_codes.py | 8 + .../pip/_internal/commands/__init__.py | 79 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2457 bytes .../commands/__pycache__/check.cpython-37.pyc | Bin 0 -> 1259 bytes .../__pycache__/completion.cpython-37.pyc | Bin 0 -> 3031 bytes .../__pycache__/configuration.cpython-37.pyc | Bin 0 -> 6383 bytes .../__pycache__/download.cpython-37.pyc | Bin 0 -> 4611 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 2827 bytes .../commands/__pycache__/hash.cpython-37.pyc | Bin 0 -> 2021 bytes .../commands/__pycache__/help.cpython-37.pyc | Bin 0 -> 1197 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 11793 bytes .../commands/__pycache__/list.cpython-37.pyc | Bin 0 -> 8870 bytes .../__pycache__/search.cpython-37.pyc | Bin 0 -> 4263 bytes .../commands/__pycache__/show.cpython-37.pyc | Bin 0 -> 5844 bytes .../__pycache__/uninstall.cpython-37.pyc | Bin 0 -> 2653 bytes .../commands/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 4874 bytes .../pip/_internal/commands/check.py | 41 + .../pip/_internal/commands/completion.py | 94 + .../pip/_internal/commands/configuration.py | 227 + .../pip/_internal/commands/download.py | 174 + .../pip/_internal/commands/freeze.py | 96 + .../pip/_internal/commands/hash.py | 57 + .../pip/_internal/commands/help.py | 37 + .../pip/_internal/commands/install.py | 535 ++ .../pip/_internal/commands/list.py | 306 + .../pip/_internal/commands/search.py | 135 + .../pip/_internal/commands/show.py | 168 + .../pip/_internal/commands/uninstall.py | 78 + .../pip/_internal/commands/wheel.py | 183 + .../pip/_internal/configuration.py | 387 + .../site-packages/pip/_internal/download.py | 921 ++ .../site-packages/pip/_internal/exceptions.py | 268 + .../site-packages/pip/_internal/index.py | 899 ++ .../site-packages/pip/_internal/locations.py | 194 + .../pip/_internal/models/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 217 bytes .../__pycache__/candidate.cpython-37.pyc | Bin 0 -> 1052 bytes .../__pycache__/format_control.cpython-37.pyc | Bin 0 -> 2387 bytes .../models/__pycache__/index.cpython-37.pyc | Bin 0 -> 1121 bytes .../models/__pycache__/link.cpython-37.pyc | Bin 0 -> 4719 bytes .../pip/_internal/models/candidate.py | 23 + .../pip/_internal/models/format_control.py | 62 + .../pip/_internal/models/index.py | 29 + .../pip/_internal/models/link.py | 141 + .../pip/_internal/operations/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 153 bytes .../__pycache__/check.cpython-37.pyc | Bin 0 -> 3330 bytes .../__pycache__/freeze.cpython-37.pyc | Bin 0 -> 6285 bytes .../__pycache__/prepare.cpython-37.pyc | Bin 0 -> 9151 bytes .../pip/_internal/operations/check.py | 148 + .../pip/_internal/operations/freeze.py | 264 + .../pip/_internal/operations/prepare.py | 355 + .../site-packages/pip/_internal/pep425tags.py | 317 + .../site-packages/pip/_internal/pyproject.py | 144 + .../pip/_internal/req/__init__.py | 69 + .../req/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1521 bytes .../__pycache__/constructors.cpython-37.pyc | Bin 0 -> 6919 bytes .../req/__pycache__/req_file.cpython-37.pyc | Bin 0 -> 8620 bytes .../__pycache__/req_install.cpython-37.pyc | Bin 0 -> 22770 bytes .../req/__pycache__/req_set.cpython-37.pyc | Bin 0 -> 5734 bytes .../__pycache__/req_tracker.cpython-37.pyc | Bin 0 -> 2845 bytes .../__pycache__/req_uninstall.cpython-37.pyc | Bin 0 -> 12817 bytes .../pip/_internal/req/constructors.py | 298 + .../pip/_internal/req/req_file.py | 340 + .../pip/_internal/req/req_install.py | 860 ++ .../pip/_internal/req/req_set.py | 181 + .../pip/_internal/req/req_tracker.py | 76 + .../pip/_internal/req/req_uninstall.py | 460 + .../site-packages/pip/_internal/resolve.py | 353 + .../pip/_internal/utils/__init__.py | 0 .../utils/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 148 bytes .../utils/__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 7869 bytes .../utils/__pycache__/compat.cpython-37.pyc | Bin 0 -> 5939 bytes .../__pycache__/deprecation.cpython-37.pyc | Bin 0 -> 2522 bytes .../utils/__pycache__/encoding.cpython-37.pyc | Bin 0 -> 1084 bytes .../__pycache__/filesystem.cpython-37.pyc | Bin 0 -> 615 bytes .../utils/__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1506 bytes .../utils/__pycache__/hashes.cpython-37.pyc | Bin 0 -> 3283 bytes .../utils/__pycache__/logging.cpython-37.pyc | Bin 0 -> 5316 bytes .../utils/__pycache__/misc.cpython-37.pyc | Bin 0 -> 23862 bytes .../utils/__pycache__/models.cpython-37.pyc | Bin 0 -> 1897 bytes .../utils/__pycache__/outdated.cpython-37.pyc | Bin 0 -> 3869 bytes .../__pycache__/packaging.cpython-37.pyc | Bin 0 -> 2348 bytes .../setuptools_build.cpython-37.pyc | Bin 0 -> 343 bytes .../utils/__pycache__/temp_dir.cpython-37.pyc | Bin 0 -> 2760 bytes .../utils/__pycache__/typing.cpython-37.pyc | Bin 0 -> 1292 bytes .../utils/__pycache__/ui.cpython-37.pyc | Bin 0 -> 11817 bytes .../pip/_internal/utils/appdirs.py | 258 + .../pip/_internal/utils/compat.py | 248 + .../pip/_internal/utils/deprecation.py | 89 + .../pip/_internal/utils/encoding.py | 33 + .../pip/_internal/utils/filesystem.py | 28 + .../pip/_internal/utils/glibc.py | 84 + .../pip/_internal/utils/hashes.py | 94 + .../pip/_internal/utils/logging.py | 225 + .../site-packages/pip/_internal/utils/misc.py | 940 ++ .../pip/_internal/utils/models.py | 40 + .../pip/_internal/utils/outdated.py | 154 + .../pip/_internal/utils/packaging.py | 75 + .../pip/_internal/utils/setuptools_build.py | 8 + .../pip/_internal/utils/temp_dir.py | 82 + .../pip/_internal/utils/typing.py | 29 + .../site-packages/pip/_internal/utils/ui.py | 421 + .../pip/_internal/vcs/__init__.py | 509 + .../vcs/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 15514 bytes .../vcs/__pycache__/bazaar.cpython-37.pyc | Bin 0 -> 3777 bytes .../vcs/__pycache__/git.cpython-37.pyc | Bin 0 -> 9082 bytes .../vcs/__pycache__/mercurial.cpython-37.pyc | Bin 0 -> 3750 bytes .../vcs/__pycache__/subversion.cpython-37.pyc | Bin 0 -> 6352 bytes .../site-packages/pip/_internal/vcs/bazaar.py | 112 + .../site-packages/pip/_internal/vcs/git.py | 346 + .../pip/_internal/vcs/mercurial.py | 101 + .../pip/_internal/vcs/subversion.py | 213 + .../site-packages/pip/_internal/wheel.py | 831 ++ .../site-packages/pip/_vendor/__init__.py | 110 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2818 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20565 bytes .../_vendor/__pycache__/distro.cpython-37.pyc | Bin 0 -> 36098 bytes .../__pycache__/ipaddress.cpython-37.pyc | Bin 0 -> 66408 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203012 bytes .../__pycache__/retrying.cpython-37.pyc | Bin 0 -> 8046 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24951 bytes .../site-packages/pip/_vendor/appdirs.py | 604 ++ .../pip/_vendor/cachecontrol/__init__.py | 11 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 506 bytes .../__pycache__/_cmd.cpython-37.pyc | Bin 0 -> 1509 bytes .../__pycache__/adapter.cpython-37.pyc | Bin 0 -> 2992 bytes .../__pycache__/cache.cpython-37.pyc | Bin 0 -> 1722 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 713 bytes .../__pycache__/controller.cpython-37.pyc | Bin 0 -> 7592 bytes .../__pycache__/filewrapper.cpython-37.pyc | Bin 0 -> 2110 bytes .../__pycache__/heuristics.cpython-37.pyc | Bin 0 -> 4630 bytes .../__pycache__/serialize.cpython-37.pyc | Bin 0 -> 4194 bytes .../__pycache__/wrapper.cpython-37.pyc | Bin 0 -> 614 bytes .../pip/_vendor/cachecontrol/_cmd.py | 57 + .../pip/_vendor/cachecontrol/adapter.py | 133 + .../pip/_vendor/cachecontrol/cache.py | 39 + .../_vendor/cachecontrol/caches/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 250 bytes .../__pycache__/file_cache.cpython-37.pyc | Bin 0 -> 3184 bytes .../__pycache__/redis_cache.cpython-37.pyc | Bin 0 -> 1506 bytes .../_vendor/cachecontrol/caches/file_cache.py | 146 + .../cachecontrol/caches/redis_cache.py | 33 + .../pip/_vendor/cachecontrol/compat.py | 29 + .../pip/_vendor/cachecontrol/controller.py | 367 + .../pip/_vendor/cachecontrol/filewrapper.py | 80 + .../pip/_vendor/cachecontrol/heuristics.py | 135 + .../pip/_vendor/cachecontrol/serialize.py | 186 + .../pip/_vendor/cachecontrol/wrapper.py | 29 + .../pip/_vendor/certifi/__init__.py | 3 + .../pip/_vendor/certifi/__main__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 233 bytes .../__pycache__/__main__.cpython-37.pyc | Bin 0 -> 216 bytes .../certifi/__pycache__/core.cpython-37.pyc | Bin 0 -> 1168 bytes .../pip/_vendor/certifi/cacert.pem | 4300 +++++++++ .../site-packages/pip/_vendor/certifi/core.py | 37 + .../pip/_vendor/chardet/__init__.py | 39 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 800 bytes .../__pycache__/big5freq.cpython-37.pyc | Bin 0 -> 27135 bytes .../__pycache__/big5prober.cpython-37.pyc | Bin 0 -> 1076 bytes .../chardistribution.cpython-37.pyc | Bin 0 -> 6262 bytes .../charsetgroupprober.cpython-37.pyc | Bin 0 -> 2183 bytes .../__pycache__/charsetprober.cpython-37.pyc | Bin 0 -> 3393 bytes .../codingstatemachine.cpython-37.pyc | Bin 0 -> 2840 bytes .../chardet/__pycache__/compat.cpython-37.pyc | Bin 0 -> 311 bytes .../__pycache__/cp949prober.cpython-37.pyc | Bin 0 -> 1083 bytes .../chardet/__pycache__/enums.cpython-37.pyc | Bin 0 -> 2574 bytes .../__pycache__/escprober.cpython-37.pyc | Bin 0 -> 2561 bytes .../chardet/__pycache__/escsm.cpython-37.pyc | Bin 0 -> 7022 bytes .../__pycache__/eucjpprober.cpython-37.pyc | Bin 0 -> 2369 bytes .../__pycache__/euckrfreq.cpython-37.pyc | Bin 0 -> 12019 bytes .../__pycache__/euckrprober.cpython-37.pyc | Bin 0 -> 1084 bytes .../__pycache__/euctwfreq.cpython-37.pyc | Bin 0 -> 27139 bytes .../__pycache__/euctwprober.cpython-37.pyc | Bin 0 -> 1084 bytes .../__pycache__/gb2312freq.cpython-37.pyc | Bin 0 -> 19063 bytes .../__pycache__/gb2312prober.cpython-37.pyc | Bin 0 -> 1092 bytes .../__pycache__/hebrewprober.cpython-37.pyc | Bin 0 -> 2926 bytes .../__pycache__/jisfreq.cpython-37.pyc | Bin 0 -> 22091 bytes .../chardet/__pycache__/jpcntx.cpython-37.pyc | Bin 0 -> 37970 bytes .../langbulgarianmodel.cpython-37.pyc | Bin 0 -> 23584 bytes .../langcyrillicmodel.cpython-37.pyc | Bin 0 -> 29040 bytes .../__pycache__/langgreekmodel.cpython-37.pyc | Bin 0 -> 23542 bytes .../langhebrewmodel.cpython-37.pyc | Bin 0 -> 22171 bytes .../langhungarianmodel.cpython-37.pyc | Bin 0 -> 23573 bytes .../__pycache__/langthaimodel.cpython-37.pyc | Bin 0 -> 22150 bytes .../langturkishmodel.cpython-37.pyc | Bin 0 -> 22173 bytes .../__pycache__/latin1prober.cpython-37.pyc | Bin 0 -> 2883 bytes .../mbcharsetprober.cpython-37.pyc | Bin 0 -> 2188 bytes .../mbcsgroupprober.cpython-37.pyc | Bin 0 -> 1079 bytes .../chardet/__pycache__/mbcssm.cpython-37.pyc | Bin 0 -> 15634 bytes .../sbcharsetprober.cpython-37.pyc | Bin 0 -> 2941 bytes .../sbcsgroupprober.cpython-37.pyc | Bin 0 -> 1569 bytes .../__pycache__/sjisprober.cpython-37.pyc | Bin 0 -> 2395 bytes .../universaldetector.cpython-37.pyc | Bin 0 -> 5785 bytes .../__pycache__/utf8prober.cpython-37.pyc | Bin 0 -> 1926 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 395 bytes .../pip/_vendor/chardet/big5freq.py | 386 + .../pip/_vendor/chardet/big5prober.py | 47 + .../pip/_vendor/chardet/chardistribution.py | 233 + .../pip/_vendor/chardet/charsetgroupprober.py | 106 + .../pip/_vendor/chardet/charsetprober.py | 145 + .../pip/_vendor/chardet/cli/__init__.py | 1 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 152 bytes .../cli/__pycache__/chardetect.cpython-37.pyc | Bin 0 -> 2641 bytes .../pip/_vendor/chardet/cli/chardetect.py | 85 + .../pip/_vendor/chardet/codingstatemachine.py | 88 + .../pip/_vendor/chardet/compat.py | 34 + .../pip/_vendor/chardet/cp949prober.py | 49 + .../pip/_vendor/chardet/enums.py | 76 + .../pip/_vendor/chardet/escprober.py | 101 + .../pip/_vendor/chardet/escsm.py | 246 + .../pip/_vendor/chardet/eucjpprober.py | 92 + .../pip/_vendor/chardet/euckrfreq.py | 195 + .../pip/_vendor/chardet/euckrprober.py | 47 + .../pip/_vendor/chardet/euctwfreq.py | 387 + .../pip/_vendor/chardet/euctwprober.py | 46 + .../pip/_vendor/chardet/gb2312freq.py | 283 + .../pip/_vendor/chardet/gb2312prober.py | 46 + .../pip/_vendor/chardet/hebrewprober.py | 292 + .../pip/_vendor/chardet/jisfreq.py | 325 + .../pip/_vendor/chardet/jpcntx.py | 233 + .../pip/_vendor/chardet/langbulgarianmodel.py | 228 + .../pip/_vendor/chardet/langcyrillicmodel.py | 333 + .../pip/_vendor/chardet/langgreekmodel.py | 225 + .../pip/_vendor/chardet/langhebrewmodel.py | 200 + .../pip/_vendor/chardet/langhungarianmodel.py | 225 + .../pip/_vendor/chardet/langthaimodel.py | 199 + .../pip/_vendor/chardet/langturkishmodel.py | 193 + .../pip/_vendor/chardet/latin1prober.py | 145 + .../pip/_vendor/chardet/mbcharsetprober.py | 91 + .../pip/_vendor/chardet/mbcsgroupprober.py | 54 + .../pip/_vendor/chardet/mbcssm.py | 572 ++ .../pip/_vendor/chardet/sbcharsetprober.py | 132 + .../pip/_vendor/chardet/sbcsgroupprober.py | 73 + .../pip/_vendor/chardet/sjisprober.py | 92 + .../pip/_vendor/chardet/universaldetector.py | 286 + .../pip/_vendor/chardet/utf8prober.py | 82 + .../pip/_vendor/chardet/version.py | 9 + .../pip/_vendor/colorama/__init__.py | 7 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 400 bytes .../colorama/__pycache__/ansi.cpython-37.pyc | Bin 0 -> 3298 bytes .../__pycache__/ansitowin32.cpython-37.pyc | Bin 0 -> 7011 bytes .../__pycache__/initialise.cpython-37.pyc | Bin 0 -> 1619 bytes .../colorama/__pycache__/win32.cpython-37.pyc | Bin 0 -> 3834 bytes .../__pycache__/winterm.cpython-37.pyc | Bin 0 -> 4523 bytes .../pip/_vendor/colorama/ansi.py | 102 + .../pip/_vendor/colorama/ansitowin32.py | 236 + .../pip/_vendor/colorama/initialise.py | 82 + .../pip/_vendor/colorama/win32.py | 156 + .../pip/_vendor/colorama/winterm.py | 162 + .../pip/_vendor/distlib/__init__.py | 23 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 998 bytes .../distlib/__pycache__/compat.cpython-37.pyc | Bin 0 -> 32008 bytes .../__pycache__/database.cpython-37.pyc | Bin 0 -> 42481 bytes .../distlib/__pycache__/index.cpython-37.pyc | Bin 0 -> 17294 bytes .../__pycache__/locators.cpython-37.pyc | Bin 0 -> 38601 bytes .../__pycache__/manifest.cpython-37.pyc | Bin 0 -> 10246 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 4432 bytes .../__pycache__/metadata.cpython-37.pyc | Bin 0 -> 27641 bytes .../__pycache__/resources.cpython-37.pyc | Bin 0 -> 10842 bytes .../__pycache__/scripts.cpython-37.pyc | Bin 0 -> 11018 bytes .../distlib/__pycache__/util.cpython-37.pyc | Bin 0 -> 47839 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 20382 bytes .../distlib/__pycache__/wheel.cpython-37.pyc | Bin 0 -> 25032 bytes .../pip/_vendor/distlib/_backport/__init__.py | 6 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 440 bytes .../_backport/__pycache__/misc.cpython-37.pyc | Bin 0 -> 1037 bytes .../__pycache__/shutil.cpython-37.pyc | Bin 0 -> 21353 bytes .../__pycache__/sysconfig.cpython-37.pyc | Bin 0 -> 15818 bytes .../__pycache__/tarfile.cpython-37.pyc | Bin 0 -> 62683 bytes .../pip/_vendor/distlib/_backport/misc.py | 41 + .../pip/_vendor/distlib/_backport/shutil.py | 761 ++ .../_vendor/distlib/_backport/sysconfig.cfg | 84 + .../_vendor/distlib/_backport/sysconfig.py | 788 ++ .../pip/_vendor/distlib/_backport/tarfile.py | 2607 ++++++ .../pip/_vendor/distlib/compat.py | 1120 +++ .../pip/_vendor/distlib/database.py | 1336 +++ .../pip/_vendor/distlib/index.py | 516 ++ .../pip/_vendor/distlib/locators.py | 1292 +++ .../pip/_vendor/distlib/manifest.py | 393 + .../pip/_vendor/distlib/markers.py | 131 + .../pip/_vendor/distlib/metadata.py | 1091 +++ .../pip/_vendor/distlib/resources.py | 355 + .../pip/_vendor/distlib/scripts.py | 415 + .../site-packages/pip/_vendor/distlib/t32.exe | Bin 0 -> 92672 bytes .../site-packages/pip/_vendor/distlib/t64.exe | Bin 0 -> 102400 bytes .../site-packages/pip/_vendor/distlib/util.py | 1755 ++++ .../pip/_vendor/distlib/version.py | 736 ++ .../site-packages/pip/_vendor/distlib/w32.exe | Bin 0 -> 89088 bytes .../site-packages/pip/_vendor/distlib/w64.exe | Bin 0 -> 99328 bytes .../pip/_vendor/distlib/wheel.py | 984 ++ .../site-packages/pip/_vendor/distro.py | 1197 +++ .../pip/_vendor/html5lib/__init__.py | 35 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 1269 bytes .../__pycache__/_ihatexml.cpython-37.pyc | Bin 0 -> 13716 bytes .../__pycache__/_inputstream.cpython-37.pyc | Bin 0 -> 22607 bytes .../__pycache__/_tokenizer.cpython-37.pyc | Bin 0 -> 41508 bytes .../__pycache__/_utils.cpython-37.pyc | Bin 0 -> 3261 bytes .../__pycache__/constants.cpython-37.pyc | Bin 0 -> 66173 bytes .../__pycache__/html5parser.cpython-37.pyc | Bin 0 -> 97770 bytes .../__pycache__/serializer.cpython-37.pyc | Bin 0 -> 10786 bytes .../pip/_vendor/html5lib/_ihatexml.py | 288 + .../pip/_vendor/html5lib/_inputstream.py | 923 ++ .../pip/_vendor/html5lib/_tokenizer.py | 1721 ++++ .../pip/_vendor/html5lib/_trie/__init__.py | 14 + .../_trie/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 382 bytes .../_trie/__pycache__/_base.cpython-37.pyc | Bin 0 -> 1465 bytes .../_trie/__pycache__/datrie.cpython-37.pyc | Bin 0 -> 1984 bytes .../_trie/__pycache__/py.cpython-37.pyc | Bin 0 -> 2187 bytes .../pip/_vendor/html5lib/_trie/_base.py | 37 + .../pip/_vendor/html5lib/_trie/datrie.py | 44 + .../pip/_vendor/html5lib/_trie/py.py | 67 + .../pip/_vendor/html5lib/_utils.py | 124 + .../pip/_vendor/html5lib/constants.py | 2947 ++++++ .../pip/_vendor/html5lib/filters/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 157 bytes .../alphabeticalattributes.cpython-37.pyc | Bin 0 -> 1273 bytes .../filters/__pycache__/base.cpython-37.pyc | Bin 0 -> 807 bytes .../inject_meta_charset.cpython-37.pyc | Bin 0 -> 1827 bytes .../filters/__pycache__/lint.cpython-37.pyc | Bin 0 -> 2591 bytes .../__pycache__/optionaltags.cpython-37.pyc | Bin 0 -> 2718 bytes .../__pycache__/sanitizer.cpython-37.pyc | Bin 0 -> 16393 bytes .../__pycache__/whitespace.cpython-37.pyc | Bin 0 -> 1311 bytes .../filters/alphabeticalattributes.py | 29 + .../pip/_vendor/html5lib/filters/base.py | 12 + .../html5lib/filters/inject_meta_charset.py | 73 + .../pip/_vendor/html5lib/filters/lint.py | 93 + .../_vendor/html5lib/filters/optionaltags.py | 207 + .../pip/_vendor/html5lib/filters/sanitizer.py | 896 ++ .../_vendor/html5lib/filters/whitespace.py | 38 + .../pip/_vendor/html5lib/html5parser.py | 2791 ++++++ .../pip/_vendor/html5lib/serializer.py | 409 + .../_vendor/html5lib/treeadapters/__init__.py | 30 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 896 bytes .../__pycache__/genshi.cpython-37.pyc | Bin 0 -> 1493 bytes .../__pycache__/sax.cpython-37.pyc | Bin 0 -> 1443 bytes .../_vendor/html5lib/treeadapters/genshi.py | 54 + .../pip/_vendor/html5lib/treeadapters/sax.py | 50 + .../_vendor/html5lib/treebuilders/__init__.py | 88 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3277 bytes .../__pycache__/base.cpython-37.pyc | Bin 0 -> 11200 bytes .../__pycache__/dom.cpython-37.pyc | Bin 0 -> 9230 bytes .../__pycache__/etree.cpython-37.pyc | Bin 0 -> 11809 bytes .../__pycache__/etree_lxml.cpython-37.pyc | Bin 0 -> 11749 bytes .../pip/_vendor/html5lib/treebuilders/base.py | 417 + .../pip/_vendor/html5lib/treebuilders/dom.py | 236 + .../_vendor/html5lib/treebuilders/etree.py | 340 + .../html5lib/treebuilders/etree_lxml.py | 366 + .../_vendor/html5lib/treewalkers/__init__.py | 154 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3954 bytes .../__pycache__/base.cpython-37.pyc | Bin 0 -> 6950 bytes .../__pycache__/dom.cpython-37.pyc | Bin 0 -> 1679 bytes .../__pycache__/etree.cpython-37.pyc | Bin 0 -> 3486 bytes .../__pycache__/etree_lxml.cpython-37.pyc | Bin 0 -> 6595 bytes .../__pycache__/genshi.cpython-37.pyc | Bin 0 -> 1853 bytes .../pip/_vendor/html5lib/treewalkers/base.py | 252 + .../pip/_vendor/html5lib/treewalkers/dom.py | 43 + .../pip/_vendor/html5lib/treewalkers/etree.py | 130 + .../html5lib/treewalkers/etree_lxml.py | 213 + .../_vendor/html5lib/treewalkers/genshi.py | 69 + .../pip/_vendor/idna/__init__.py | 2 + .../idna/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 214 bytes .../idna/__pycache__/codec.cpython-37.pyc | Bin 0 -> 3021 bytes .../idna/__pycache__/compat.cpython-37.pyc | Bin 0 -> 574 bytes .../idna/__pycache__/core.cpython-37.pyc | Bin 0 -> 9106 bytes .../idna/__pycache__/idnadata.cpython-37.pyc | Bin 0 -> 20538 bytes .../idna/__pycache__/intranges.cpython-37.pyc | Bin 0 -> 1754 bytes .../__pycache__/package_data.cpython-37.pyc | Bin 0 -> 168 bytes .../idna/__pycache__/uts46data.cpython-37.pyc | Bin 0 -> 175610 bytes .../site-packages/pip/_vendor/idna/codec.py | 118 + .../site-packages/pip/_vendor/idna/compat.py | 12 + .../site-packages/pip/_vendor/idna/core.py | 399 + .../pip/_vendor/idna/idnadata.py | 1893 ++++ .../pip/_vendor/idna/intranges.py | 53 + .../pip/_vendor/idna/package_data.py | 2 + .../pip/_vendor/idna/uts46data.py | 8179 +++++++++++++++++ .../site-packages/pip/_vendor/ipaddress.py | 2419 +++++ .../pip/_vendor/lockfile/__init__.py | 347 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9864 bytes .../__pycache__/linklockfile.cpython-37.pyc | Bin 0 -> 2245 bytes .../__pycache__/mkdirlockfile.cpython-37.pyc | Bin 0 -> 2607 bytes .../__pycache__/pidlockfile.cpython-37.pyc | Bin 0 -> 4807 bytes .../__pycache__/sqlitelockfile.cpython-37.pyc | Bin 0 -> 3706 bytes .../symlinklockfile.cpython-37.pyc | Bin 0 -> 2130 bytes .../pip/_vendor/lockfile/linklockfile.py | 73 + .../pip/_vendor/lockfile/mkdirlockfile.py | 84 + .../pip/_vendor/lockfile/pidlockfile.py | 190 + .../pip/_vendor/lockfile/sqlitelockfile.py | 156 + .../pip/_vendor/lockfile/symlinklockfile.py | 70 + .../pip/_vendor/msgpack/__init__.py | 66 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2026 bytes .../__pycache__/_version.cpython-37.pyc | Bin 0 -> 175 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 2131 bytes .../__pycache__/fallback.cpython-37.pyc | Bin 0 -> 24503 bytes .../pip/_vendor/msgpack/_version.py | 1 + .../pip/_vendor/msgpack/exceptions.py | 41 + .../pip/_vendor/msgpack/fallback.py | 977 ++ .../pip/_vendor/packaging/__about__.py | 21 + .../pip/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 676 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 514 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 966 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2818 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8817 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3833 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19744 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 1412 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 11930 bytes .../pip/_vendor/packaging/_compat.py | 30 + .../pip/_vendor/packaging/_structures.py | 70 + .../pip/_vendor/packaging/markers.py | 301 + .../pip/_vendor/packaging/requirements.py | 130 + .../pip/_vendor/packaging/specifiers.py | 774 ++ .../pip/_vendor/packaging/utils.py | 63 + .../pip/_vendor/packaging/version.py | 441 + .../pip/_vendor/pep517/__init__.py | 4 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 237 bytes .../__pycache__/_in_process.cpython-37.pyc | Bin 0 -> 5302 bytes .../pep517/__pycache__/check.cpython-37.pyc | Bin 0 -> 4701 bytes .../__pycache__/colorlog.cpython-37.pyc | Bin 0 -> 2866 bytes .../pep517/__pycache__/compat.cpython-37.pyc | Bin 0 -> 975 bytes .../__pycache__/envbuild.cpython-37.pyc | Bin 0 -> 4132 bytes .../__pycache__/wrappers.cpython-37.pyc | Bin 0 -> 4699 bytes .../pip/_vendor/pep517/_in_process.py | 182 + .../site-packages/pip/_vendor/pep517/check.py | 194 + .../pip/_vendor/pep517/colorlog.py | 110 + .../pip/_vendor/pep517/compat.py | 23 + .../pip/_vendor/pep517/envbuild.py | 150 + .../pip/_vendor/pep517/wrappers.py | 134 + .../pip/_vendor/pkg_resources/__init__.py | 3149 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 95982 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 599 bytes .../pip/_vendor/pkg_resources/py31compat.py | 23 + .../pip/_vendor/progress/__init__.py | 127 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3867 bytes .../progress/__pycache__/bar.cpython-37.pyc | Bin 0 -> 2689 bytes .../__pycache__/counter.cpython-37.pyc | Bin 0 -> 1531 bytes .../__pycache__/helpers.cpython-37.pyc | Bin 0 -> 2973 bytes .../__pycache__/spinner.cpython-37.pyc | Bin 0 -> 1448 bytes .../site-packages/pip/_vendor/progress/bar.py | 94 + .../pip/_vendor/progress/counter.py | 48 + .../pip/_vendor/progress/helpers.py | 91 + .../pip/_vendor/progress/spinner.py | 44 + .../site-packages/pip/_vendor/pyparsing.py | 5742 ++++++++++++ .../pip/_vendor/pytoml/__init__.py | 3 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 287 bytes .../pytoml/__pycache__/core.cpython-37.pyc | Bin 0 -> 896 bytes .../pytoml/__pycache__/parser.cpython-37.pyc | Bin 0 -> 11099 bytes .../pytoml/__pycache__/writer.cpython-37.pyc | Bin 0 -> 3798 bytes .../site-packages/pip/_vendor/pytoml/core.py | 13 + .../pip/_vendor/pytoml/parser.py | 374 + .../pip/_vendor/pytoml/writer.py | 127 + .../pip/_vendor/requests/__init__.py | 138 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 3744 bytes .../__pycache__/__version__.cpython-37.pyc | Bin 0 -> 507 bytes .../_internal_utils.cpython-37.pyc | Bin 0 -> 1265 bytes .../__pycache__/adapters.cpython-37.pyc | Bin 0 -> 16730 bytes .../requests/__pycache__/api.cpython-37.pyc | Bin 0 -> 6456 bytes .../requests/__pycache__/auth.cpython-37.pyc | Bin 0 -> 8301 bytes .../requests/__pycache__/certs.cpython-37.pyc | Bin 0 -> 590 bytes .../__pycache__/compat.cpython-37.pyc | Bin 0 -> 1600 bytes .../__pycache__/cookies.cpython-37.pyc | Bin 0 -> 18709 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 5462 bytes .../requests/__pycache__/help.cpython-37.pyc | Bin 0 -> 2654 bytes .../requests/__pycache__/hooks.cpython-37.pyc | Bin 0 -> 954 bytes .../__pycache__/models.cpython-37.pyc | Bin 0 -> 23921 bytes .../__pycache__/packages.cpython-37.pyc | Bin 0 -> 467 bytes .../__pycache__/sessions.cpython-37.pyc | Bin 0 -> 18526 bytes .../__pycache__/status_codes.cpython-37.pyc | Bin 0 -> 4123 bytes .../__pycache__/structures.cpython-37.pyc | Bin 0 -> 4336 bytes .../requests/__pycache__/utils.cpython-37.pyc | Bin 0 -> 21906 bytes .../pip/_vendor/requests/__version__.py | 14 + .../pip/_vendor/requests/_internal_utils.py | 42 + .../pip/_vendor/requests/adapters.py | 530 ++ .../site-packages/pip/_vendor/requests/api.py | 152 + .../pip/_vendor/requests/auth.py | 305 + .../pip/_vendor/requests/certs.py | 18 + .../pip/_vendor/requests/compat.py | 75 + .../pip/_vendor/requests/cookies.py | 546 ++ .../pip/_vendor/requests/exceptions.py | 126 + .../pip/_vendor/requests/help.py | 120 + .../pip/_vendor/requests/hooks.py | 34 + .../pip/_vendor/requests/models.py | 952 ++ .../pip/_vendor/requests/packages.py | 16 + .../pip/_vendor/requests/sessions.py | 741 ++ .../pip/_vendor/requests/status_codes.py | 120 + .../pip/_vendor/requests/structures.py | 103 + .../pip/_vendor/requests/utils.py | 976 ++ .../site-packages/pip/_vendor/retrying.py | 267 + .../site-packages/pip/_vendor/six.py | 891 ++ .../pip/_vendor/urllib3/__init__.py | 97 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2379 bytes .../__pycache__/_collections.cpython-37.pyc | Bin 0 -> 10703 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 10224 bytes .../__pycache__/connectionpool.cpython-37.pyc | Bin 0 -> 23758 bytes .../__pycache__/exceptions.cpython-37.pyc | Bin 0 -> 10357 bytes .../urllib3/__pycache__/fields.cpython-37.pyc | Bin 0 -> 5825 bytes .../__pycache__/filepost.cpython-37.pyc | Bin 0 -> 2717 bytes .../__pycache__/poolmanager.cpython-37.pyc | Bin 0 -> 12656 bytes .../__pycache__/request.cpython-37.pyc | Bin 0 -> 5548 bytes .../__pycache__/response.cpython-37.pyc | Bin 0 -> 17374 bytes .../pip/_vendor/urllib3/_collections.py | 332 + .../pip/_vendor/urllib3/connection.py | 403 + .../pip/_vendor/urllib3/connectionpool.py | 906 ++ .../pip/_vendor/urllib3/contrib/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 156 bytes .../__pycache__/appengine.cpython-37.pyc | Bin 0 -> 8904 bytes .../__pycache__/ntlmpool.cpython-37.pyc | Bin 0 -> 3204 bytes .../__pycache__/pyopenssl.cpython-37.pyc | Bin 0 -> 14231 bytes .../securetransport.cpython-37.pyc | Bin 0 -> 17853 bytes .../contrib/__pycache__/socks.cpython-37.pyc | Bin 0 -> 4862 bytes .../contrib/_securetransport/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 173 bytes .../__pycache__/bindings.cpython-37.pyc | Bin 0 -> 10268 bytes .../__pycache__/low_level.cpython-37.pyc | Bin 0 -> 7449 bytes .../contrib/_securetransport/bindings.py | 593 ++ .../contrib/_securetransport/low_level.py | 346 + .../pip/_vendor/urllib3/contrib/appengine.py | 305 + .../pip/_vendor/urllib3/contrib/ntlmpool.py | 112 + .../pip/_vendor/urllib3/contrib/pyopenssl.py | 457 + .../urllib3/contrib/securetransport.py | 804 ++ .../pip/_vendor/urllib3/contrib/socks.py | 192 + .../pip/_vendor/urllib3/exceptions.py | 246 + .../pip/_vendor/urllib3/fields.py | 178 + .../pip/_vendor/urllib3/filepost.py | 98 + .../pip/_vendor/urllib3/packages/__init__.py | 5 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 270 bytes .../__pycache__/ordered_dict.cpython-37.pyc | Bin 0 -> 8364 bytes .../packages/__pycache__/six.cpython-37.pyc | Bin 0 -> 24358 bytes .../urllib3/packages/backports/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 167 bytes .../__pycache__/makefile.cpython-37.pyc | Bin 0 -> 1265 bytes .../urllib3/packages/backports/makefile.py | 53 + .../_vendor/urllib3/packages/ordered_dict.py | 259 + .../pip/_vendor/urllib3/packages/six.py | 868 ++ .../packages/ssl_match_hostname/__init__.py | 19 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 511 bytes .../_implementation.cpython-37.pyc | Bin 0 -> 3270 bytes .../ssl_match_hostname/_implementation.py | 157 + .../pip/_vendor/urllib3/poolmanager.py | 449 + .../pip/_vendor/urllib3/request.py | 150 + .../pip/_vendor/urllib3/response.py | 676 ++ .../pip/_vendor/urllib3/util/__init__.py | 54 + .../util/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 948 bytes .../__pycache__/connection.cpython-37.pyc | Bin 0 -> 3025 bytes .../util/__pycache__/queue.cpython-37.pyc | Bin 0 -> 997 bytes .../util/__pycache__/request.cpython-37.pyc | Bin 0 -> 3178 bytes .../util/__pycache__/response.cpython-37.pyc | Bin 0 -> 1859 bytes .../util/__pycache__/retry.cpython-37.pyc | Bin 0 -> 12611 bytes .../util/__pycache__/ssl_.cpython-37.pyc | Bin 0 -> 9949 bytes .../util/__pycache__/timeout.cpython-37.pyc | Bin 0 -> 8727 bytes .../util/__pycache__/url.cpython-37.pyc | Bin 0 -> 5137 bytes .../util/__pycache__/wait.cpython-37.pyc | Bin 0 -> 3110 bytes .../pip/_vendor/urllib3/util/connection.py | 126 + .../pip/_vendor/urllib3/util/queue.py | 21 + .../pip/_vendor/urllib3/util/request.py | 118 + .../pip/_vendor/urllib3/util/response.py | 81 + .../pip/_vendor/urllib3/util/retry.py | 411 + .../pip/_vendor/urllib3/util/ssl_.py | 396 + .../pip/_vendor/urllib3/util/timeout.py | 242 + .../pip/_vendor/urllib3/util/url.py | 230 + .../pip/_vendor/urllib3/util/wait.py | 153 + .../pip/_vendor/webencodings/__init__.py | 342 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 9632 bytes .../__pycache__/labels.cpython-37.pyc | Bin 0 -> 4046 bytes .../__pycache__/mklabels.cpython-37.pyc | Bin 0 -> 1868 bytes .../__pycache__/tests.cpython-37.pyc | Bin 0 -> 5009 bytes .../__pycache__/x_user_defined.cpython-37.pyc | Bin 0 -> 2621 bytes .../pip/_vendor/webencodings/labels.py | 231 + .../pip/_vendor/webencodings/mklabels.py | 59 + .../pip/_vendor/webencodings/tests.py | 153 + .../_vendor/webencodings/x_user_defined.py | 325 + .../site-packages/pkg_resources/__init__.py | 3171 +++++++ .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 96825 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 594 bytes .../pkg_resources/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 157 bytes .../__pycache__/appdirs.cpython-37.pyc | Bin 0 -> 20645 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 203000 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24358 bytes .../pkg_resources/_vendor/appdirs.py | 608 ++ .../_vendor/packaging/__about__.py | 21 + .../_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 693 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 531 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 983 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2835 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8843 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3848 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19761 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 462 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10528 bytes .../_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../pkg_resources/_vendor/packaging/utils.py | 14 + .../_vendor/packaging/version.py | 393 + .../pkg_resources/_vendor/pyparsing.py | 5742 ++++++++++++ .../pkg_resources/_vendor/six.py | 868 ++ .../pkg_resources/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2376 bytes .../site-packages/pkg_resources/py31compat.py | 23 + .../setuptools-40.6.3.dist-info/INSTALLER | 1 + .../setuptools-40.6.3.dist-info/LICENSE | 19 + .../setuptools-40.6.3.dist-info/METADATA | 73 + .../setuptools-40.6.3.dist-info/RECORD | 188 + .../setuptools-40.6.3.dist-info/WHEEL | 6 + .../dependency_links.txt | 2 + .../entry_points.txt | 65 + .../setuptools-40.6.3.dist-info/top_level.txt | 3 + .../setuptools-40.6.3.dist-info/zip-safe | 1 + .../site-packages/setuptools/__init__.py | 195 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 6481 bytes .../_deprecation_warning.cpython-37.pyc | Bin 0 -> 512 bytes .../__pycache__/archive_util.cpython-37.pyc | Bin 0 -> 5093 bytes .../__pycache__/build_meta.cpython-37.pyc | Bin 0 -> 6215 bytes .../__pycache__/config.cpython-37.pyc | Bin 0 -> 16961 bytes .../__pycache__/dep_util.cpython-37.pyc | Bin 0 -> 819 bytes .../__pycache__/depends.cpython-37.pyc | Bin 0 -> 5228 bytes .../__pycache__/dist.cpython-37.pyc | Bin 0 -> 38403 bytes .../__pycache__/extension.cpython-37.pyc | Bin 0 -> 1939 bytes .../__pycache__/glibc.cpython-37.pyc | Bin 0 -> 1504 bytes .../__pycache__/glob.cpython-37.pyc | Bin 0 -> 3714 bytes .../__pycache__/launch.cpython-37.pyc | Bin 0 -> 818 bytes .../__pycache__/lib2to3_ex.cpython-37.pyc | Bin 0 -> 2397 bytes .../__pycache__/monkey.cpython-37.pyc | Bin 0 -> 4598 bytes .../__pycache__/msvc.cpython-37.pyc | Bin 0 -> 34395 bytes .../__pycache__/namespaces.cpython-37.pyc | Bin 0 -> 3576 bytes .../__pycache__/package_index.cpython-37.pyc | Bin 0 -> 32430 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 7167 bytes .../__pycache__/py27compat.cpython-37.pyc | Bin 0 -> 775 bytes .../__pycache__/py31compat.cpython-37.pyc | Bin 0 -> 1161 bytes .../__pycache__/py33compat.cpython-37.pyc | Bin 0 -> 1384 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 2156 bytes .../__pycache__/sandbox.cpython-37.pyc | Bin 0 -> 15500 bytes .../__pycache__/site-patch.cpython-37.pyc | Bin 0 -> 1466 bytes .../__pycache__/ssl_support.cpython-37.pyc | Bin 0 -> 6755 bytes .../__pycache__/unicode_utils.cpython-37.pyc | Bin 0 -> 1133 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 292 bytes .../__pycache__/wheel.cpython-37.pyc | Bin 0 -> 6980 bytes .../windows_support.cpython-37.pyc | Bin 0 -> 975 bytes .../setuptools/_deprecation_warning.py | 7 + .../setuptools/_vendor/__init__.py | 0 .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 154 bytes .../__pycache__/pyparsing.cpython-37.pyc | Bin 0 -> 202997 bytes .../_vendor/__pycache__/six.cpython-37.pyc | Bin 0 -> 24355 bytes .../setuptools/_vendor/packaging/__about__.py | 21 + .../setuptools/_vendor/packaging/__init__.py | 14 + .../__pycache__/__about__.cpython-37.pyc | Bin 0 -> 690 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 528 bytes .../__pycache__/_compat.cpython-37.pyc | Bin 0 -> 980 bytes .../__pycache__/_structures.cpython-37.pyc | Bin 0 -> 2832 bytes .../__pycache__/markers.cpython-37.pyc | Bin 0 -> 8837 bytes .../__pycache__/requirements.cpython-37.pyc | Bin 0 -> 3839 bytes .../__pycache__/specifiers.cpython-37.pyc | Bin 0 -> 19758 bytes .../__pycache__/utils.cpython-37.pyc | Bin 0 -> 459 bytes .../__pycache__/version.cpython-37.pyc | Bin 0 -> 10525 bytes .../setuptools/_vendor/packaging/_compat.py | 30 + .../_vendor/packaging/_structures.py | 68 + .../setuptools/_vendor/packaging/markers.py | 301 + .../_vendor/packaging/requirements.py | 127 + .../_vendor/packaging/specifiers.py | 774 ++ .../setuptools/_vendor/packaging/utils.py | 14 + .../setuptools/_vendor/packaging/version.py | 393 + .../setuptools/_vendor/pyparsing.py | 5742 ++++++++++++ .../site-packages/setuptools/_vendor/six.py | 868 ++ .../site-packages/setuptools/archive_util.py | 173 + .../site-packages/setuptools/build_meta.py | 182 + .../site-packages/setuptools/cli-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/cli-64.exe | Bin 0 -> 74752 bytes .../site-packages/setuptools/cli.exe | Bin 0 -> 65536 bytes .../setuptools/command/__init__.py | 18 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 700 bytes .../command/__pycache__/alias.cpython-37.pyc | Bin 0 -> 2368 bytes .../__pycache__/bdist_egg.cpython-37.pyc | Bin 0 -> 14156 bytes .../__pycache__/bdist_rpm.cpython-37.pyc | Bin 0 -> 1747 bytes .../__pycache__/bdist_wininst.cpython-37.pyc | Bin 0 -> 938 bytes .../__pycache__/build_clib.cpython-37.pyc | Bin 0 -> 2417 bytes .../__pycache__/build_ext.cpython-37.pyc | Bin 0 -> 9671 bytes .../__pycache__/build_py.cpython-37.pyc | Bin 0 -> 8547 bytes .../__pycache__/develop.cpython-37.pyc | Bin 0 -> 6388 bytes .../__pycache__/dist_info.cpython-37.pyc | Bin 0 -> 1343 bytes .../__pycache__/easy_install.cpython-37.pyc | Bin 0 -> 64799 bytes .../__pycache__/egg_info.cpython-37.pyc | Bin 0 -> 21620 bytes .../__pycache__/install.cpython-37.pyc | Bin 0 -> 3975 bytes .../install_egg_info.cpython-37.pyc | Bin 0 -> 2376 bytes .../__pycache__/install_lib.cpython-37.pyc | Bin 0 -> 4052 bytes .../install_scripts.cpython-37.pyc | Bin 0 -> 2255 bytes .../__pycache__/py36compat.cpython-37.pyc | Bin 0 -> 4588 bytes .../__pycache__/register.cpython-37.pyc | Bin 0 -> 745 bytes .../command/__pycache__/rotate.cpython-37.pyc | Bin 0 -> 2494 bytes .../__pycache__/saveopts.cpython-37.pyc | Bin 0 -> 889 bytes .../command/__pycache__/sdist.cpython-37.pyc | Bin 0 -> 6185 bytes .../command/__pycache__/setopt.cpython-37.pyc | Bin 0 -> 4487 bytes .../command/__pycache__/test.cpython-37.pyc | Bin 0 -> 8082 bytes .../command/__pycache__/upload.cpython-37.pyc | Bin 0 -> 5168 bytes .../__pycache__/upload_docs.cpython-37.pyc | Bin 0 -> 6098 bytes .../site-packages/setuptools/command/alias.py | 80 + .../setuptools/command/bdist_egg.py | 502 + .../setuptools/command/bdist_rpm.py | 43 + .../setuptools/command/bdist_wininst.py | 21 + .../setuptools/command/build_clib.py | 98 + .../setuptools/command/build_ext.py | 321 + .../setuptools/command/build_py.py | 270 + .../setuptools/command/develop.py | 218 + .../setuptools/command/dist_info.py | 36 + .../setuptools/command/easy_install.py | 2342 +++++ .../setuptools/command/egg_info.py | 716 ++ .../setuptools/command/install.py | 125 + .../setuptools/command/install_egg_info.py | 62 + .../setuptools/command/install_lib.py | 121 + .../setuptools/command/install_scripts.py | 65 + .../setuptools/command/launcher manifest.xml | 15 + .../setuptools/command/py36compat.py | 136 + .../setuptools/command/register.py | 18 + .../setuptools/command/rotate.py | 66 + .../setuptools/command/saveopts.py | 22 + .../site-packages/setuptools/command/sdist.py | 200 + .../setuptools/command/setopt.py | 149 + .../site-packages/setuptools/command/test.py | 270 + .../setuptools/command/upload.py | 196 + .../setuptools/command/upload_docs.py | 206 + .../site-packages/setuptools/config.py | 635 ++ .../site-packages/setuptools/dep_util.py | 23 + .../site-packages/setuptools/depends.py | 186 + .../site-packages/setuptools/dist.py | 1147 +++ .../site-packages/setuptools/extension.py | 57 + .../setuptools/extern/__init__.py | 73 + .../__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2377 bytes .../site-packages/setuptools/glibc.py | 86 + .../site-packages/setuptools/glob.py | 174 + .../site-packages/setuptools/gui-32.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/gui-64.exe | Bin 0 -> 75264 bytes .../site-packages/setuptools/gui.exe | Bin 0 -> 65536 bytes .../site-packages/setuptools/launch.py | 35 + .../site-packages/setuptools/lib2to3_ex.py | 62 + .../site-packages/setuptools/monkey.py | 179 + .../site-packages/setuptools/msvc.py | 1301 +++ .../site-packages/setuptools/namespaces.py | 107 + .../site-packages/setuptools/package_index.py | 1128 +++ .../site-packages/setuptools/pep425tags.py | 319 + .../site-packages/setuptools/py27compat.py | 28 + .../site-packages/setuptools/py31compat.py | 32 + .../site-packages/setuptools/py33compat.py | 55 + .../site-packages/setuptools/py36compat.py | 82 + .../site-packages/setuptools/sandbox.py | 491 + .../setuptools/script (dev).tmpl | 6 + .../site-packages/setuptools/script.tmpl | 3 + .../site-packages/setuptools/site-patch.py | 74 + .../site-packages/setuptools/ssl_support.py | 260 + .../site-packages/setuptools/unicode_utils.py | 44 + .../site-packages/setuptools/version.py | 6 + .../site-packages/setuptools/wheel.py | 210 + .../setuptools/windows_support.py | 29 + .../wheel-0.32.3.dist-info/INSTALLER | 1 + .../wheel-0.32.3.dist-info/LICENSE.txt | 22 + .../wheel-0.32.3.dist-info/METADATA | 60 + .../wheel-0.32.3.dist-info/RECORD | 34 + .../wheel-0.32.3.dist-info/WHEEL | 6 + .../wheel-0.32.3.dist-info/entry_points.txt | 6 + .../wheel-0.32.3.dist-info/top_level.txt | 1 + .../python3.7/site-packages/wheel/__init__.py | 2 + .../python3.7/site-packages/wheel/__main__.py | 19 + .../wheel/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 158 bytes .../wheel/__pycache__/__main__.cpython-37.pyc | Bin 0 -> 551 bytes .../__pycache__/bdist_wheel.cpython-37.pyc | Bin 0 -> 9982 bytes .../wheel/__pycache__/metadata.cpython-37.pyc | Bin 0 -> 3725 bytes .../__pycache__/pep425tags.cpython-37.pyc | Bin 0 -> 4669 bytes .../wheel/__pycache__/pkginfo.cpython-37.pyc | Bin 0 -> 1529 bytes .../wheel/__pycache__/util.cpython-37.pyc | Bin 0 -> 1225 bytes .../__pycache__/wheelfile.cpython-37.pyc | Bin 0 -> 5223 bytes .../site-packages/wheel/bdist_wheel.py | 368 + .../site-packages/wheel/cli/__init__.py | 87 + .../cli/__pycache__/__init__.cpython-37.pyc | Bin 0 -> 2914 bytes .../cli/__pycache__/convert.cpython-37.pyc | Bin 0 -> 6169 bytes .../cli/__pycache__/install.cpython-37.pyc | Bin 0 -> 139 bytes .../wheel/cli/__pycache__/pack.cpython-37.pyc | Bin 0 -> 2424 bytes .../cli/__pycache__/unpack.cpython-37.pyc | Bin 0 -> 903 bytes .../site-packages/wheel/cli/convert.py | 269 + .../site-packages/wheel/cli/install.py | 0 .../python3.7/site-packages/wheel/cli/pack.py | 54 + .../site-packages/wheel/cli/unpack.py | 25 + .../python3.7/site-packages/wheel/metadata.py | 141 + .../site-packages/wheel/pep425tags.py | 185 + .../python3.7/site-packages/wheel/pkginfo.py | 43 + env/lib/python3.7/site-packages/wheel/util.py | 41 + .../site-packages/wheel/wheelfile.py | 160 + env/lib/python3.7/site.py | 758 ++ env/lib/python3.7/sre_compile.py | 1 + env/lib/python3.7/sre_constants.py | 1 + env/lib/python3.7/sre_parse.py | 1 + env/lib/python3.7/stat.py | 1 + env/lib/python3.7/struct.py | 1 + env/lib/python3.7/tarfile.py | 1 + env/lib/python3.7/tempfile.py | 1 + env/lib/python3.7/token.py | 1 + env/lib/python3.7/tokenize.py | 1 + env/lib/python3.7/types.py | 1 + env/lib/python3.7/warnings.py | 1 + env/lib/python3.7/weakref.py | 1 + env/pip-selfcheck.json | 1 + requirements.txt | 1 + testData.txt | 183 + untitled | 0 1184 files changed, 167997 insertions(+) create mode 100644 PyGeoIP.py create mode 100644 cc.csv create mode 100644 env/bin/__pycache__/ipwhois_cli.cpython-37.pyc create mode 100644 env/bin/__pycache__/ipwhois_utils_cli.cpython-37.pyc create mode 100644 env/bin/activate create mode 100644 env/bin/activate.csh create mode 100644 env/bin/activate.fish create mode 100644 env/bin/activate_this.py create mode 100755 env/bin/easy_install create mode 100755 env/bin/easy_install-3.7 create mode 100644 env/bin/ipwhois_cli.py create mode 100644 env/bin/ipwhois_utils_cli.py create mode 100755 env/bin/pip create mode 100755 env/bin/pip3 create mode 100755 env/bin/pip3.7 create mode 100755 env/bin/python create mode 100755 env/bin/python-config create mode 120000 env/bin/python3 create mode 120000 env/bin/python3.7 create mode 100755 env/bin/wheel create mode 120000 env/include/python3.7m create mode 120000 env/lib/python3.7/__future__.py create mode 100644 env/lib/python3.7/__pycache__/__future__.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/_bootlocale.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/_collections_abc.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/_weakrefset.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/abc.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/base64.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/bisect.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/codecs.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/copy.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/copyreg.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/enum.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/fnmatch.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/functools.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/genericpath.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/hashlib.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/heapq.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/hmac.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/imp.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/io.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/keyword.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/linecache.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/locale.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/operator.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/os.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/posixpath.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/random.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/re.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/reprlib.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/shutil.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/site.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/sre_compile.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/sre_constants.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/sre_parse.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/stat.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/struct.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/tarfile.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/tempfile.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/token.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/tokenize.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/types.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/warnings.cpython-37.pyc create mode 100644 env/lib/python3.7/__pycache__/weakref.cpython-37.pyc create mode 120000 env/lib/python3.7/_bootlocale.py create mode 120000 env/lib/python3.7/_collections_abc.py create mode 120000 env/lib/python3.7/_dummy_thread.py create mode 120000 env/lib/python3.7/_weakrefset.py create mode 120000 env/lib/python3.7/abc.py create mode 120000 env/lib/python3.7/base64.py create mode 120000 env/lib/python3.7/bisect.py create mode 120000 env/lib/python3.7/codecs.py create mode 120000 env/lib/python3.7/collections create mode 120000 env/lib/python3.7/config-3.7m-x86_64-linux-gnu create mode 120000 env/lib/python3.7/copy.py create mode 120000 env/lib/python3.7/copyreg.py create mode 100644 env/lib/python3.7/distutils/__init__.py create mode 100644 env/lib/python3.7/distutils/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/distutils/distutils.cfg create mode 120000 env/lib/python3.7/encodings create mode 120000 env/lib/python3.7/enum.py create mode 120000 env/lib/python3.7/fnmatch.py create mode 120000 env/lib/python3.7/functools.py create mode 120000 env/lib/python3.7/genericpath.py create mode 120000 env/lib/python3.7/hashlib.py create mode 120000 env/lib/python3.7/heapq.py create mode 120000 env/lib/python3.7/hmac.py create mode 120000 env/lib/python3.7/imp.py create mode 120000 env/lib/python3.7/importlib create mode 120000 env/lib/python3.7/io.py create mode 120000 env/lib/python3.7/keyword.py create mode 120000 env/lib/python3.7/lib-dynload create mode 120000 env/lib/python3.7/linecache.py create mode 120000 env/lib/python3.7/locale.py create mode 100644 env/lib/python3.7/no-global-site-packages.txt create mode 120000 env/lib/python3.7/ntpath.py create mode 120000 env/lib/python3.7/operator.py create mode 100644 env/lib/python3.7/orig-prefix.txt create mode 120000 env/lib/python3.7/os.py create mode 120000 env/lib/python3.7/posixpath.py create mode 120000 env/lib/python3.7/random.py create mode 120000 env/lib/python3.7/re.py create mode 120000 env/lib/python3.7/reprlib.py create mode 120000 env/lib/python3.7/rlcompleter.py create mode 120000 env/lib/python3.7/shutil.py create mode 100644 env/lib/python3.7/site-packages/__pycache__/easy_install.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__init__.py create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/_compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/dnssec.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/e164.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/edns.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/entropy.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/exception.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/flags.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/grange.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/hash.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/inet.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/ipv4.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/ipv6.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/message.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/name.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/namedict.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/node.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/opcode.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/query.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/rcode.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/rdata.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/rdataclass.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/rdataset.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/rdatatype.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/renderer.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/resolver.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/reversename.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/rrset.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/set.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/tokenizer.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/tsig.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/tsigkeyring.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/ttl.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/update.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/version.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/wiredata.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/__pycache__/zone.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/_compat.py create mode 100644 env/lib/python3.7/site-packages/dns/dnssec.py create mode 100644 env/lib/python3.7/site-packages/dns/e164.py create mode 100644 env/lib/python3.7/site-packages/dns/edns.py create mode 100644 env/lib/python3.7/site-packages/dns/entropy.py create mode 100644 env/lib/python3.7/site-packages/dns/exception.py create mode 100644 env/lib/python3.7/site-packages/dns/flags.py create mode 100644 env/lib/python3.7/site-packages/dns/grange.py create mode 100644 env/lib/python3.7/site-packages/dns/hash.py create mode 100644 env/lib/python3.7/site-packages/dns/inet.py create mode 100644 env/lib/python3.7/site-packages/dns/ipv4.py create mode 100644 env/lib/python3.7/site-packages/dns/ipv6.py create mode 100644 env/lib/python3.7/site-packages/dns/message.py create mode 100644 env/lib/python3.7/site-packages/dns/name.py create mode 100644 env/lib/python3.7/site-packages/dns/namedict.py create mode 100644 env/lib/python3.7/site-packages/dns/node.py create mode 100644 env/lib/python3.7/site-packages/dns/opcode.py create mode 100644 env/lib/python3.7/site-packages/dns/py.typed create mode 100644 env/lib/python3.7/site-packages/dns/query.py create mode 100644 env/lib/python3.7/site-packages/dns/rcode.py create mode 100644 env/lib/python3.7/site-packages/dns/rdata.py create mode 100644 env/lib/python3.7/site-packages/dns/rdataclass.py create mode 100644 env/lib/python3.7/site-packages/dns/rdataset.py create mode 100644 env/lib/python3.7/site-packages/dns/rdatatype.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/AFSDB.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/AVC.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/CAA.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/CDNSKEY.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/CDS.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/CERT.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/CNAME.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/CSYNC.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/DLV.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/DNAME.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/DNSKEY.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/DS.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/EUI48.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/EUI64.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/GPOS.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/HINFO.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/HIP.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/ISDN.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/LOC.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/MX.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/NS.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC3.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC3PARAM.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/OPENPGPKEY.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/PTR.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/RP.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/RRSIG.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/RT.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/SOA.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/SPF.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/SSHFP.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/TLSA.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/TXT.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/URI.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/X25.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__init__.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/AFSDB.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/AVC.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CAA.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CDNSKEY.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CDS.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CERT.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CNAME.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CSYNC.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DLV.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DNAME.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DNSKEY.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DS.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/EUI48.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/EUI64.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/GPOS.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/HINFO.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/HIP.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/ISDN.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/LOC.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/MX.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/NS.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/NSEC.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/NSEC3.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/OPENPGPKEY.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/PTR.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/RP.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/RRSIG.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/RT.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/SOA.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/SPF.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/SSHFP.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/TLSA.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/TXT.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/URI.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/X25.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/CH/A.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/CH/__init__.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/CH/__pycache__/A.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/CH/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/A.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/AAAA.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/APL.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/DHCID.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/IPSECKEY.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/KX.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/NAPTR.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/NSAP.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/NSAP_PTR.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/PX.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/SRV.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/WKS.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__init__.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/A.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/AAAA.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/APL.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/DHCID.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/IPSECKEY.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/KX.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/NAPTR.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/NSAP.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/NSAP_PTR.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/PX.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/SRV.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/WKS.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/__init__.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/dnskeybase.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/dsbase.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/euibase.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/mxbase.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/nsbase.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/txtbase.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/dnskeybase.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/dsbase.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/euibase.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/mxbase.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/nsbase.py create mode 100644 env/lib/python3.7/site-packages/dns/rdtypes/txtbase.py create mode 100644 env/lib/python3.7/site-packages/dns/renderer.py create mode 100644 env/lib/python3.7/site-packages/dns/resolver.py create mode 100644 env/lib/python3.7/site-packages/dns/reversename.py create mode 100644 env/lib/python3.7/site-packages/dns/rrset.py create mode 100644 env/lib/python3.7/site-packages/dns/set.py create mode 100644 env/lib/python3.7/site-packages/dns/tokenizer.py create mode 100644 env/lib/python3.7/site-packages/dns/tsig.py create mode 100644 env/lib/python3.7/site-packages/dns/tsigkeyring.py create mode 100644 env/lib/python3.7/site-packages/dns/ttl.py create mode 100644 env/lib/python3.7/site-packages/dns/update.py create mode 100644 env/lib/python3.7/site-packages/dns/version.py create mode 100644 env/lib/python3.7/site-packages/dns/wiredata.py create mode 100644 env/lib/python3.7/site-packages/dns/zone.py create mode 100644 env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/DESCRIPTION.rst create mode 100644 env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/INSTALLER create mode 100644 env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/LICENSE.txt create mode 100644 env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/METADATA create mode 100644 env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/RECORD create mode 100644 env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/WHEEL create mode 100644 env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/metadata.json create mode 100644 env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/top_level.txt create mode 100644 env/lib/python3.7/site-packages/easy_install.py create mode 100644 env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/DESCRIPTION.rst create mode 100644 env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/INSTALLER create mode 100644 env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/METADATA create mode 100644 env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/RECORD create mode 100644 env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/WHEEL create mode 100644 env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/metadata.json create mode 100644 env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/top_level.txt create mode 100644 env/lib/python3.7/site-packages/ipwhois/__init__.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/asn.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/exceptions.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/experimental.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/hr.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/ipwhois.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/net.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/nir.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/rdap.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/utils.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/__pycache__/whois.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/ipwhois/asn.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/data/iso_3166-1.csv create mode 100644 env/lib/python3.7/site-packages/ipwhois/data/iso_3166-1_list_en.xml create mode 100644 env/lib/python3.7/site-packages/ipwhois/exceptions.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/experimental.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/hr.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/ipwhois.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/net.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/nir.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/rdap.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/utils.py create mode 100644 env/lib/python3.7/site-packages/ipwhois/whois.py create mode 100644 env/lib/python3.7/site-packages/pip-18.1.dist-info/INSTALLER create mode 100644 env/lib/python3.7/site-packages/pip-18.1.dist-info/LICENSE.txt create mode 100644 env/lib/python3.7/site-packages/pip-18.1.dist-info/METADATA create mode 100644 env/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD create mode 100644 env/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL create mode 100644 env/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt create mode 100644 env/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt create mode 100644 env/lib/python3.7/site-packages/pip/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/__main__.py create mode 100644 env/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/download.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/exceptions.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/index.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/locations.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/resolve.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/__pycache__/wheel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/build_env.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cache.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/autocompletion.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/parser.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/autocompletion.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/base_command.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/parser.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/configuration.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/download.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/install.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/show.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/wheel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/check.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/completion.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/configuration.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/download.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/freeze.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/hash.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/help.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/install.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/list.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/search.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/show.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/commands/wheel.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/configuration.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/download.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/exceptions.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/index.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/locations.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/candidate.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/index.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/candidate.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/format_control.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/index.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/models/link.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/operations/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/operations/check.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/operations/freeze.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/operations/prepare.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/pep425tags.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/pyproject.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/constructors.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_set.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/constructors.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/req_file.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/req_install.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/req_set.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/resolve.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/misc.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/models.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/outdated.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/packaging.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/typing.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/encoding.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/glibc.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/hashes.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/logging.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/misc.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/models.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/outdated.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/packaging.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/typing.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/utils/ui.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/git.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py create mode 100644 env/lib/python3.7/site-packages/pip/_internal/wheel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/__pycache__/distro.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/__pycache__/retrying.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/appdirs.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/certifi/core.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/chardet/version.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/database.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/index.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/t32.exe create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/t64.exe create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/util.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/version.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/w32.exe create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/w64.exe create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/distro.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/py.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/codec.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/core.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/ipaddress.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/pidlockfile.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/packaging/version.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/check.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/bar.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/counter.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pyparsing.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pytoml/parser.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/pytoml/writer.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/api.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/auth.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/certs.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/compat.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/help.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/models.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/packages.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/structures.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/requests/utils.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/retrying.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/six.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py create mode 100644 env/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/__init__.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/_vendor/six.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/extern/__init__.py create mode 100644 env/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/pkg_resources/py31compat.py create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/INSTALLER create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/LICENSE create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/METADATA create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/RECORD create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/WHEEL create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/dependency_links.txt create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/entry_points.txt create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/top_level.txt create mode 100644 env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/zip-safe create mode 100644 env/lib/python3.7/site-packages/setuptools/__init__.py create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/py36compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_deprecation_warning.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/__init__.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py create mode 100644 env/lib/python3.7/site-packages/setuptools/_vendor/six.py create mode 100644 env/lib/python3.7/site-packages/setuptools/archive_util.py create mode 100644 env/lib/python3.7/site-packages/setuptools/build_meta.py create mode 100644 env/lib/python3.7/site-packages/setuptools/cli-32.exe create mode 100644 env/lib/python3.7/site-packages/setuptools/cli-64.exe create mode 100644 env/lib/python3.7/site-packages/setuptools/cli.exe create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__init__.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/command/alias.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/bdist_egg.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/build_clib.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/build_ext.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/build_py.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/develop.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/dist_info.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/easy_install.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/egg_info.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/install.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/install_egg_info.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/install_lib.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/install_scripts.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml create mode 100644 env/lib/python3.7/site-packages/setuptools/command/py36compat.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/register.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/rotate.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/saveopts.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/sdist.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/setopt.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/test.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/upload.py create mode 100644 env/lib/python3.7/site-packages/setuptools/command/upload_docs.py create mode 100644 env/lib/python3.7/site-packages/setuptools/config.py create mode 100644 env/lib/python3.7/site-packages/setuptools/dep_util.py create mode 100644 env/lib/python3.7/site-packages/setuptools/depends.py create mode 100644 env/lib/python3.7/site-packages/setuptools/dist.py create mode 100644 env/lib/python3.7/site-packages/setuptools/extension.py create mode 100644 env/lib/python3.7/site-packages/setuptools/extern/__init__.py create mode 100644 env/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/setuptools/glibc.py create mode 100644 env/lib/python3.7/site-packages/setuptools/glob.py create mode 100644 env/lib/python3.7/site-packages/setuptools/gui-32.exe create mode 100644 env/lib/python3.7/site-packages/setuptools/gui-64.exe create mode 100644 env/lib/python3.7/site-packages/setuptools/gui.exe create mode 100644 env/lib/python3.7/site-packages/setuptools/launch.py create mode 100644 env/lib/python3.7/site-packages/setuptools/lib2to3_ex.py create mode 100644 env/lib/python3.7/site-packages/setuptools/monkey.py create mode 100644 env/lib/python3.7/site-packages/setuptools/msvc.py create mode 100644 env/lib/python3.7/site-packages/setuptools/namespaces.py create mode 100644 env/lib/python3.7/site-packages/setuptools/package_index.py create mode 100644 env/lib/python3.7/site-packages/setuptools/pep425tags.py create mode 100644 env/lib/python3.7/site-packages/setuptools/py27compat.py create mode 100644 env/lib/python3.7/site-packages/setuptools/py31compat.py create mode 100644 env/lib/python3.7/site-packages/setuptools/py33compat.py create mode 100644 env/lib/python3.7/site-packages/setuptools/py36compat.py create mode 100644 env/lib/python3.7/site-packages/setuptools/sandbox.py create mode 100644 env/lib/python3.7/site-packages/setuptools/script (dev).tmpl create mode 100644 env/lib/python3.7/site-packages/setuptools/script.tmpl create mode 100644 env/lib/python3.7/site-packages/setuptools/site-patch.py create mode 100644 env/lib/python3.7/site-packages/setuptools/ssl_support.py create mode 100644 env/lib/python3.7/site-packages/setuptools/unicode_utils.py create mode 100644 env/lib/python3.7/site-packages/setuptools/version.py create mode 100644 env/lib/python3.7/site-packages/setuptools/wheel.py create mode 100644 env/lib/python3.7/site-packages/setuptools/windows_support.py create mode 100644 env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/INSTALLER create mode 100644 env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/LICENSE.txt create mode 100644 env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/METADATA create mode 100644 env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/RECORD create mode 100644 env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/WHEEL create mode 100644 env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/entry_points.txt create mode 100644 env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/top_level.txt create mode 100644 env/lib/python3.7/site-packages/wheel/__init__.py create mode 100644 env/lib/python3.7/site-packages/wheel/__main__.py create mode 100644 env/lib/python3.7/site-packages/wheel/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/__pycache__/__main__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/__pycache__/bdist_wheel.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/__pycache__/metadata.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/__pycache__/pep425tags.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/__pycache__/pkginfo.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/__pycache__/util.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/__pycache__/wheelfile.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/bdist_wheel.py create mode 100644 env/lib/python3.7/site-packages/wheel/cli/__init__.py create mode 100644 env/lib/python3.7/site-packages/wheel/cli/__pycache__/__init__.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/cli/__pycache__/convert.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/cli/__pycache__/install.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/cli/__pycache__/pack.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/cli/__pycache__/unpack.cpython-37.pyc create mode 100644 env/lib/python3.7/site-packages/wheel/cli/convert.py create mode 100644 env/lib/python3.7/site-packages/wheel/cli/install.py create mode 100644 env/lib/python3.7/site-packages/wheel/cli/pack.py create mode 100644 env/lib/python3.7/site-packages/wheel/cli/unpack.py create mode 100644 env/lib/python3.7/site-packages/wheel/metadata.py create mode 100644 env/lib/python3.7/site-packages/wheel/pep425tags.py create mode 100644 env/lib/python3.7/site-packages/wheel/pkginfo.py create mode 100644 env/lib/python3.7/site-packages/wheel/util.py create mode 100644 env/lib/python3.7/site-packages/wheel/wheelfile.py create mode 100644 env/lib/python3.7/site.py create mode 120000 env/lib/python3.7/sre_compile.py create mode 120000 env/lib/python3.7/sre_constants.py create mode 120000 env/lib/python3.7/sre_parse.py create mode 120000 env/lib/python3.7/stat.py create mode 120000 env/lib/python3.7/struct.py create mode 120000 env/lib/python3.7/tarfile.py create mode 120000 env/lib/python3.7/tempfile.py create mode 120000 env/lib/python3.7/token.py create mode 120000 env/lib/python3.7/tokenize.py create mode 120000 env/lib/python3.7/types.py create mode 120000 env/lib/python3.7/warnings.py create mode 120000 env/lib/python3.7/weakref.py create mode 100644 env/pip-selfcheck.json create mode 100644 requirements.txt create mode 100644 testData.txt create mode 100644 untitled diff --git a/PyGeoIP.py b/PyGeoIP.py new file mode 100644 index 0000000..57374cf --- /dev/null +++ b/PyGeoIP.py @@ -0,0 +1,62 @@ +#!/usr/bin/python3 + +import ipwhois +from ipwhois.net import Net +from ipwhois.asn import IPASN +import warnings + +ipList = [] + +def lookupIP(inData): + try: + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", category=UserWarning) + ipnet = Net(inData) + ipobj = IPASN(ipnet) + results = ipobj.lookup() + # print(results) + return results + + except ipwhois.exceptions.IPDefinedError: + pass # We do not care about local/invalid IPs + except Exception as e: + pass # Garbage data was given lol + + +def parseIPS(): + with open("testData.txt", 'r') as f: + testdata = f.read() + + data = testdata.split('\n') + for ip in data: + ip = ip.strip() + ipAddr = ip.split() + if len(ipAddr) == 2: + ipList.append(ipAddr) + else: + pass + +parseIPS() + +ff = lookupIP("122.106.224.146") + +print(ff["asn_country_code"]) + +for ips in ipList: + # ccode = ipCheck(lookupIP(ips[1])) + ret = lookupIP(ips[1]) + if ret == None: + continue + cc = ret["asn_country_code"] + desc = ret["asn_description"] + if cc == "AU" or cc == "NZ" or cc == "US": + continue + print("IP: {}\t\tCountry: {}\tDesc: {}\tCount: {}".format(ips[1], cc, desc, ips[0])) + + + + +# print(ipList[0]) +# lookupIP("123.23.23.12") + +##{'asn_registry': 'apnic', 'asn': '4134', 'asn_cidr': '220.174.0.0/16', 'asn_country_code': 'CN', 'asn_date': '2002-10-30', 'asn_description': 'CHINANET-BACKBONE No.31,Jin-rong Street, CN'} \ No newline at end of file diff --git a/cc.csv b/cc.csv new file mode 100644 index 0000000..a8924ea --- /dev/null +++ b/cc.csv @@ -0,0 +1,249 @@ +Afghanistan,AF +Åland Islands,AX +Albania,AL +Algeria,DZ +American Samoa,AS +Andorra,AD +Angola,AO +Anguilla,AI +Antarctica,AQ +Antigua and Barbuda,AG +Argentina,AR +Armenia,AM +Aruba,AW +Australia,AU +Austria,AT +Azerbaijan,AZ +Bahamas,BS +Bahrain,BH +Bangladesh,BD +Barbados,BB +Belarus,BY +Belgium,BE +Belize,BZ +Benin,BJ +Bermuda,BM +Bhutan,BT +Bolivia (Plurinational State of),BO +"Bonaire, Sint Eustatius and Saba",BQ +Bosnia and Herzegovina,BA +Botswana,BW +Bouvet Island,BV +Brazil,BR +British Indian Ocean Territory,IO +Brunei Darussalam,BN +Bulgaria,BG +Burkina Faso,BF +Burundi,BI +Cambodia,KH +Cameroon,CM +Canada,CA +Cabo Verde,CV +Cayman Islands,KY +Central African Republic,CF +Chad,TD +Chile,CL +China,CN +Christmas Island,CX +Cocos (Keeling) Islands,CC +Colombia,CO +Comoros,KM +Congo,CG +Congo (Democratic Republic of the),CD +Cook Islands,CK +Costa Rica,CR +Côte d'Ivoire,CI +Croatia,HR +Cuba,CU +Curaçao,CW +Cyprus,CY +Czech Republic,CZ +Denmark,DK +Djibouti,DJ +Dominica,DM +Dominican Republic,DO +Ecuador,EC +Egypt,EG +El Salvador,SV +Equatorial Guinea,GQ +Eritrea,ER +Estonia,EE +Ethiopia,ET +Falkland Islands (Malvinas),FK +Faroe Islands,FO +Fiji,FJ +Finland,FI +France,FR +French Guiana,GF +French Polynesia,PF +French Southern Territories,TF +Gabon,GA +Gambia,GM +Georgia,GE +Germany,DE +Ghana,GH +Gibraltar,GI +Greece,GR +Greenland,GL +Grenada,GD +Guadeloupe,GP +Guam,GU +Guatemala,GT +Guernsey,GG +Guinea,GN +Guinea-Bissau,GW +Guyana,GY +Haiti,HT +Heard Island and McDonald Islands,HM +Holy See,VA +Honduras,HN +Hong Kong,HK +Hungary,HU +Iceland,IS +India,IN +Indonesia,ID +Iran (Islamic Republic of),IR +Iraq,IQ +Ireland,IE +Isle of Man,IM +Israel,IL +Italy,IT +Jamaica,JM +Japan,JP +Jersey,JE +Jordan,JO +Kazakhstan,KZ +Kenya,KE +Kiribati,KI +Korea (Democratic People's Republic of),KP +Korea (Republic of),KR +Kuwait,KW +Kyrgyzstan,KG +Lao People's Democratic Republic,LA +Latvia,LV +Lebanon,LB +Lesotho,LS +Liberia,LR +Libya,LY +Liechtenstein,LI +Lithuania,LT +Luxembourg,LU +Macao,MO +Macedonia (the former Yugoslav Republic of),MK +Madagascar,MG +Malawi,MW +Malaysia,MY +Maldives,MV +Mali,ML +Malta,MT +Marshall Islands,MH +Martinique,MQ +Mauritania,MR +Mauritius,MU +Mayotte,YT +Mexico,MX +Micronesia (Federated States of),FM +Moldova (Republic of),MD +Monaco,MC +Mongolia,MN +Montenegro,ME +Montserrat,MS +Morocco,MA +Mozambique,MZ +Myanmar,MM +Namibia,NA +Nauru,NR +Nepal,NP +Netherlands,NL +New Caledonia,NC +New Zealand,NZ +Nicaragua,NI +Niger,NE +Nigeria,NG +Niue,NU +Norfolk Island,NF +Northern Mariana Islands,MP +Norway,NO +Oman,OM +Pakistan,PK +Palau,PW +"Palestine, State of",PS +Panama,PA +Papua New Guinea,PG +Paraguay,PY +Peru,PE +Philippines,PH +Pitcairn,PN +Poland,PL +Portugal,PT +Puerto Rico,PR +Qatar,QA +Réunion,RE +Romania,RO +Russian Federation,RU +Rwanda,RW +Saint Barthélemy,BL +"Saint Helena, Ascension and Tristan da Cunha",SH +Saint Kitts and Nevis,KN +Saint Lucia,LC +Saint Martin (French part),MF +Saint Pierre and Miquelon,PM +Saint Vincent and the Grenadines,VC +Samoa,WS +San Marino,SM +Sao Tome and Principe,ST +Saudi Arabia,SA +Senegal,SN +Serbia,RS +Seychelles,SC +Sierra Leone,SL +Singapore,SG +Sint Maarten (Dutch part),SX +Slovakia,SK +Slovenia,SI +Solomon Islands,SB +Somalia,SO +South Africa,ZA +South Georgia and the South Sandwich Islands,GS +South Sudan,SS +Spain,ES +Sri Lanka,LK +Sudan,SD +Suriname,SR +Svalbard and Jan Mayen,SJ +Swaziland,SZ +Sweden,SE +Switzerland,CH +Syrian Arab Republic,SY +"Taiwan, Province of China",TW +Tajikistan,TJ +"Tanzania, United Republic of",TZ +Thailand,TH +Timor-Leste,TL +Togo,TG +Tokelau,TK +Tonga,TO +Trinidad and Tobago,TT +Tunisia,TN +Turkey,TR +Turkmenistan,TM +Turks and Caicos Islands,TC +Tuvalu,TV +Uganda,UG +Ukraine,UA +United Arab Emirates,AE +United Kingdom of Great Britain and Northern Ireland,GB +United States of America,US +United States Minor Outlying Islands,UM +Uruguay,UY +Uzbekistan,UZ +Vanuatu,VU +Venezuela (Bolivarian Republic of),VE +Viet Nam,VN +Virgin Islands (British),VG +Virgin Islands (U.S.),VI +Wallis and Futuna,WF +Western Sahara,EH +Yemen,YE +Zambia,ZM +Zimbabwe,ZW diff --git a/env/bin/__pycache__/ipwhois_cli.cpython-37.pyc b/env/bin/__pycache__/ipwhois_cli.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5edd15f753338d33879894bed0695bab175ea6cb GIT binary patch literal 29564 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 literal 0 HcmV?d00001 diff --git a/env/bin/activate b/env/bin/activate new file mode 100644 index 0000000..045e167 --- /dev/null +++ b/env/bin/activate @@ -0,0 +1,78 @@ +# This file must be used with "source bin/activate" *from bash* +# you cannot run it directly + +deactivate () { + unset -f pydoc >/dev/null 2>&1 + + # reset old environment variables + # ! [ -z ${VAR+_} ] returns true if VAR is declared at all + if ! [ -z "${_OLD_VIRTUAL_PATH+_}" ] ; then + PATH="$_OLD_VIRTUAL_PATH" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if ! [ -z "${_OLD_VIRTUAL_PYTHONHOME+_}" ] ; then + PYTHONHOME="$_OLD_VIRTUAL_PYTHONHOME" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # This should detect bash and zsh, which have a hash command that must + # be called to get it to forget past commands. Without forgetting + # past commands the $PATH changes we made may not be respected + if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null + fi + + if ! [ -z "${_OLD_VIRTUAL_PS1+_}" ] ; then + PS1="$_OLD_VIRTUAL_PS1" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + if [ ! "${1-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +VIRTUAL_ENV="/home/ben/Documents/Projects/Python/PyGeoIP/env" +export VIRTUAL_ENV + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/bin:$PATH" +export PATH + +# unset PYTHONHOME if set +if ! [ -z "${PYTHONHOME+_}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="$PYTHONHOME" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT-}" ] ; then + _OLD_VIRTUAL_PS1="$PS1" + if [ "x" != x ] ; then + PS1="$PS1" + else + PS1="(`basename \"$VIRTUAL_ENV\"`) $PS1" + fi + export PS1 +fi + +# Make sure to unalias pydoc if it's already there +alias pydoc 2>/dev/null >/dev/null && unalias pydoc + +pydoc () { + python -m pydoc "$@" +} + +# This should detect bash and zsh, which have a hash command that must +# be called to get it to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ] ; then + hash -r 2>/dev/null +fi diff --git a/env/bin/activate.csh b/env/bin/activate.csh new file mode 100644 index 0000000..07afb72 --- /dev/null +++ b/env/bin/activate.csh @@ -0,0 +1,36 @@ +# This file must be used with "source bin/activate.csh" *from csh*. +# You cannot run it directly. +# Created by Davide Di Blasi . + +alias deactivate 'test $?_OLD_VIRTUAL_PATH != 0 && setenv PATH "$_OLD_VIRTUAL_PATH" && unset _OLD_VIRTUAL_PATH; rehash; test $?_OLD_VIRTUAL_PROMPT != 0 && set prompt="$_OLD_VIRTUAL_PROMPT" && unset _OLD_VIRTUAL_PROMPT; unsetenv VIRTUAL_ENV; test "\!:*" != "nondestructive" && unalias deactivate && unalias pydoc' + +# Unset irrelevant variables. +deactivate nondestructive + +setenv VIRTUAL_ENV "/home/ben/Documents/Projects/Python/PyGeoIP/env" + +set _OLD_VIRTUAL_PATH="$PATH" +setenv PATH "$VIRTUAL_ENV/bin:$PATH" + + + +if ("" != "") then + set env_name = "" +else + set env_name = `basename "$VIRTUAL_ENV"` +endif + +# Could be in a non-interactive environment, +# in which case, $prompt is undefined and we wouldn't +# care about the prompt anyway. +if ( $?prompt ) then + set _OLD_VIRTUAL_PROMPT="$prompt" + set prompt = "[$env_name] $prompt" +endif + +unset env_name + +alias pydoc python -m pydoc + +rehash + diff --git a/env/bin/activate.fish b/env/bin/activate.fish new file mode 100644 index 0000000..b75c9ee --- /dev/null +++ b/env/bin/activate.fish @@ -0,0 +1,76 @@ +# This file must be used using `. bin/activate.fish` *within a running fish ( http://fishshell.com ) session*. +# Do not run it directly. + +function deactivate -d 'Exit virtualenv mode and return to the normal environment.' + # reset old environment variables + if test -n "$_OLD_VIRTUAL_PATH" + set -gx PATH $_OLD_VIRTUAL_PATH + set -e _OLD_VIRTUAL_PATH + end + + if test -n "$_OLD_VIRTUAL_PYTHONHOME" + set -gx PYTHONHOME $_OLD_VIRTUAL_PYTHONHOME + set -e _OLD_VIRTUAL_PYTHONHOME + end + + if test -n "$_OLD_FISH_PROMPT_OVERRIDE" + # Set an empty local `$fish_function_path` to allow the removal of `fish_prompt` using `functions -e`. + set -l fish_function_path + + # Erase virtualenv's `fish_prompt` and restore the original. + functions -e fish_prompt + functions -c _old_fish_prompt fish_prompt + functions -e _old_fish_prompt + set -e _OLD_FISH_PROMPT_OVERRIDE + end + + set -e VIRTUAL_ENV + + if test "$argv[1]" != 'nondestructive' + # Self-destruct! + functions -e pydoc + functions -e deactivate + end +end + +# Unset irrelevant variables. +deactivate nondestructive + +set -gx VIRTUAL_ENV "/home/ben/Documents/Projects/Python/PyGeoIP/env" + +set -gx _OLD_VIRTUAL_PATH $PATH +set -gx PATH "$VIRTUAL_ENV/bin" $PATH + +# Unset `$PYTHONHOME` if set. +if set -q PYTHONHOME + set -gx _OLD_VIRTUAL_PYTHONHOME $PYTHONHOME + set -e PYTHONHOME +end + +function pydoc + python -m pydoc $argv +end + +if test -z "$VIRTUAL_ENV_DISABLE_PROMPT" + # Copy the current `fish_prompt` function as `_old_fish_prompt`. + functions -c fish_prompt _old_fish_prompt + + function fish_prompt + # Save the current $status, for fish_prompts that display it. + set -l old_status $status + + # Prompt override provided? + # If not, just prepend the environment name. + if test -n "" + printf '%s%s' "" (set_color normal) + else + printf '%s(%s) ' (set_color normal) (basename "$VIRTUAL_ENV") + end + + # Restore the original $status + echo "exit $old_status" | source + _old_fish_prompt + end + + set -gx _OLD_FISH_PROMPT_OVERRIDE "$VIRTUAL_ENV" +end diff --git a/env/bin/activate_this.py b/env/bin/activate_this.py new file mode 100644 index 0000000..f18193b --- /dev/null +++ b/env/bin/activate_this.py @@ -0,0 +1,34 @@ +"""By using execfile(this_file, dict(__file__=this_file)) you will +activate this virtualenv environment. + +This can be used when you must use an existing Python interpreter, not +the virtualenv bin/python +""" + +try: + __file__ +except NameError: + raise AssertionError( + "You must run this like execfile('path/to/activate_this.py', dict(__file__='path/to/activate_this.py'))") +import sys +import os + +old_os_path = os.environ.get('PATH', '') +os.environ['PATH'] = os.path.dirname(os.path.abspath(__file__)) + os.pathsep + old_os_path +base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +if sys.platform == 'win32': + site_packages = os.path.join(base, 'Lib', 'site-packages') +else: + site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages') +prev_sys_path = list(sys.path) +import site +site.addsitedir(site_packages) +sys.real_prefix = sys.prefix +sys.prefix = base +# Move the added items to the front of the path: +new_sys_path = [] +for item in list(sys.path): + if item not in prev_sys_path: + new_sys_path.append(item) + sys.path.remove(item) +sys.path[:0] = new_sys_path diff --git a/env/bin/easy_install b/env/bin/easy_install new file mode 100755 index 0000000..b3bbf71 --- /dev/null +++ b/env/bin/easy_install @@ -0,0 +1,11 @@ +#!/home/ben/Documents/Projects/Python/PyGeoIP/env/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/env/bin/easy_install-3.7 b/env/bin/easy_install-3.7 new file mode 100755 index 0000000..b3bbf71 --- /dev/null +++ b/env/bin/easy_install-3.7 @@ -0,0 +1,11 @@ +#!/home/ben/Documents/Projects/Python/PyGeoIP/env/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from setuptools.command.easy_install import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/env/bin/ipwhois_cli.py b/env/bin/ipwhois_cli.py new file mode 100644 index 0000000..cca0a09 --- /dev/null +++ b/env/bin/ipwhois_cli.py @@ -0,0 +1,1517 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# CLI python script interface for ipwhois.IPWhois lookups. + +import argparse +import json +from os import path +from ipwhois import IPWhois +from ipwhois.hr import (HR_ASN, HR_RDAP, HR_RDAP_COMMON, HR_WHOIS, + HR_WHOIS_NIR) + +try: # pragma: no cover + from urllib.request import (ProxyHandler, + build_opener) +except ImportError: # pragma: no cover + from urllib2 import (ProxyHandler, + build_opener) + +# CLI ANSI rendering +ANSI = { + 'end': '\033[0m', + 'b': '\033[1m', + 'ul': '\033[4m', + 'red': '\033[31m', + 'green': '\033[32m', + 'yellow': '\033[33m', + 'cyan': '\033[36m' +} + +# Color definitions for sub lines +COLOR_DEPTH = { + '0': ANSI['green'], + '1': ANSI['yellow'], + '2': ANSI['red'], + '3': ANSI['cyan'] +} + +# Line formatting, keys ending in C are colorized versions. +LINES = { + '1': '>> ', + '2': '>> >>> ', + '3': '>> >>> >>>> ', + '4': '>> >>> >>>> >>>>> ', + '1C': '{0}>>{1} '.format(COLOR_DEPTH['0'], ANSI['end']), + '2C': '{0}>>{1} >>>{2} '.format( + COLOR_DEPTH['0'], COLOR_DEPTH['1'], ANSI['end'] + ), + '3C': '{0}>>{1} >>>{2} >>>>{3} '.format( + COLOR_DEPTH['0'], COLOR_DEPTH['1'], COLOR_DEPTH['2'], ANSI['end'] + ), + '4C': '{0}>>{1} >>>{2} >>>>{3} >>>>>{4} '.format( + COLOR_DEPTH['0'], COLOR_DEPTH['1'], COLOR_DEPTH['2'], COLOR_DEPTH['3'], + ANSI['end'] + ), +} + +# Setup the arg parser. +parser = argparse.ArgumentParser( + description='ipwhois CLI interface' +) +parser.add_argument( + '--whois', + action='store_true', + help='Retrieve whois data via legacy Whois (port 43) instead of RDAP ' + '(default).' +) +parser.add_argument( + '--exclude_nir', + action='store_true', + help='Disable NIR whois lookups (JPNIC, KRNIC). This is the opposite of ' + 'the ipwhois inc_nir, in order to enable inc_nir by default in the ' + 'CLI.', + default=False +) +parser.add_argument( + '--json', + action='store_true', + help='Output results in JSON format.', + default=False +) + +# Output options +group = parser.add_argument_group('Output options') +group.add_argument( + '--hr', + action='store_true', + help='If set, returns results with human readable key translations.' +) +group.add_argument( + '--show_name', + action='store_true', + help='If this and --hr are set, the key name is shown in parentheses after' + 'its short value' +) +group.add_argument( + '--colorize', + action='store_true', + help='If set, colorizes the output using ANSI. Should work in most ' + 'platform consoles.' +) + +# IPWhois settings (common) +group = parser.add_argument_group('IPWhois settings') +group.add_argument( + '--timeout', + type=int, + default=5, + metavar='TIMEOUT', + help='The default timeout for socket connections in seconds.' +) +group.add_argument( + '--proxy_http', + type=str, + nargs=1, + default='', + metavar='"PROXY_HTTP"', + help='The proxy HTTP address passed to request.ProxyHandler. User auth ' + 'can be passed like "http://user:pass@192.168.0.1:80"', + required=False +) +group.add_argument( + '--proxy_https', + type=str, + nargs=1, + default='', + metavar='"PROXY_HTTPS"', + help='The proxy HTTPS address passed to request.ProxyHandler. User auth' + 'can be passed like "https://user:pass@192.168.0.1:443"', + required=False +) +group.add_argument( + '--disallow_permutations', + action='store_true', + help='Disable additional methods if DNS lookups to Cymru fail. This is the' + ' opposite of the ipwhois allow_permutations, in order to enable ' + 'allow_permutations by default in the CLI. *WARNING* deprecated in ' + 'favor of new argument asn_methods.', + default=False +) + +# Common (RDAP & Legacy Whois) +group = parser.add_argument_group('Common settings (RDAP & Legacy Whois)') +group.add_argument( + '--inc_raw', + action='store_true', + help='Include the raw whois results in the output.' +) +group.add_argument( + '--retry_count', + type=int, + default=3, + metavar='RETRY_COUNT', + help='The number of times to retry in case socket errors, timeouts, ' + 'connection resets, etc. are encountered.' +) +group.add_argument( + '--asn_alts', + type=str, + nargs=1, + default='whois,http', + metavar='"ASN_ALTS"', + help='A comma delimited list of additional lookup types to attempt if the ' + 'ASN dns lookup fails. Allow permutations must be enabled. ' + 'Defaults to all: "whois,http" *WARNING* deprecated in ' + 'favor of new argument asn_methods.' +) +group.add_argument( + '--asn_methods', + type=str, + nargs=1, + default='dns,whois,http', + metavar='"ASN_METHODS"', + help='List of ASN lookup types to attempt, in order. ' + 'Defaults to all [\'dns\', \'whois\', \'http\'].' +) +group.add_argument( + '--extra_org_map', + type=json.loads, + nargs=1, + default='{"DNIC": "arin"}', + metavar='"EXTRA_ORG_MAP"', + help='Dictionary mapping org handles to RIRs. This is for limited cases ' + 'where ARIN REST (ASN fallback HTTP lookup) does not show an RIR as ' + 'the org handle e.g., DNIC (which is now the built in ORG_MAP) e.g., ' + '{\\"DNIC\\": \\"arin\\"}. Valid RIR values are (note the ' + 'case-sensitive - this is meant to match the REST result): ' + '\'ARIN\', \'RIPE\', \'apnic\', \'lacnic\', \'afrinic\'' +) +group.add_argument( + '--skip_asn_description', + action='store_true', + help='Don\'t run an additional query when pulling ASN information via dns ' + '(to get the ASN description). This is the opposite of the ipwhois ' + 'get_asn_description argument, in order to enable ' + 'get_asn_description by default in the CLI.', + default=False +) + +# RDAP +group = parser.add_argument_group('RDAP settings') +group.add_argument( + '--depth', + type=int, + default=0, + metavar='COLOR_DEPTH', + help='If not --whois, how many levels deep to run RDAP queries when ' + 'additional referenced objects are found.' +) +group.add_argument( + '--excluded_entities', + type=str, + nargs=1, + default=None, + metavar='"EXCLUDED_ENTITIES"', + help='If not --whois, a comma delimited list of entity handles to not ' + 'perform lookups.' +) +group.add_argument( + '--bootstrap', + action='store_true', + help='If not --whois, performs lookups via ARIN bootstrap rather than ' + 'lookups based on ASN data. ASN lookups are not performed and no ' + 'output for any of the asn* fields is provided.' +) +group.add_argument( + '--rate_limit_timeout', + type=int, + default=120, + metavar='RATE_LIMIT_TIMEOUT', + help='If not --whois, the number of seconds to wait before retrying when ' + 'a rate limit notice is returned via rdap+json.' +) + +# Legacy Whois +group = parser.add_argument_group('Legacy Whois settings') +group.add_argument( + '--get_referral', + action='store_true', + help='If --whois, retrieve referral whois information, if available.' +) +group.add_argument( + '--extra_blacklist', + type=str, + nargs=1, + default='', + metavar='"EXTRA_BLACKLIST"', + help='If --whois, A list of blacklisted whois servers in addition to the ' + 'global BLACKLIST.' +) +group.add_argument( + '--ignore_referral_errors', + action='store_true', + help='If --whois, ignore and continue when an exception is encountered on ' + 'referral whois lookups.' +) +group.add_argument( + '--field_list', + type=str, + nargs=1, + default='', + metavar='"FIELD_LIST"', + help='If --whois, a list of fields to parse: ' + '[\'name\', \'handle\', \'description\', \'country\', \'state\', ' + '\'city\', \'address\', \'postal_code\', \'emails\', \'created\', ' + '\'updated\']' +) + +# NIR (National Internet Registry -- JPNIC, KRNIC) +group = parser.add_argument_group('NIR (National Internet Registry) settings') +group.add_argument( + '--nir_field_list', + type=str, + nargs=1, + default='', + metavar='"NIR_FIELD_LIST"', + help='If not --exclude_nir, a list of fields to parse: ' + '[\'name\', \'handle\', \'country\', \'address\', \'postal_code\', ' + '\'nameservers\', \'created\', \'updated\', \'contact_admin\', ' + '\'contact_tech\']' +) + +# Input (required) +group = parser.add_argument_group('Input (Required)') +group.add_argument( + '--addr', + type=str, + nargs=1, + metavar='"IP"', + help='An IPv4 or IPv6 address as a string.', + required=True +) + +# Get the args +script_args = parser.parse_args() + +# Get the current working directory. +CUR_DIR = path.dirname(__file__) + + +def generate_output(line='0', short=None, name=None, value=None, + is_parent=False, colorize=True): + """ + The function for formatting CLI output results. + + Args: + line (:obj:`str`): The line number (0-4). Determines indentation. + Defaults to '0'. + short (:obj:`str`): The optional abbreviated name for a field. + See hr.py for values. + name (:obj:`str`): The optional name for a field. See hr.py for values. + value (:obj:`str`): The field data (required). + is_parent (:obj:`bool`): Set to True if the field value has sub-items + (dicts/lists). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI colors. + Defaults to True. + + Returns: + str: The generated output. + """ + + # TODO: so ugly + output = '{0}{1}{2}{3}{4}{5}{6}{7}\n'.format( + LINES['{0}{1}'.format(line, 'C' if colorize else '')] if ( + line in LINES.keys()) else '', + COLOR_DEPTH[line] if (colorize and line in COLOR_DEPTH) else '', + ANSI['b'], + short if short is not None else ( + name if (name is not None) else '' + ), + '' if (name is None or short is None) else ' ({0})'.format( + name), + '' if (name is None and short is None) else ': ', + ANSI['end'] if colorize else '', + '' if is_parent else value + ) + + return output + + +class IPWhoisCLI: + """ + The CLI wrapper class for outputting formatted IPWhois results. + + Args: + addr (:obj:`str`/:obj:`int`/:obj:`IPv4Address`/:obj:`IPv6Address`): + An IPv4 or IPv6 address + timeout (:obj:`int`): The default timeout for socket connections in + seconds. Defaults to 5. + proxy_http (:obj:`urllib.request.OpenerDirector`): The request for + proxy HTTP support or None. + proxy_https (:obj:`urllib.request.OpenerDirector`): The request for + proxy HTTPS support or None. + allow_permutations (:obj:`bool`): Allow net.Net() to use additional + methods if DNS lookups to Cymru fail. *WARNING* deprecated in + favor of new argument asn_methods. Defaults to True. + """ + + def __init__( + self, + addr, + timeout, + proxy_http, + proxy_https, + allow_permutations + ): + + self.addr = addr + self.timeout = timeout + + handler_dict = None + if proxy_http is not None: + + handler_dict = {'http': proxy_http} + + if proxy_https is not None: + + if handler_dict is None: + + handler_dict = {'https': proxy_https} + + else: + + handler_dict['https'] = proxy_https + + if handler_dict is None: + + self.opener = None + else: + + handler = ProxyHandler(handler_dict) + self.opener = build_opener(handler) + + self.allow_permutations = allow_permutations + + self.obj = IPWhois(address=self.addr, + timeout=self.timeout, + proxy_opener=self.opener, + allow_permutations=self.allow_permutations) + + def generate_output_header(self, query_type='RDAP'): + """ + The function for generating the CLI output header. + + Args: + query_type (:obj:`str`): The IPWhois query type. Defaults to + 'RDAP'. + + Returns: + str: The generated output. + """ + + output = '\n{0}{1}{2} query for {3}:{4}\n\n'.format( + ANSI['ul'], + ANSI['b'], + query_type, + self.obj.address_str, + ANSI['end'] + ) + + return output + + def generate_output_newline(self, line='0', colorize=True): + """ + The function for generating a CLI output new line. + + Args: + line (:obj:`str`): The line number (0-4). Determines indentation. + Defaults to '0'. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + return generate_output( + line=line, + is_parent=True, + colorize=colorize + ) + + def generate_output_asn(self, json_data=None, hr=True, show_name=False, + colorize=True): + """ + The function for generating CLI output ASN results. + + Args: + json_data (:obj:`dict`): The data to process. Defaults to None. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + if json_data is None: + json_data = {} + + # Python 2.6 doesn't support set literal expressions, use explicit + # set() instead. + keys = set(['asn', 'asn_cidr', 'asn_country_code', 'asn_date', + 'asn_registry', 'asn_description']).intersection(json_data) + + output = '' + + for key in keys: + + output += generate_output( + line='0', + short=HR_ASN[key]['_short'] if hr else key, + name=HR_ASN[key]['_name'] if (hr and show_name) else None, + value=(json_data[key] if ( + json_data[key] is not None and + len(json_data[key]) > 0 and + json_data[key] != 'NA') else 'None'), + colorize=colorize + ) + + return output + + def generate_output_entities(self, json_data=None, hr=True, + show_name=False, colorize=True): + """ + The function for generating CLI output RDAP entity results. + + Args: + json_data (:obj:`dict`): The data to process. Defaults to None. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + output = '' + short = HR_RDAP['entities']['_short'] if hr else 'entities' + name = HR_RDAP['entities']['_name'] if (hr and show_name) else None + + output += generate_output( + line='0', + short=short, + name=name, + is_parent=False if (json_data is None or + json_data['entities'] is None) else True, + value='None' if (json_data is None or + json_data['entities'] is None) else None, + colorize=colorize + ) + + if json_data is not None: + + for ent in json_data['entities']: + + output += generate_output( + line='1', + value=ent, + colorize=colorize + ) + + return output + + def generate_output_events(self, source, key, val, line='2', hr=True, + show_name=False, colorize=True): + """ + The function for generating CLI output RDAP events results. + + Args: + source (:obj:`str`): The parent key 'network' or 'objects' + (required). + key (:obj:`str`): The event key 'events' or 'events_actor' + (required). + val (:obj:`dict`): The event dictionary (required). + line (:obj:`str`): The line number (0-4). Determines indentation. + Defaults to '0'. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + output = generate_output( + line=line, + short=HR_RDAP[source][key]['_short'] if hr else key, + name=HR_RDAP[source][key]['_name'] if (hr and show_name) else None, + is_parent=False if (val is None or + len(val) == 0) else True, + value='None' if (val is None or + len(val) == 0) else None, + colorize=colorize + ) + + if val is not None: + + count = 0 + for item in val: + + try: + action = item['action'] + except KeyError: + action = None + + try: + timestamp = item['timestamp'] + except KeyError: + timestamp = None + + try: + actor = item['actor'] + except KeyError: + actor = None + + if count > 0: + output += generate_output( + line=str(int(line)+1), + is_parent=True, + colorize=colorize + ) + + output += generate_output( + line=str(int(line)+1), + short=HR_RDAP_COMMON[key]['action'][ + '_short'] if hr else 'action', + name=HR_RDAP_COMMON[key]['action'][ + '_name'] if (hr and show_name) else None, + value=action, + colorize=colorize + ) + + output += generate_output( + line=str(int(line)+1), + short=HR_RDAP_COMMON[key]['timestamp'][ + '_short'] if hr else 'timestamp', + name=HR_RDAP_COMMON[key]['timestamp'][ + '_name'] if (hr and show_name) else None, + value=timestamp, + colorize=colorize + ) + + output += generate_output( + line=str(int(line)+1), + short=HR_RDAP_COMMON[key]['actor'][ + '_short'] if hr else 'actor', + name=HR_RDAP_COMMON[key]['actor'][ + '_name'] if (hr and show_name) else None, + value=actor, + colorize=colorize + ) + + count += 1 + + return output + + def generate_output_list(self, source, key, val, line='2', hr=True, + show_name=False, colorize=True): + """ + The function for generating CLI output RDAP list results. + + Args: + source (:obj:`str`): The parent key 'network' or 'objects' + (required). + key (:obj:`str`): The event key 'events' or 'events_actor' + (required). + val (:obj:`dict`): The event dictionary (required). + line (:obj:`str`): The line number (0-4). Determines indentation. + Defaults to '0'. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + output = generate_output( + line=line, + short=HR_RDAP[source][key]['_short'] if hr else key, + name=HR_RDAP[source][key]['_name'] if (hr and show_name) else None, + is_parent=False if (val is None or + len(val) == 0) else True, + value='None' if (val is None or + len(val) == 0) else None, + colorize=colorize + ) + + if val is not None: + for item in val: + output += generate_output( + line=str(int(line)+1), + value=item, + colorize=colorize + ) + + return output + + def generate_output_notices(self, source, key, val, line='1', hr=True, + show_name=False, colorize=True): + """ + The function for generating CLI output RDAP notices results. + + Args: + source (:obj:`str`): The parent key 'network' or 'objects' + (required). + key (:obj:`str`): The event key 'events' or 'events_actor' + (required). + val (:obj:`dict`): The event dictionary (required). + line (:obj:`str`): The line number (0-4). Determines indentation. + Defaults to '0'. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + output = generate_output( + line=line, + short=HR_RDAP[source][key]['_short'] if hr else key, + name=HR_RDAP[source][key]['_name'] if (hr and show_name) else None, + is_parent=False if (val is None or + len(val) == 0) else True, + value='None' if (val is None or + len(val) == 0) else None, + colorize=colorize + ) + + if val is not None: + + count = 0 + for item in val: + + title = item['title'] + description = item['description'] + links = item['links'] + + if count > 0: + output += generate_output( + line=str(int(line)+1), + is_parent=True, + colorize=colorize + ) + + output += generate_output( + line=str(int(line)+1), + short=HR_RDAP_COMMON[key]['title']['_short'] if hr else ( + 'title'), + name=HR_RDAP_COMMON[key]['title']['_name'] if ( + hr and show_name) else None, + value=title, + colorize=colorize + ) + + output += generate_output( + line=str(int(line)+1), + short=HR_RDAP_COMMON[key]['description'][ + '_short'] if hr else 'description', + name=HR_RDAP_COMMON[key]['description'][ + '_name'] if (hr and show_name) else None, + value=description.replace( + '\n', + '\n{0}'.format(generate_output(line='3')) + ), + colorize=colorize + ) + output += self.generate_output_list( + source=source, + key='links', + val=links, + line=str(int(line)+1), + hr=hr, + show_name=show_name, + colorize=colorize + ) + + count += 1 + + return output + + def generate_output_network(self, json_data=None, hr=True, show_name=False, + colorize=True): + """ + The function for generating CLI output RDAP network results. + + Args: + json_data (:obj:`dict`): The data to process. Defaults to None. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + if json_data is None: + json_data = {} + + output = generate_output( + line='0', + short=HR_RDAP['network']['_short'] if hr else 'network', + name=HR_RDAP['network']['_name'] if (hr and show_name) else None, + is_parent=True, + colorize=colorize + ) + + for key, val in json_data['network'].items(): + + if key in ['links', 'status']: + + output += self.generate_output_list( + source='network', + key=key, + val=val, + line='1', + hr=hr, + show_name=show_name, + colorize=colorize + ) + + elif key in ['notices', 'remarks']: + + output += self.generate_output_notices( + source='network', + key=key, + val=val, + line='1', + hr=hr, + show_name=show_name, + colorize=colorize + ) + + elif key == 'events': + + output += self.generate_output_events( + source='network', + key=key, + val=val, + line='1', + hr=hr, + show_name=show_name, + colorize=colorize + ) + + elif key not in ['raw']: + + output += generate_output( + line='1', + short=HR_RDAP['network'][key]['_short'] if hr else key, + name=HR_RDAP['network'][key]['_name'] if ( + hr and show_name) else None, + value=val, + colorize=colorize + ) + + return output + + def generate_output_objects(self, json_data=None, hr=True, show_name=False, + colorize=True): + """ + The function for generating CLI output RDAP object results. + + Args: + json_data (:obj:`dict`): The data to process. Defaults to None. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + if json_data is None: + json_data = {} + + output = generate_output( + line='0', + short=HR_RDAP['objects']['_short'] if hr else 'objects', + name=HR_RDAP['objects']['_name'] if (hr and show_name) else None, + is_parent=True, + colorize=colorize + ) + + count = 0 + for obj_name, obj in json_data['objects'].items(): + if count > 0: + output += self.generate_output_newline( + line='1', + colorize=colorize + ) + count += 1 + + output += generate_output( + line='1', + short=obj_name, + is_parent=True, + colorize=colorize + ) + + for key, val in obj.items(): + + if key in ['links', 'entities', 'roles', 'status']: + + output += self.generate_output_list( + source='objects', + key=key, + val=val, + line='2', + hr=hr, + show_name=show_name, + colorize=colorize + ) + + elif key in ['notices', 'remarks']: + + output += self.generate_output_notices( + source='objects', + key=key, + val=val, + line='2', + hr=hr, + show_name=show_name, + colorize=colorize + ) + + elif key == 'events': + + output += self.generate_output_events( + source='objects', + key=key, + val=val, + line='2', + hr=hr, + show_name=show_name, + colorize=colorize + ) + + elif key == 'contact': + + output += generate_output( + line='2', + short=HR_RDAP['objects']['contact'][ + '_short'] if hr else 'contact', + name=HR_RDAP['objects']['contact']['_name'] if ( + hr and show_name) else None, + is_parent=False if (val is None or + len(val) == 0) else True, + value='None' if (val is None or + len(val) == 0) else None, + colorize=colorize + ) + + if val is not None: + + for k, v in val.items(): + + if k in ['phone', 'address', 'email']: + + output += generate_output( + line='3', + short=HR_RDAP['objects']['contact'][k][ + '_short'] if hr else k, + name=HR_RDAP['objects']['contact'][k][ + '_name'] if ( + hr and show_name) else None, + is_parent=False if ( + val is None or + len(val) == 0 + ) else True, + value='None' if (val is None or + len(val) == 0) else None, + colorize=colorize + ) + + if v is not None: + for item in v: + i_type = ', '.join(item['type']) if ( + isinstance(item['type'], list) + ) else item['type'] + + i_type = i_type if ( + i_type is not None and + len(i_type) > 0) else '' + + i_value = item['value'].replace( + '\n', + '\n{0}'.format( + generate_output( + line='4', + is_parent=True, + colorize=colorize + ).replace('\n', '')) + ) + + tmp_out = '{0}{1}{2}'.format( + i_type, + ': ' if i_type != '' else '', + i_value + ) + + output += generate_output( + line='4', + value=tmp_out, + colorize=colorize + ) + + else: + + output += generate_output( + line='3', + short=HR_RDAP['objects']['contact'][k][ + '_short'] if hr else k, + name=HR_RDAP['objects']['contact'][k][ + '_name'] if ( + hr and show_name) else None, + value=v, + colorize=colorize + ) + + elif key not in ['raw']: + + output += generate_output( + line='2', + short=HR_RDAP['objects'][key]['_short'] if hr else key, + name=HR_RDAP['objects'][key]['_name'] if ( + hr and show_name) else None, + value=val, + colorize=colorize + ) + + return output + + def lookup_rdap(self, hr=True, show_name=False, colorize=True, **kwargs): + """ + The function for wrapping IPWhois.lookup_rdap() and generating + formatted CLI output. + + Args: + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + kwargs: Arguments to pass to IPWhois.lookup_rdap(). + + Returns: + str: The generated output. + """ + + # Perform the RDAP lookup + ret = self.obj.lookup_rdap(**kwargs) + + if script_args.json: + + output = json.dumps(ret) + + else: + + # Header + output = self.generate_output_header(query_type='RDAP') + + # ASN + output += self.generate_output_asn( + json_data=ret, hr=hr, show_name=show_name, colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + # Entities + output += self.generate_output_entities( + json_data=ret, hr=hr, show_name=show_name, colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + # Network + output += self.generate_output_network( + json_data=ret, hr=hr, show_name=show_name, colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + # Objects + output += self.generate_output_objects( + json_data=ret, hr=hr, show_name=show_name, colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + if 'nir' in ret: + + # NIR + output += self.generate_output_nir( + json_data=ret, hr=hr, show_name=show_name, + colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + return output + + def generate_output_whois_nets(self, json_data=None, hr=True, + show_name=False, colorize=True): + """ + The function for generating CLI output Legacy Whois networks results. + + Args: + json_data (:obj:`dict`): The data to process. Defaults to None. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + if json_data is None: + json_data = {} + + output = generate_output( + line='0', + short=HR_WHOIS['nets']['_short'] if hr else 'nets', + name=HR_WHOIS['nets']['_name'] if (hr and show_name) else None, + is_parent=True, + colorize=colorize + ) + + count = 0 + for net in json_data['nets']: + if count > 0: + output += self.generate_output_newline( + line='1', + colorize=colorize + ) + count += 1 + + output += generate_output( + line='1', + short=net['handle'], + is_parent=True, + colorize=colorize + ) + + for key, val in net.items(): + + if val and '\n' in val: + + output += generate_output( + line='2', + short=HR_WHOIS['nets'][key]['_short'] if hr else key, + name=HR_WHOIS['nets'][key]['_name'] if ( + hr and show_name) else None, + is_parent=False if (val is None or + len(val) == 0) else True, + value='None' if (val is None or + len(val) == 0) else None, + colorize=colorize + ) + + for v in val.split('\n'): + output += generate_output( + line='3', + value=v, + colorize=colorize + ) + + else: + + output += generate_output( + line='2', + short=HR_WHOIS['nets'][key]['_short'] if hr else key, + name=HR_WHOIS['nets'][key]['_name'] if ( + hr and show_name) else None, + value=val, + colorize=colorize + ) + + return output + + def generate_output_whois_referral(self, json_data=None, hr=True, + show_name=False, colorize=True): + """ + The function for generating CLI output Legacy Whois referral results. + + Args: + json_data (:obj:`dict`): The data to process. Defaults to None. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + if json_data is None: + json_data = {} + + output = generate_output( + line='0', + short=HR_WHOIS['referral']['_short'] if hr else 'referral', + name=HR_WHOIS['referral']['_name'] if (hr and show_name) else None, + is_parent=False if json_data['referral'] is None else True, + value='None' if json_data['referral'] is None else None, + colorize=colorize + ) + + if json_data['referral']: + + for key, val in json_data['referral'].items(): + + if val and '\n' in val: + + output += generate_output( + line='1', + short=HR_WHOIS['nets'][key]['_short'] if hr else key, + name=HR_WHOIS['nets'][key]['_name'] if ( + hr and show_name) else None, + is_parent=False if (val is None or + len(val) == 0) else True, + value='None' if (val is None or + len(val) == 0) else None, + colorize=colorize + ) + + for v in val.split('\n'): + output += generate_output( + line='2', + value=v, + colorize=colorize + ) + + else: + + output += generate_output( + line='1', + short=HR_WHOIS['nets'][key]['_short'] if hr else key, + name=HR_WHOIS['nets'][key]['_name'] if ( + hr and show_name) else None, + value=val, + colorize=colorize + ) + + return output + + def generate_output_nir(self, json_data=None, hr=True, show_name=False, + colorize=True): + """ + The function for generating CLI output NIR network results. + + Args: + json_data (:obj:`dict`): The data to process. Defaults to None. + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + + Returns: + str: The generated output. + """ + + if json_data is None: + json_data = {} + + output = generate_output( + line='0', + short=HR_WHOIS_NIR['nets']['_short'] if hr else 'nir_nets', + name=HR_WHOIS_NIR['nets']['_name'] if (hr and show_name) else None, + is_parent=True, + colorize=colorize + ) + + count = 0 + if json_data['nir']: + + for net in json_data['nir']['nets']: + + if count > 0: + + output += self.generate_output_newline( + line='1', + colorize=colorize + ) + + count += 1 + + output += generate_output( + line='1', + short=net['handle'], + is_parent=True, + colorize=colorize + ) + + for key, val in net.items(): + + if val and (isinstance(val, dict) or '\n' in val or + key == 'nameservers'): + + output += generate_output( + line='2', + short=( + HR_WHOIS_NIR['nets'][key]['_short'] if ( + hr) else key + ), + name=HR_WHOIS_NIR['nets'][key]['_name'] if ( + hr and show_name) else None, + is_parent=False if (val is None or + len(val) == 0) else True, + value='None' if (val is None or + len(val) == 0) else None, + colorize=colorize + ) + + if key == 'contacts': + + for k, v in val.items(): + + if v: + + output += generate_output( + line='3', + is_parent=False if ( + len(v) == 0) else True, + name=k, + colorize=colorize + ) + + for contact_key, contact_val in v.items(): + + if v is not None: + + tmp_out = '{0}{1}{2}'.format( + contact_key, + ': ', + contact_val + ) + + output += generate_output( + line='4', + value=tmp_out, + colorize=colorize + ) + elif key == 'nameservers': + + for v in val: + output += generate_output( + line='3', + value=v, + colorize=colorize + ) + else: + + for v in val.split('\n'): + output += generate_output( + line='3', + value=v, + colorize=colorize + ) + + else: + + output += generate_output( + line='2', + short=( + HR_WHOIS_NIR['nets'][key]['_short'] if ( + hr) else key + ), + name=HR_WHOIS_NIR['nets'][key]['_name'] if ( + hr and show_name) else None, + value=val, + colorize=colorize + ) + + else: + + output += 'None' + + return output + + def lookup_whois(self, hr=True, show_name=False, colorize=True, **kwargs): + """ + The function for wrapping IPWhois.lookup_whois() and generating + formatted CLI output. + + Args: + hr (:obj:`bool`): Enable human readable key translations. Defaults + to True. + show_name (:obj:`bool`): Show human readable name (default is to + only show short). Defaults to False. + colorize (:obj:`bool`): Colorize the console output with ANSI + colors. Defaults to True. + kwargs: Arguments to pass to IPWhois.lookup_whois(). + + Returns: + str: The generated output. + """ + + # Perform the RDAP lookup + ret = self.obj.lookup_whois(**kwargs) + + if script_args.json: + + output = json.dumps(ret) + + else: + + # Header + output = self.generate_output_header(query_type='Legacy Whois') + + # ASN + output += self.generate_output_asn( + json_data=ret, hr=hr, show_name=show_name, colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + # Network + output += self.generate_output_whois_nets( + json_data=ret, hr=hr, show_name=show_name, colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + # Referral + output += self.generate_output_whois_referral( + json_data=ret, hr=hr, show_name=show_name, colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + if 'nir' in ret: + + # NIR + output += self.generate_output_nir( + json_data=ret, hr=hr, show_name=show_name, + colorize=colorize + ) + output += self.generate_output_newline(colorize=colorize) + + return output + +if script_args.addr: + + results = IPWhoisCLI( + addr=script_args.addr[0], + timeout=script_args.timeout, + proxy_http=script_args.proxy_http if ( + script_args.proxy_http and len(script_args.proxy_http) > 0 + ) else None, + proxy_https=script_args.proxy_https if ( + script_args.proxy_https and len(script_args.proxy_https) > 0 + ) else None, + allow_permutations=(not script_args.disallow_permutations) + ) + + if script_args.whois: + + print(results.lookup_whois( + hr=script_args.hr, + show_name=script_args.show_name, + colorize=script_args.colorize, + inc_raw=script_args.inc_raw, + retry_count=script_args.retry_count, + get_referral=script_args.get_referral, + extra_blacklist=script_args.extra_blacklist.split(',') if ( + script_args.extra_blacklist and + len(script_args.extra_blacklist) > 0) else None, + ignore_referral_errors=script_args.ignore_referral_errors, + field_list=script_args.field_list.split(',') if ( + script_args.field_list and + len(script_args.field_list) > 0) else None, + asn_alts=script_args.asn_alts.split(',') if ( + script_args.asn_alts and not script_args.asn_methods and + len(script_args.asn_alts) > 0) else None, + extra_org_map=script_args.extra_org_map, + inc_nir=(not script_args.exclude_nir), + nir_field_list=script_args.nir_field_list.split(',') if ( + script_args.nir_field_list and + len(script_args.nir_field_list) > 0) else None, + asn_methods=script_args.asn_methods.split(',') if ( + script_args.asn_methods and + len(script_args.asn_methods) > 0) else None, + get_asn_description=(not script_args.skip_asn_description) + )) + + else: + + print(results.lookup_rdap( + hr=script_args.hr, + show_name=script_args.show_name, + colorize=script_args.colorize, + inc_raw=script_args.inc_raw, + retry_count=script_args.retry_count, + depth=script_args.depth, + excluded_entities=script_args.excluded_entities.split(',') if ( + script_args.excluded_entities and + len(script_args.excluded_entities) > 0) else None, + bootstrap=script_args.bootstrap, + rate_limit_timeout=script_args.rate_limit_timeout, + asn_alts=script_args.asn_alts.split(',') if ( + script_args.asn_alts and not script_args.asn_methods and + len(script_args.asn_alts) > 0) else None, + extra_org_map=script_args.extra_org_map, + inc_nir=(not script_args.exclude_nir), + nir_field_list=script_args.nir_field_list.split(',') if ( + script_args.nir_field_list and + len(script_args.nir_field_list) > 0) else None, + asn_methods=script_args.asn_methods.split(',') if ( + script_args.asn_methods and + len(script_args.asn_methods) > 0) else None, + get_asn_description=(not script_args.skip_asn_description) + )) diff --git a/env/bin/ipwhois_utils_cli.py b/env/bin/ipwhois_utils_cli.py new file mode 100644 index 0000000..3f77adb --- /dev/null +++ b/env/bin/ipwhois_utils_cli.py @@ -0,0 +1,269 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# CLI python script interface for ipwhois.utils lookups. + +import argparse +from collections import OrderedDict +import json +from ipwhois.utils import (ipv4_lstrip_zeros, calculate_cidr, get_countries, + ipv4_is_defined, ipv6_is_defined, unique_everseen, + unique_addresses) + +# CLI ANSI rendering +ANSI = { + 'end': '\033[0m', + 'b': '\033[1m', + 'ul': '\033[4m', + 'red': '\033[31m', + 'green': '\033[32m', + 'yellow': '\033[33m', + 'cyan': '\033[36m' +} + +# Setup the arg parser. +parser = argparse.ArgumentParser( + description='ipwhois utilities CLI interface' +) +parser.add_argument( + '--ipv4_lstrip_zeros', + type=str, + nargs=1, + metavar='"IP ADDRESS"', + help='Strip leading zeros in each octet of an IPv4 address.' +) +parser.add_argument( + '--calculate_cidr', + type=str, + nargs=2, + metavar='"IP ADDRESS"', + help='Calculate a CIDR range(s) from a start and end IP address.' +) +parser.add_argument( + '--get_countries', + action='store_true', + help='Output a dictionary containing ISO_3166-1 country codes to names.' +) +parser.add_argument( + '--get_country', + type=str, + nargs=1, + metavar='"COUNTRY CODE"', + help='Output the ISO_3166-1 name for a country code.' +) +parser.add_argument( + '--ipv4_is_defined', + type=str, + nargs=1, + metavar='"IP ADDRESS"', + help='Check if an IPv4 address is defined (in a reserved address range).' +) +parser.add_argument( + '--ipv6_is_defined', + type=str, + nargs=1, + metavar='"IP ADDRESS"', + help='Check if an IPv6 address is defined (in a reserved address range).' +) +parser.add_argument( + '--unique_everseen', + type=json.loads, + nargs=1, + metavar='"ITERABLE"', + help='List unique elements from input iterable, preserving the order.' +) +parser.add_argument( + '--unique_addresses', + type=str, + nargs=1, + metavar='"FILE PATH"', + help='Search an input file, extracting, counting, and summarizing ' + 'IPv4/IPv6 addresses/networks.' +) + +# Output options +group = parser.add_argument_group('Output options') +group.add_argument( + '--colorize', + action='store_true', + help='If set, colorizes the output using ANSI. Should work in most ' + 'platform consoles.' +) + +# Get the args +script_args = parser.parse_args() + +if script_args.ipv4_lstrip_zeros: + + print(ipv4_lstrip_zeros(address=script_args.ipv4_lstrip_zeros[0])) + +elif script_args.calculate_cidr: + + try: + + result = calculate_cidr( + start_address=script_args.calculate_cidr[0], + end_address=script_args.calculate_cidr[1] + ) + + print('{0}Found {1} CIDR blocks for ({2}, {3}){4}:\n{5}'.format( + ANSI['green'] if script_args.colorize else '', + len(result), + script_args.calculate_cidr[0], + script_args.calculate_cidr[1], + ANSI['end'] if script_args.colorize else '', + '\n'.join(result) + )) + + except Exception as e: + + print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e))) + +elif script_args.get_countries: + + try: + + result = get_countries() + + print('{0}Found {1} countries{2}:\n{3}'.format( + ANSI['green'] if script_args.colorize else '', + len(result), + ANSI['end'] if script_args.colorize else '', + '\n'.join(['{0}: {1}'.format(k, v) for k, v in ( + OrderedDict(sorted(result.items())).iteritems())]) + )) + + except Exception as e: + + print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e))) + +elif script_args.get_country: + + try: + + countries = get_countries() + result = countries[script_args.get_country[0].upper()] + + print('{0}Match found for country code ({1}){2}:\n{3}'.format( + ANSI['green'] if script_args.colorize else '', + script_args.get_country[0], + ANSI['end'] if script_args.colorize else '', + result + )) + + except Exception as e: + + print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e))) + +elif script_args.ipv4_is_defined: + + try: + + result = ipv4_is_defined(address=script_args.ipv4_is_defined[0]) + + if result[0]: + print('{0}{1} is defined{2}:\n{3}'.format( + ANSI['green'] if script_args.colorize else '', + script_args.ipv4_is_defined[0], + ANSI['end'] if script_args.colorize else '', + 'Name: {0}\nRFC: {1}'.format(result[1], result[2]) + )) + else: + print('{0}{1} is not defined{2}'.format( + ANSI['yellow'] if script_args.colorize else '', + script_args.ipv4_is_defined[0], + ANSI['end'] if script_args.colorize else '' + )) + + except Exception as e: + + print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e))) + +elif script_args.ipv6_is_defined: + + try: + + result = ipv6_is_defined(address=script_args.ipv6_is_defined[0]) + + if result[0]: + print('{0}{1} is defined{2}:\n{3}'.format( + ANSI['green'] if script_args.colorize else '', + script_args.ipv6_is_defined[0], + ANSI['end'] if script_args.colorize else '', + 'Name: {0}\nRFC: {1}'.format(result[1], result[2]) + )) + else: + print('{0}{1} is not defined{2}'.format( + ANSI['yellow'] if script_args.colorize else '', + script_args.ipv6_is_defined[0], + ANSI['end'] if script_args.colorize else '' + )) + + except Exception as e: + + print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e))) + +elif script_args.unique_everseen: + + try: + + result = list(unique_everseen(iterable=script_args.unique_everseen[0])) + + print('{0}Unique everseen{1}:\n{2}'.format( + ANSI['green'] if script_args.colorize else '', + ANSI['end'] if script_args.colorize else '', + result + )) + + except Exception as e: + + print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e))) + +elif script_args.unique_addresses: + + try: + + result = unique_addresses(file_path=script_args.unique_addresses[0]) + + tmp = [] + for k, v in sorted(result.items(), key=lambda kv: int(kv[1]['count']), + reverse=True): + tmp.append('{0}{1}{2}: Count: {3}, Ports: {4}'.format( + ANSI['b'] if script_args.colorize else '', + k, + ANSI['end'] if script_args.colorize else '', + v['count'], + json.dumps(v['ports']) + )) + + print('{0}Found {1} unique addresses{2}:\n{3}'.format( + ANSI['green'] if script_args.colorize else '', + len(result), + ANSI['end'] if script_args.colorize else '', + '\n'.join(tmp) + )) + + except Exception as e: + + print('{0}Error{1}: {2}'.format(ANSI['red'], ANSI['end'], str(e))) diff --git a/env/bin/pip b/env/bin/pip new file mode 100755 index 0000000..5d67e84 --- /dev/null +++ b/env/bin/pip @@ -0,0 +1,11 @@ +#!/home/ben/Documents/Projects/Python/PyGeoIP/env/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/env/bin/pip3 b/env/bin/pip3 new file mode 100755 index 0000000..5d67e84 --- /dev/null +++ b/env/bin/pip3 @@ -0,0 +1,11 @@ +#!/home/ben/Documents/Projects/Python/PyGeoIP/env/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/env/bin/pip3.7 b/env/bin/pip3.7 new file mode 100755 index 0000000..5d67e84 --- /dev/null +++ b/env/bin/pip3.7 @@ -0,0 +1,11 @@ +#!/home/ben/Documents/Projects/Python/PyGeoIP/env/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from pip._internal import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/env/bin/python b/env/bin/python new file mode 100755 index 0000000000000000000000000000000000000000..fc81572291faf777989df155f60c047287ab99b1 GIT binary patch literal 14096 zcmeHOYiu0V6~5~SahiB-LQD;b@Iaw*P&`@Zg`qOpwc}*0Iw3%uB0(}*d&l+`dlz($kU^I)?~CxtjKCL5O@(Xqs@DYcZaR_bAh zi%>_%<6GBv;?w7Te)4c<*Iz%mdvWJ`f4ldNm9L(B>i!ddIeDOV`9}w8Z~D!WyC3-7 z{oyvE^`DZ$h$=}g(Xng+{Uf9^7SKOUx`q5ZF5o{v`fCD(Q6#WmtP!8L2`}ZS z7=Z%w=0y_g>2A~~13k{Kh+akX|Mv9_=lTCb^oXMepwg zq7W6e>80mWOM1^>|UbSY_f}Py5QO) z>1>WPgCqHzXl!Ng7_)nG+0ku*&G+svmbitivYkxYO%sJ7pwJ+0p;{)Jvr9!MgASNN z43{W5R`wN(;=i@0yQ9-yYpyjn1YxLhp}zCW>`>Yt}VdW@9~(;+?Y2PiWkJ?1LgPKWfEGpzqA zq@SA`Y|uqVKu17FKu17FKu17F;Cmi{|JGe~)*An$#(J#!82#;TJ#^Tu@QzyJZ`Mru zBloU*gVY0NUDJcU%>J#Pc9)OsvC1D=;~$^iv9o8QdKdlaWlhxnom{Mm_IErg4SR|A z`I96*%k557|AFDguiOUeY8Th3tHs`QUDG~pcv6u3$9(?{1%_3#){)stt9;rzGPB8w zy=5Jnb(d2E8>E36Z+f7vY4bdv$G5MY&8oDn*BWnM##O6)%B{5?YrmWXuR+myrk}?6 zR`pV<#&%E6U*F`we7&wIskps=4wA2okLA=ay36mUc6FD}q-N(Fa<4Vf z!gzbns#6@(!I=ZIo@X8Tw$i<-^+Yhvp7PnA@|n%$&r;s<53KRYn04carGIg}@7$fb zE44edCuN7n!2R)^VD#_P+?^q%E;<4_0y+XZ0y+XZ0y+XZ0y+XZ0y+XZ0y+ZUF#<7q zClgyy`Lky7=l32fPkSD}w^>a{kJW1Re>~46e1?$UmGOI2F0sA0sn}?JY{k+=HBZvh zKkHZ0G5wk6@e{Y&yvToZ!}|4f93p-AJqfqnL&x*fkN=KtOT7MximrI$V?uZ*5@y3pLeMh{;f4}r=YG;bt3BR8ql`c90 zIs!TZIs!TZIs!TZIs!TZIs!TZKZpn*pAPwR$c?*Pt{yT!>v4e$dvRqi(G%acSw8mM%b4TFM9m+<@I9!T4WhMn!RX< zeDI6aAo3} zQytwcZhBCp!CcAgD`hEBJDX7^OGD}6kTNr4x#HMJfNmkM+~*XE*?jIC!6sY58BQ~S zJECk<({)Da>?gCDg}k55YC1#qKp{Qi*h3j&KnfUkx==`u1q{@wx%5c3pZdyETR|I? z->S_1{K$xtb1zaLd0z6IK+frfzH2~tm_Lw_hYo%;kKcf!Apg%MT&^a8=RWu!O9gms z*qQ24KL4-g49#8eYh(fg_X{8E73&Jk-b@va0r*(Ib0``oWBqL*9d`*n_5&c+ zKe_lN8o%wN<+TYu)+6v5;bHvn1Kvq?Uh9yt-hqbjqvIE~`XyC3rr=}$0b>6_|IzE` zdC1o!+sJ$Zwd}*#XUWAc(fhZTv|&E-*MSd30w&E$Yf9~l@Uh3m@^T0#A_AYtAX)LHP_-_!7ZS7=Z)9)`1t)d-9kz#@C&4Q8T!}B!1o^gW1q+OK=|$l^8-BGNB-`DuOIwFlBa%X z4JoNu0nDAj2fj;|FkdCbH4z~C5$$=`bDRv^7W&6`9`(XUKj25Eqk5kVtP^**De&=k X1q|Sa5q-ml@p@@+I;^BRcu@ZzYfCVP literal 0 HcmV?d00001 diff --git a/env/bin/python-config b/env/bin/python-config new file mode 100755 index 0000000..f978cfb --- /dev/null +++ b/env/bin/python-config @@ -0,0 +1,78 @@ +#!/home/ben/Documents/Projects/Python/PyGeoIP/env/bin/python + +import sys +import getopt +import sysconfig + +valid_opts = ['prefix', 'exec-prefix', 'includes', 'libs', 'cflags', + 'ldflags', 'help'] + +if sys.version_info >= (3, 2): + valid_opts.insert(-1, 'extension-suffix') + valid_opts.append('abiflags') +if sys.version_info >= (3, 3): + valid_opts.append('configdir') + + +def exit_with_usage(code=1): + sys.stderr.write("Usage: {0} [{1}]\n".format( + sys.argv[0], '|'.join('--'+opt for opt in valid_opts))) + sys.exit(code) + +try: + opts, args = getopt.getopt(sys.argv[1:], '', valid_opts) +except getopt.error: + exit_with_usage() + +if not opts: + exit_with_usage() + +pyver = sysconfig.get_config_var('VERSION') +getvar = sysconfig.get_config_var + +opt_flags = [flag for (flag, val) in opts] + +if '--help' in opt_flags: + exit_with_usage(code=0) + +for opt in opt_flags: + if opt == '--prefix': + print(sysconfig.get_config_var('prefix')) + + elif opt == '--exec-prefix': + print(sysconfig.get_config_var('exec_prefix')) + + elif opt in ('--includes', '--cflags'): + flags = ['-I' + sysconfig.get_path('include'), + '-I' + sysconfig.get_path('platinclude')] + if opt == '--cflags': + flags.extend(getvar('CFLAGS').split()) + print(' '.join(flags)) + + elif opt in ('--libs', '--ldflags'): + abiflags = getattr(sys, 'abiflags', '') + libs = ['-lpython' + pyver + abiflags] + libs += getvar('LIBS').split() + libs += getvar('SYSLIBS').split() + # add the prefix/lib/pythonX.Y/config dir, but only if there is no + # shared library in prefix/lib/. + if opt == '--ldflags': + if not getvar('Py_ENABLE_SHARED'): + libs.insert(0, '-L' + getvar('LIBPL')) + if not getvar('PYTHONFRAMEWORK'): + libs.extend(getvar('LINKFORSHARED').split()) + print(' '.join(libs)) + + elif opt == '--extension-suffix': + ext_suffix = sysconfig.get_config_var('EXT_SUFFIX') + if ext_suffix is None: + ext_suffix = sysconfig.get_config_var('SO') + print(ext_suffix) + + elif opt == '--abiflags': + if not getattr(sys, 'abiflags', None): + exit_with_usage() + print(sys.abiflags) + + elif opt == '--configdir': + print(sysconfig.get_config_var('LIBPL')) diff --git a/env/bin/python3 b/env/bin/python3 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/env/bin/python3 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/env/bin/python3.7 b/env/bin/python3.7 new file mode 120000 index 0000000..d8654aa --- /dev/null +++ b/env/bin/python3.7 @@ -0,0 +1 @@ +python \ No newline at end of file diff --git a/env/bin/wheel b/env/bin/wheel new file mode 100755 index 0000000..9ed2741 --- /dev/null +++ b/env/bin/wheel @@ -0,0 +1,11 @@ +#!/home/ben/Documents/Projects/Python/PyGeoIP/env/bin/python + +# -*- coding: utf-8 -*- +import re +import sys + +from wheel.cli import main + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(main()) diff --git a/env/include/python3.7m b/env/include/python3.7m new file mode 120000 index 0000000..4fe7f6c --- /dev/null +++ b/env/include/python3.7m @@ -0,0 +1 @@ +/usr/include/python3.7m \ No newline at end of file diff --git a/env/lib/python3.7/__future__.py b/env/lib/python3.7/__future__.py new file mode 120000 index 0000000..f8b4fc8 --- /dev/null +++ b/env/lib/python3.7/__future__.py @@ -0,0 +1 @@ +/usr/lib/python3.7/__future__.py \ No newline at end of file diff --git a/env/lib/python3.7/__pycache__/__future__.cpython-37.pyc b/env/lib/python3.7/__pycache__/__future__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55606de3478aa40b7d5131649a01582bdce86dac GIT binary patch literal 4157 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 ve(mhz{{e75qnMR;RAqf(|ffF?RA+dqP2O9~H zbCBQy+~xQCS9Nvw?Cgq?DBT&zE~ffbUG=Z3fBoN8eSCbplEdE{-~G35{qX%A^Ume3)p;fq;yOe9sxH;cltOT=8u3B_*y-B~M zT)((Ichh;-xs+3Rm9G}xD!!3>GuO_)kyAxgQX{IYMpZ>^Qe$ddO{mRkQf*ON)m>_v zx?62mJJe3KOWmXHRrjg;)dT85<*A3%ZnZ}}toEu$)IK$(rq!eBOKQJ5pk~xTb?EZ` z>WF%*T2_y{x$0=OqMpEUQ*}%|SshnTRVV!XmCfqu#eDFe{R*B;R=4=$)vfI@f6QD> zRJZz->RtX=bsL`C?N3yTPvejlAbn_o%O_msA;N5385egYV_4d(|1` z;rNL9ih2mged?=fH;z;4tlER)w0cE7jN_x~>uOf*!<%1HHT9~R!r6XxPW=*|9Z=`h z1srEqpY#u^lQ*5}AsjE__!y3_;rKX?ujBXxj+by`zBh1u%3#FPi7|A7IA z@Ouou$MJgtzbEl~%3y?3ea3$Vxx0d2hpUJEXVsgFdEEKXe;DI-L{-&WHw%8gc0{h9 zQ*WuNTtBDs7jo0z=zZulI?8W^-hl(&xz+AMr|q5K4ez{vxfynY)&1VFb7#DITX_q9 zYuOLNnM$Q{DQI@Pe%qT{^K20=c=H5x4O$ws13*Er4 zFP-=6sVfc=o^4G(Gxx^hd;0atWgnxNoMZf@*t>DRnLrR{8Mqzi9z||IK?rzyO;=yi zZ$%}YEvgVGb5G9A{c#{$v(c^jLC^`pXuNs3-3k2oaw71TTlI#$-g$kg)mW$pfj>X+ zWXD{+u^6`M;ljX!t?l{}YEBnZMX|(kKhX6=V;W;jtp(uT|M~%rG3(EbDLyG=hp;{zW z2hAv{0_J2TxErtZ4xNx`sQfOlKJ>0FV7d{yX8W?YvMk8YL27uq3Bl?`PLnOQW?1X` z*U^t0Ph@VCQJRAvxz-4NC-4i;A?fBma{9Tx)6e${eRtlymA^6CAL)7CfG==*7mQ}YLP45 zz6bRM4EJ?V$v-&fw-27|G*&pl!h`36&K1AG6QP4RyySPzoIB{ZuO4hQ z=MFB*?I&iQIVc?;&VZUdhSI){U$`AfuCUE1W&X>!>TQvc%hG>`K_*X=_dn0L45(8KxJ-rnc;hBJFZuQNwrz4=by#X}A1=heI3-aXe} zm@Y=6wORwyAjB9{YPF?~T50(>AFI{gS*f=;Dz%#QPn2(}X(u?0>ZNydas-!A8Cm@0 z0I%aJB&0bf?~FOUt?4%DEYrnV{!NeYEmQpScp>;Q65@mEG*BD|L%J<^k!Ku^RKi*X z|1aPq979re+_IZzwG-nFT-(0_&W_?260I^btjyU3p3Hg18Rl??$;{#?)t|-0^-lWp z&9)!PJZiQ<0p>wnq&LHEz3aF9Fx34Dj(5=DBw3$l{w{*~%xE$;HGObK=a`!ImVEF~ z6?#kcRc|HqJ=L6_C%x->LfGv43*e|N&gHPN00JM9l`aRJt4+>Xfl3oXuO3_${G9Pn zW$4=iNG_4{YQ43Bx9ecP%YmQVs)@PdTfbiBE=ra)u8l5(n#ES1-Yjzjpc^mX6RfeIt0)ZyKIxA~z zcI$I3A2dwJGUuU3vM!}Rmy{9rI*vw2xz>d6zz(Jq(3ziaHk$R8_u7|EpFVxkJAdlj z*<&Y8y>e>y;?OcqynO8Zu@e_hotFVm%Mq`&o1EOSP}FG;eP2eKy-%@d-;4V^NKNr1 zoJro;7p|a_F9V(Yuu)(3*Yv=0(7cMLQk%Ej0Um~E!pRfucDj@`td8ZJPxmBSP+tc6 zpg@-Q#w%wNC{lfwI<>uwz83@q_D^-%t*Kb2c^sYARhOx%7ftmYJNzbPS$q)Z{BpE+}Ur1it&AkhCkHosZ2aWp`$>mgr#r3HlRb~43SdJ(@iP!0P~6FH%A?M~MVyO7k767?X9 z6B~s+-~u->_%q&XDau8lF9>tj(x_k@XC1VVYYWZB0wBJMiQVxQeSbMAw-Z3L90Yf% zzKCHnvX18qApjK_0<>g80ZS`kmt!r22bD-WeXr*S&?|Ho+wsZtj2NKT}Iz7py@T@a=m6$PHC zq(^v=TkZkQeT&FPF*UcPHzs{=c++j6>Hj2}o)nq?^G8$Nw{{TPagXVd*DTQR<+=Hq zQ7PtD=522geQ*t;<%O+IcP8ctnjwb! zb@o3bt9b)cnBmCHP}i4?8zK2?IP0{Q_}OQj<$@c{I?42lI_m-wZ8OV)lQ<7fF-c@n z5l1Os{xkga1iL$)V7g_PyTNfhj1Q&YD6Rr4_y)&#$vGE zRPJiv(*6~2b`-ymrDi1E%~sN#q-{_nUDyXjmxPTF#}V2IaV)C|u%s=)4iwS*bD0Up z+TL38f)RQ-Z9u-sra;k`z$luS8=%Ghaww9hc?iBKWr3b9L)XBBT5kFfB`D3x2?#8y zqb9yqKGsF7tzF8Z!DDF-a<{yx*@_{ume7MvK&F7y3_F7l&A0)6PF7|s(&B~;O+yGH z+RY<>9QAM#3H01tO?0jr?6l~gLhr9EkvIWmvrF1Aw3{qzOUMB^s|{c4pOz{P8c>RZfl_@k;o#L*z$t= zQAv|lT#7z8WIj;6Yqp!+TJ8JnM<`QJ(xB$vySDAncXiIwx5I~e$1L2ZjLc*iF@!NK zC=rjpEqarlDdMh>aWYXXQzKdw6-~HDX$U<-D5FjPfCxVeZDL^%# zpHSsmJIDMWfiYm4H-fVaE-gj;dkd;N6dmGxnHf2(M_aZ>FF;&pcWwx(X@Ce7B0J83 zCfFi0>VPzXD8&#=r8Jva-8PN!QBhhlfGts(<4OVdk3Xh~alV8voSq&X$`f8@uM!J` zuQ2&4lUJA|>?dInB-_7-pEijU!6G(QO66j?)WA*qSHRg({6g}w45Qd$83hd@a5uqa zL`LDj=(vVasLjYRswP1Y?~3j@F0z)d)}mhT_oa_7E>JWw#skuswK+kbMZbc=4*I1h z$Xq@2#oi#2h~Xp6#M*2~dEhm*fUPH^k>9mu02?0bBYqh18_cRMKp6?~6Y~d7>l5rk zGUeDpdMgi440%OfX)9cC8c#uFI4pq--k$Y4*3!*}P*=Rh zqn#*L%Oo%`x*D42YLd;d*K*7mo+a2svKLL%bkAt}u>aq1PgB4`Z+atuGH)g1oF+k< zx~0nw;e_VPzOy5DqtK^$8R?aLKYy$6cK(KYqloLG%Ke@EF667_`mTn*5U}@xSDBFE zOqWtEVIv|})w}hmqzQjij#c1+#>s5@OXL?lJeRLH+wv1m@1YIaHH5-*5=nEm;Y4G= zEoYyuDH zn?0=aHt6Uq^8E?nU~9^xqs4NuQZBpYLcnJY{Olhw;V6E0Lhjy)a)!#?TJH{EkD&?V zPRrf8)b-_VQ@fDN4diYqh62~Ra(7&j78^E@y9J4j+)Whf{n#>UEpZPB+y=tLmb9+G z9p_xf^!|$^aFb>WrTZ9;;ezJtDO1h}RHmtxPb37HIJ=fnh&i%%)b_M~-{^2OkbHXa zIvB!bMAesLREY%R26n}skdS;r7=K#EDqH4(0l zfvLD#4qZbh)OlOjIfJt*>`7R#vOJ^>={OW5L1q_J# z$ZHEQvot< zTn}?}ZbMKYzy2wHiNaM8g==ECgm4mBKSzb@qz=gGeNRSuBZbT4{8S28JjaZ}6<@}~ zIp8pXs@9>wysLfEBq(sMWxRcB#QJ`2JP_H-$x36A3MNDA@x%Jd5(>a!H zevayu?z|%wd55c479dTbYWl5&o8L+G>NR%eQ1vP}$49@!R!&pV8L#`&m1{4;V_ z7z2&tCUqBvaC>kMiq^!3c*j2;ZKqG-LfifkG*y7&_hw3={A8<~r-r()q^Bpbw)l<3C-$W$}V@Q>48EU%a9KPGr+t;+!Q4Y=Z$ z5pDyAKK(80M-j0y8yPS(l4#u+B6;-=#1Tn3aV!x)NC&{wKPHqY(`nwm&n2RU@C}Ko zN#q@7@IF-(O%{A9XH7D|dhPRlpFY@T2&#gLP$G|`XDse)5J!^%J{xbF^bPz^5?O=E zqLF)G2N?1H6J^z@GzZ3X{yOF>?DMa9kb1M() zWS$nwEBTKQ_NvW&Vw`xvlNc3kvDPzsUr5zQ>lWI4C?V+#FP+ikAl)oioA}9hr7=-a zB3h@lu{J8{GBpPt#(Xc~#TDC5cPm0KGwqbpG6uUM-jGI;)3TAufg#qpg@3LmK(h+H zx6;i*YZ~xuwDD8cSBRE?ScyxO+LUfsW++!eDrz$VK-!%mCPDfW33}vSL0FqHj7Kg# zkpm+cRip&OLi%Cf^0H!Y$J%B}o{Ut1{JO0iSwqDs270GkD?9hg848H=Oi#tW z3B;3#KOM?Y-D|Xb_(Y_}{kjO5Q~()qDQ!l9X3LoO5KrwP+C5y*6*1frB~vpO_(a2^ zpM{`YTj;d1KOEHMKrSii<3#vD^Bpc~^RXN%K&5%z)wAMBfS&+DLn;e|4BzVkt6 zNqT$*af3l?RihDwf`ke{mLwgEozjd+k47LC*1O$c0Q6{6jWJJrQmg%@?eAi5X9oOK zruFATU%Q8-27quF)ehE%7;$Ll2yv|amaWU_Z6B!1WXWhtR+bV07QOY6V}}nesk|X} zjaDc0V`AqrDlRHY^g)#G&J99?zykj|0}DP(0W(O}b&f>a*V6jfpnpJ|a-=}PTTDco zAX)@9Cf{IEXEM(uQFs!MD@DjE;h?Zs&R2GoNAN#ZDUFrNg$C}~Kcdc2{KCJ5Bo=7> z0z}vcjZj;}B0P$<^tL`^{H`Ndl*iB<2cbE8xR6i8SuExgarR*@=);{&T-1j|`QhFq7y9A2MOA>VdxKp7V*}xL29LACFCCj;6op&#%3-;|75r*N zMbWsV8AknmjQ1MR*aVV&cF`Eqg#>Sa@?Nx}v8m|)i^l7O*i+cscV|Rn8^RqI_eo;B zpG$l*1c?Lqc?paGZ3S3tB6LP1#Hd0Ols2S96O_dDxe%Q#HHq1+CAXtW`kbPL&K^_g z4JFUtAz>h=$ZgdNekxAcN}w8B6A6^`fqy*WJ_aw3n6?-4XgWqT6q`z?I z-la*ksZ!fre)Kc^own3^6Ef1qaRR^aEZ!w=3+_Yed?bAC7QJx=?bZcb&M)SIslIa~ zfBnD8RWUfuHAq(qH^I6Wadi&lLvp>2yTy-6w{kb!_Lx4WoOy$}NBS;;0E+!$2-$XZ zJIG5JE6H+KMn%{z-59}Y*KfGFZUyU~|J=#lC}aKe@qQurW1SPwl&@^kfda`p{nC{& z2C}^G+!zH+qc^dFZqW(;)4Nz7{VrBiV->7(qx{R|c*Qho98r!5HyG(d{=ZV_m!5$k z0IS>F@X>R*cOJb&Q3P%NzzH4&e1#hoq|zhp2Y3xg@+?8_LpiYJ75XH%rTSk&%CXVY zA_7{OAk@}@lxkoEQX9*bk?|l!4aBu&9ur?fxJ^`(;<^@S+bfKeq)Mj8US-yjK(sY} zo@|W2c3;duhpsC)cw{Y2+ow!u92$m-tZ!1vXv9xF^+pxtFGeP4o( zCdyUXPfAPy+8ZTMkFFU~nf@48^lEG(A4;-D_Hc?Vft7J2*y_vhl0riS zUhMb$8K5nuRi=#2vUUvXNIAZ$6-W3yjdq8r6D-D-Jv;ldh3KKuq)NIT{bAZBgTj^e zolc_7X#4m@tXU~jZ$_2jkI2@h$Ad*2f+mwUnOs2<72y9fY8<;NxXdSHW14AiU5jxN zf*Ew9O1O-L)kLjudXuOxSj3Coh>Ai9qfv{+)e-2%?0d1JRLi)MED)Ook(E%vsNi33 zL`5l3dpi=jUqXVH0o5Onxsv_n?khoUEal4uw~)`5oe78OSbhv)WiD2u=AG?$?&j~q za@a8(5o(5i7YlwXdHf1#rSm)*j)+>efA*qPJ4aE8HP-xxm@%IN(*Yv`!=XJ2XJ5{B z!H%xv!0htSln=+x!L(sAM+ycOp6wUFs-R=M4;CozVktSIwO&^xVaM)`!UxXvHr_4v zT`o6&KTqZye6L&T7rP@j^T9X!#gAZWzvYDAk$a=K_dU5+x#jST??Ru+t4;6cpCM~U zEFX>qsdo7ot_|UEv zAVnN3mkKW9(Fa=^vkKcYg7NgrIr@h8ssk2&SXq33sT3|5%5kTj1z zh`ba|F=d4ubohvrAPAWVb>Kw9Mi4L{!u|#OO;kW9L}ii^lFO(l^Hqolf~UoBA=MBN z8WG!m6}x=Y6&t8cr`PeMI>sl5SOQ9_ZnjsjlHo>5%a=%4DS>(J0=OX;@#i*S;zE$0 zD2!nmyE478f*+H5!g1Yg&NgQ&NdTTr6u7c~BEJ=Bxd1YOym`F24U>N>%79XUxAOT( zbYy8ZLQijKh zRKWt;jn)bm)*8t`mZU(O37T9PoPm*p3XX};rwm$a50U~>17V2Cv2>X%`pgt_4GZvr z@>u&}SJYF`A&WfFnTLz6ot8p@$V5uP(b!y7jvM&!g<0O%>W|V``zO?26A`4=NokB3;h2EcGxFLvsY6CVFmKqy%yJPJ5AT*FX zMf%`a8gAd^Qd(JupD=sMIudST#*_3VfK(ndu~IxOo4EP6}qbg}V{Vjf!8i0yWC+XhByTKK>K(njgn2(9BK zm%R%no+?eL>Hjh7X5vmvwS*n^iN}jC@oyH!2eCVdrSdCmyfFxT4d(%A)BqI|Q+Lne zUJ>E$#?Wm#K@8ob)%+vMWzf!$7+B?l$vzt0#l~aWjnaD(&9JeIB3H+3i1-digt2?4 zyJm)l-*-_-gbju|%V(ew$XaLI6(at(@o1m{vRMfCtEs)qR?sYx195fnKR__KcM9`m zCJ|dElZaFAHVoceyC(MTZ?QJ^1&krB{7F4ujC(*^sk6jJjMlWnYOt+K zzzp;qatVl4{5NeagQU#*3#@sG9nXH0-r2|*5X>Q$p{+p!=YeA4GZ|k zzj@vfM}m`bBs?hl;B8gh)#;JoUI0{g&>Rz~qA~80?C%98pk+9t@p{(+*b9WKi1Ev8 z>0p@wR5f}5yS;d(@RDgxCkW}cfk26*M_v2h_98BG)*APHYviNr6lMm{a_}GkTLR2)^+P6cpeEhrqOg;8tX`;Kr>p6h0bRX)m@r z*V@{@LhX%zJX#7dg$wInar*8}GIOqkiqG@dMoSE?=-hn$Jo|Mp=xAsU4{#ZyH`wS* zGdStsqk%Vcsr$9>KiLRlP504!AS?6yq$kOqva6CW$oR%(>MM&Aps}){60A6b=BL=I zWcEM8$SMw~5e!4bB6*bEAex%pjKp}C9u&fouJ51*A}vVHg3yqYa?KdUZFq_WUB&1y zUDWJIXV5Q4B@O#ft2=4LcS(=RILVEdMCI?@o9+Sqwl(?-8OnrZSo{zUV#E$D)RSxe z3JMkxH0G6}@C?vJQm7wTx|ok+ByPD z$!8a3gdzPKTM^dZ59t*v%OIcp@%S;ANcJPKJMoa5X|0q@S{X?29HH%u75f<6_6ZnPHxU}TYm<1Yvve63#JsrP-Yyp8< zXQ=u7KN1udCk%`p+6^Fq8>%5sWNdo!p z=nsFwHVA2hp`!wW#ZbcX^A4F=S0?^biw(uz14FRkPD;jqVe4{w!^qGVCm;X!6ePo^ z{-Bgh`|208YxIE=A<6 z6_@|m)u4d&xHwiu#>(r(+K?x#5t6Z8HnzNuBW)fug7OGFZ`|X6kv0z*L3vanZWuVO zBW^Zv3vCgQwV*t11Z6EAV@qwkJ;`mgk!K6H*2Ynb$Ge03080Hh8e_#{ikWnR#gZ}n zNo{ON3p-5WAEwL`cQobCI{c(CYNbTBiwnNqLlXBPp6azWaX^IQp^AlYvSvSArg8(+|jWoP0OjivJhR;s*1?8 zskWZct}h+Xr<$-^QG3|02MKa1Ws1bmu?_&Xk~$0~6g3lYsM(;C&EAk0ro{Y;3v`+c zEbO>;*n@8Zm$Ys%f;0Z{XgT(ixUjl~)+*=~adEFCdIo$l_S_X;O3{SH(kMSf&&Z;x z*?-UC2+hOYYn=lS$Zb0*ee1QKA$seGMq*h1&{#dBp6GaHm|-UpC$=|*#%9Wpsc;oe z0PaYH&Jgz)lrk0+M-?MBVF8})xM%rDk7cH$bbX9pf{9nEGXu#eTMVUaLr&o1zc)K8 zX*Ckcqz=Z0r4_4RF*=;Jh;WCQI#Zq8*Ax;{fp#$Q&SHKy+wlG4<(2OIfy2@ef|J5H zR;_{AV9CfpejyT>{uPz4uEYdxu;>K0PXy)}z3aJDk7ZytGa*(QH&Xqw>RzUlG?SHP z>KmqT3k7G;&rAI)X_06TCXBZ3h+ITrPOE?;i3*t7o$Xio{MX`4gF-LWz!A(v9r<;) zj{KtcH?jB2bXrFXq?E|t3H;0o1Z{jq$P{b@2*yHsrC?VhNboTgS*sf+YYAdInrMj> z(4#T&nQ3Gh^mU11xrdOKkTsVdbCPug=k?N3?VPsKdInaJP_cpeVma8RB~`ek@)GhT z#`D{P|6NqP0sO(Q^Z9_5!FQ$!b_FLn?S3cd*1e*;n{+y(cxIrV!mA0?!}|G(i@>q` z`&0}Iup4TJCyWF``aSI+3T~og?G_pa{Cjx%c+%$;0&W&Hr29OprXYWUBOWedrS%4U z)xZ#XtTl!ZXFiK6>jv+mc-_W5JUfLXb~lL1H>^>V{tnwl6{JxEqj4wf^rGCp$a=uF zXrf=boS&BKIu z0BE!Glc>uwbRRI&z+|H0{E{6yXsZC(tSX4{Q9#ZjB=rQ2!3q5Cq~82W(sj_AZ5V4j zp`kMWLi%6M6KuiBVsBT>24kXc7j9&%4(vhcJ)*$JyQstg^QNt44bAxCG|abCK&+X6 z8z`5If01X0fSx|MI`*AO@!w%e6$ub{1+d+*a-){vp5p$WFR!coSk^1xW0R0e_Ip)ACy)$y%NBpwKlaWGQizp#n!FI(D!u ziM^CS&U&N4_)DrTW`(m>@hl**)jsWVVMy={w*fcX>&JpN!*Z88+>cv-$Hx}JDb>JE zv#-i_=sKPPTKwAm%O$&r1%q2QTTo)V(*Zfv1)y&tDrCRB()}b!- z7L*-CP+~05m-JL2rWMX5_InZ+aS_coJE-enl3{_)xG&h33LEW6Inr4&m?%z^N?n+3 ztw13@vt_^0oJUNIykc+by|Ga`qn_;* z1&kFDOPoM)>@DsQO?W^4+7kx{nj&l<$%tgPwAYb#x@7K9WP#zpS+8J>$V%-zenz2pNog%Tmp@$&(Ko$TJRvDx?A4A4d8^PNWiP(Bp*$^%S zJ;fw|U2+Z04-HnpfRH%k?9yw~xY@{=a?h!1Aq=h!3KguRPCl^>C%OB}PFX@_8Ng9Sv|P!taRRhs z@F%qNG)@ea9OF_GNV#y#+;DLuwJb8?weMo*NEZt>ilCZBp_(N`n8MNls+mWMXixE= zMyMb9t^}*BrGi)*A;YUj%8u?Z|d=A!9ZONWg-n#I}D3h_;y)9uuib8wn{JXASr9h6znZ0_0a0lj*J0 zTt1_R)^-AC6IYwWv9OtsT!=BqW=)my*N9SbjBk&4!Du%~y%N$flj%?ymzfMU88aZh z41=$lX?B#G@}LEeAx$6^fF41 zImGOASyM4eb172|jS~86Uw@xx{{RVA1O8*4+Z%?QNpppSVaWg{jhyDg!L`=`jU&HG zV#es(+%8ST81Op*LIzSsNuGZhortChD(N?!D_R}@&^s%i9n5~EEoNbQ{#!~z0cJpu zYa-NB<9}cSR8r`Ao*!|dT~^nkqbVR)2-oElvSp*=IUCUT^Bs^9QwDsi!W8xZZkRfR z>JMm&_v6v;vL8gzDSv_O*5vbZZTG|Lx0`l@9}Hm44XOgY3Psw)pCMbu|IfHiFJAof|Vj5vf6Mh)N{jj~SYqSXpc3?A& z_@k6DrWybkz$)1F1iC8PltNLU9Z@YBF{nK#NMPAO?ho1b)VXq_48t!cGw$a;0w=YV zREI_VVvT^AGlL^QS5fd!kl3C#83%jbL!Licx92yeb-#B9@I1Dni0@2q2>&@@_y7eY z2U&*#K7>dAWe6qsqI$!4QohLE;D5biZ^cSh#z^VLEoabz3lzw;?i5BDg`FVsp zejDQab+4a0nfuyKm_%HxVJX7ei6vse_I~MgFwu9mV~G^*)A){WkMhaO`iXo8)$RRI zNRkjgszNmRa&@U0Mokp8!f1ogkHe!O@M-(1wj03)Gx z7Xn$oY=qRcg$STFf|MZA(s~zjUmS`_oa9C)5w64Kh!qGau465xU(CP=O&l^XnpS@Lfzj{B!~7`+#uT#7z;N>j z85j>I;s=22_#K{GEjZvOpMu|F!T||BWHKNqJ%W29m;u8_gT#V=8KNq! zl7W(=t!s<8H?AR94t^UI*|xA9{GGrr>@xFy|H}wnWymaWTRzD<5Q95al=!aDFRjBUO9B=vAXF_1hCL9{w5rh%p(`4OCd|@zlZrp`0tc<0bV@~ipxQQ);J0E^AuCR_nD|Z-iZhz>r>1!b0G8{0-DGo46aeQ^mXTUd=YU0B6N4@+`~pIU|$1)o|btqDe%kXrCtmHS~=fuC0KZ6{2#6lw@PKY}b#`FR*Y@rCRc*h?Y# zunS8jzB~=iI_W$B)SybjRfb%eMsonK@;EPVatm-JVVeNNFydH3{36aJpIe-KaN_vn z)a35T$0oltd1mr&=6VyCCfb!pE02^b_@BT(j);BShT{&dA&&o1FCA9qzv8mivRf%k G7XBYeG1Gwn literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/copy.cpython-37.pyc b/env/lib/python3.7/__pycache__/copy.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5aa9c979c00174de5d6e10c20ecdd83878e6c156 GIT binary patch literal 7126 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 bX&PCtVAK&j2+$E=V~%5*X7y;9)i3@RUTZ>m literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/copyreg.cpython-37.pyc b/env/lib/python3.7/__pycache__/copyreg.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9b6efb4740c8fab2daa9c31e21f1ed8c306026b GIT binary patch literal 4269 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/enum.cpython-37.pyc b/env/lib/python3.7/__pycache__/enum.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..744b2c65e59cb951234f76454f61ec09dae04c77 GIT binary patch literal 23963 zcmch9TaX;rd0yXUrgwIB_JYNgAlLu_5DS9~N|Y#?f*=qVij>JUOhSY*64e+?_wLT_ z?9A@zUSN0JBgq6LK~5-Bwo^%|9MvMKitWlxm8jyla&t+tl1f!veo0k4k8#BnzN9LZ z7ll=c@_qm5?wMIG6h%&XxBATK)2Gk%zyJT~%M%l21Am|W{r~W}<6kk1Kj%&M=OS|n zS9IDmjKB!YmQmxc)iT$tnzd%vY}44DLW$jS)(W+PY1}m0o@0c?)v|ioH25!1OZw?w zGuqZ?jlc;CK`|%=ZZH;pV?Aml-)@D$4AaGFTg!@o7i~EB?0r!P)HaPT-Ej11Y zMU)i7{o%|#r*MhJ!{i)aL>+8+-(sk9@+P<;99`^TN-EP;{nvE;1 zdKA4F$EtaIGY;p>{`fDeAXH&+wb_XK?zQ&j+G}B4?>o%(ORuzJ$v7{y>PvDf8K=G( zclyQ6c5`DhY+#4vkH0pqE4ZR#NMa+w&fT-tk4nzUbM`$8<8`_peLajfRXg%-sLjx8 zE_$8YD_%45>Ru2=4b@zaJL;VGQoR+0UMF4-)!k+k&i6~czZAy4&rBqlvhN3BD~vpp`LKQGe5-l;{JIoBJO441Y_83(Z}+QyGeU3K_+~iUA`-(cn`Kk&LvCbA92Cfs z+(3p45?Eic4l`#5CUXu}ZPn_W2%J@`?N|WZ&g*z;1qD70imSHVmjZim&jr0_2JWhZ zg&gZXyL%z)9#&+tjji>44?7=za2XfgvoN6d{`XIQ@{^k7`|ok<`lkQh|3blg95k1& z6}Iu?umxE}op8?mvaEyjaRm1fQP!}|m{a&yN0A>{1-34$@G3G~1zCZ??2iO?KKoDO zIS^H5Yh(7jFX~l8E!?NGFUagm-4E?C`$$jz5p!3B)%P&bpQwY(@m9?;*^gw-RGblh z9%B)KXZO5y^C$2mowujw{RB$#d2@Yv$-ECC!@a+6^vuLe3?KWC)C{Z_p# z826T%cfz*UAfkGk?Wfn9jn!8Db}O83ur2=am+Scku4oELjFuDQ03hORGeGg2wa}eC zrMyPH-R{KR?a-4}!T@_YMtX2fsg44naH6oa*e|TB4lr%kJoo#zRajs3J8i#FZ?$|7 ziOoj%3+z({Vs@YN*Dz>bhU#y&2P3`E>fn{=;{2XXbjL1iwpZJoyX}i4Rug{Ov>$E( zr-90AonW&?RJQtdqZO$q(dX{b9ehOJa~z+bqvcvfQ$2%TYU*v#O)4^8WyZ( zfr8tiQ!50dOSU3k>RvB<_?*W<3tQ zJM|W+Slc7XOgAvvY{p?UFHJ4X75lF56PGaMQ|O~#@%@d>dP^6PoCTeRtN{tE-`;Gs z`UPorX!^2E#6TJ5hmeVgt*-5uBNHWr@Gm-tWO$-qGZq1dfqmbtIg$siAz%0!C{eA5 z1t|8%e9nP9q5HcxRK2n4k@|US;o9v`c^$G0%sxPAw25U&%Q+3bPJ}uYZbo4+UzWME zIWiV3T&v~bfq=SxVX*^T<+>3V=Y8FnEE5`wSW%kb2trklo1OMZhiMNv)^UR~42eA4 z#Kt{i$9xF7x&+GOTawz6I)W|c!d#(Wh&I_M89h6(@jiGFwDzw{xr_2YYJV}FVEgZy(M6V`>@QHa!h8ZAuxRObWW3dT*1M)U zomeZA@zg5wUSjM_qtA(WMvo8azMvXZ$r~PG*8U`GV=frS&TL{nG)?UB%0A>R=Hva? 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 a>PrUyr)Iun*fa17PHoJ*h*}fwlm7?F0gV0t literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/fnmatch.cpython-37.pyc b/env/lib/python3.7/__pycache__/fnmatch.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1bc01adb551d7777d500f64324eeeaec9c580b17 GIT binary patch literal 3362 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 X@s_c}#n0r!xICACuy`V0${+ea@37&; literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/genericpath.cpython-37.pyc b/env/lib/python3.7/__pycache__/genericpath.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7d5639fd37adc796d1f53717b3a8f28e1c5d4eb GIT binary patch literal 3773 zcmcInO>Y~=8J?M4E>{#K%c|p#rY#0Wjd%lts@(=boit5j*@A(>F)RTN*w(~qXDF>i z?$R?uMHH4jRPC+ksfVH`8|WoJrhj0sJ>@U-l;<5vvZ7cm;vh@Ryz{lQ&%7Vcy!>Qg zp~dig_Qk({_xEMS{zIMPXC94@QS3iaDb{6*D>2|*?xpAo6{t`(RHT|JR&%PQ=2crQ zY|VEAwWz{Bvu>y^s1{^HEvY%kNL^GhWK%7xCSXM2eTk0(pK+dbnY5}sX zuBds)1$9-mAs5v(^+U)D>TUHS$R#D#S@Pq9f3zN_Zd;ZkZBmz)g_T)39F~Q2r5u(< zOShdCvMjXxbiK7&%A#~~Y_(Lm(U}`eI#OU66=F0$E|`lcLWI=4r!(9)sRgFS6KtuLWD_NZ>p;Eas!=lgY}_jBuP9dBs| zxI^t**zTw`^sOdlZGNEZMs9(#j&j@22Uu&SE@7O}{Mf@Uuq7{L;6RrFVomX0!^7FLf_=}+8JK;;{C=mxY zUZ)*+Kq`&i8V^z<$s`YwhFQP|%pz46P}R-#-oy1L_t)yCbv?M4PJ|(_wXn`BV^$#& znVCcNHp=&TkPl~;l+KK`%=_NWNs$FS3uozTV=0CZJl^(sv2_$PrI~cjJKyTVC*~4> zC!*%oyhUdrJD)ll>Hi&+^NvQIOLn|RYuc!e{dR}qogdsjhK;DC7?EWkx+k6A0%{6a zt>orJmbOElcQffE!7EdE<9)1HOc#8=5XEcpu)C+_qApxrwKZIB{{U}Yi{ z&r6ab`&)vI$y4aPgqv%Cau#TWvG-8EEzn<`1)64=wlMdbLG(m+4#W`f?!E!U-<*Ot z1Xrrmr7{DRZ-LR@45nwgZE z7w$AFb|?<{l(`5kKIN|IrP#ma;));gRrUw@doc~BVHH-Q3a+u;z^qnW1y%4D?6}UJ zuRdiJu}yfewwCXKTT_rK{0Xjp9HExHea6IeKMhJK1}l#4zJX2^1uVKFTz!SBnIZ3e zl+4ww+~x&BqsVj}(zbQOjYqgsf?+!Hky1x}OW(mrUeNGOXDF6Pfr%DxeHZX|zX6_-4UbNioBnow-64okkLb2;^vOQQ_=EoF zb{EzEI05CHTW3z-?SL`5HBRF2Z|GF)1snxRM+}+kz9-OYIF6`l914uniU4C#6;ssNE_D6Xr>_gNJwL9ISaO6%Uo+s{8jbo%I5 zK3-`Kk@~Oo(IB5Ci+bPb!Xg)yK0%yiP;}9BS}lp^{>eP@2EC^Z@)?TOqjVC{OqYj3 zqKf;MqFWd0mdv+`(qNh2;yA#u$ev2duHQ6e>2Bf1cFFY*NXTJ2k(=0JIC7KDm!1SX z6(BGgrk@we{1oa;;+l`@!0J&Qr32?B-iGYPs2&zd?|0{CGqX;NPtRHl$M>l3o(ZXX zu4hRx*ldjNSPF91Z1E8O*@BnGB1Y>HzslRf`~q_)w=GdGl{FN*iAwR1O+lRdpHxJm zcc&ppICT6F4xq$TJV%O)KFHYIK|er00I6bZ2ejN5mqEvh{R!(}Kw+L$fq8}%;cQfa zc$3DX2O9_P-mo_lnVK!1j>_Q}#()NqrAf+mCr*QW>2JghbI`e$7VkjG`996VI!FWy z%0IA3=EW>`K4D>-M25Hnigu=M_*M1X#$=>@atvMdGT7esdUf3Ek;n9UNuwLnKMv~E zAyC58w})4H4xg}pB}IBl1`!iKL{vn`FQachz-)4{ zZuWYr%zC}kDO0bP4h9$^{`0A+p>Q;mCK+NILy>97R)z@OhrA&^G8EF@s($-Z2z^pW pscs#AIQzTx5xsB87el%!Jb^`xcs_2&b8*A}qIfxOqPG}d`3hfEmY@It literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/hashlib.cpython-37.pyc b/env/lib/python3.7/__pycache__/hashlib.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba280a9e734770e82bc018fb3cd9f9ca2005a57a GIT binary patch literal 6616 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 SEiCa``pn#c_c#|=&-`yJ8Uq~w literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/hmac.cpython-37.pyc b/env/lib/python3.7/__pycache__/hmac.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62a9bceb17ea27bbcc8f404ad9878e0a1aa25887 GIT binary patch literal 6138 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/imp.cpython-37.pyc b/env/lib/python3.7/__pycache__/imp.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44da2155c6c05c6497318ff791e93f7b9fb332a7 GIT binary patch literal 9778 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 Wwp1O@mPQH_g_lcjqqPG082N7&M3&hA literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/io.cpython-37.pyc b/env/lib/python3.7/__pycache__/io.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8ade339aa3ded0fedb306fd4f5aa459eb8a13b7 GIT binary patch literal 3434 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/linecache.cpython-37.pyc b/env/lib/python3.7/__pycache__/linecache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9d5aa6ef034cef0cdceca6aa28943ddb1564e5fe GIT binary patch literal 3814 zcmZWs&u`qu6`mQAyIg9umVeZ-0>@zjH1-0vq_${N7_!mSt^)_H>c&d#stLB#&a6Z& zms|~JqpZL!P{;?PC|Vcop-1UbAeSC{F3@vtIRw167X$7;;7j|x;jW}OT+Q&2oOv_z zethrK59j9thU@X?|N7-WE-?0QdYD}fgdd>gDLTnEnB-CY1?kHM-Ztb}8AuOOAkWD;*@QGF=Vc3{no>Mu z?eqKpyc2b|RhY!7%EO+{2H}IT+0N21&qlhd!d{%Hd?^Ulx8ppdztpHyDjAwA)GCsv zXAUws!ssv_3^Q#o=EjY1Tcywv_rl1kN~3`apeD^s*vm$#ydK6T+>4VWOtP#W%4{zU z4K`Hi3Ud|d?shng%r?gBsg`ha9GLCMgrsgMcn-s{wX(jY44tD4x(Q9AgF)U_-M*E( zWNErwG?MS2c1xeEM|&)5w6QcRTh+NbTS>MVC3)#t!+*~7Je0irV0k+m zsO3$SF5k_%qk&3IzWhLEJE}{9bqsFrtL*-RWtD!qoWz^UL;LzWOYh<-RraJy!?6}n zcm^%^(J>zI%e*PNB+o9|w>1HcKmZ}|a3Hb2c!$hqytmLkI;d-mmFvWcNij5wNs4fNlHE?41;3Wq4V@GyDM7 zcA0Vdf&MXP^fT@O`Ynuk%%p>DyZgU+Um3e;Ytm`7d_9<}Ag2(s2U!Y2TptZ(WYno6 zBVZAiGE;ea)r8$FHBp>~QA)PZW2@XyMv#NUD4|RkFKG{FdrqfbYkQiEuj$z3+{mi8 z>y>jqQG-m6f24J$t;O1oZqU#<8tPg7uNtqTn;X?A^@fBL@7TaBUR0W{3|Iytz??zfy9$&OV@xCg32m=!jRNJ?{DjT!J&h>d%7!zrjXUFI!z43daB%##Tui^1khY|vP z7cGAW9XYfm;8fv?fLsg5HgOmDwXB1Eet{on6U7Okh4t^3@cJ~Ht{7hB(=?N=(9-jhv$yi#7B&JKVu&P zb+GEiV?DpG^i+6M_}IhW3)J96vUYI9pYhy2dq6uGybC~FMJDW=N4p@{q%jGKMiCVL zi7g5rm^Qcn=P58nr&3`I7?P;HW~5VqRE`Rq+kCLNS0%*#9_sf%0ix2at9iJmvvliv zIMk@#VH6Hjo=02idMKxPc8rDZDVA0!A5-;8hP(_`=~&%tFuc7>+DLVc z?Z0^nN|#oX45^*phAJ4+Y_>}uB*semB8F8tdI?h5 zNTU7m6shl99#dgKkPnmC(hI-@(UH=N^Jo*LJ|E-FP8O$SV|_eS)$rDP#^`u+WTwx) z$@(fKkZ`l1!ceLh)?s>)Ht;%acJ8DQXsV-jTcy7lx7mz0H4)j(I*`K()BUUEu;+7VvZ30Ma@9YQlG1fY9rr={7N%ujj12%z1WXsL7V2AQn$|eRrWzh704z5B4#E_h!mnVH(3dTLLfr;Becz&!i%eg& z=;V<^HND{asjL-LrJff2(3N#ylt3uez!@Cl6%O&-1Jt8JV1%omn%ZFGql=5w$KES`4h!e($i5h+QD9&tMDGO zOD%=#MD?plVLn1ZjVfh863h7QleGw}7ui#i9-O>0H3vaaCd0u9NClHknLi!s*z~h+ z71TwWi8@v^8*|+v-`8i6DajEP4XdCM)}TGun!kQezlm7XA-Xc?bSejSI;G#~P$oeN zPBy!SB7e-?G!>~b1gykS(ypE4Z|P2Hzl{}5|72`5 zXpJi8U&+&J`1~idoU)$HQ=U?eQl>VMeMAX}@de!Fn#Q&{nE32(zN~jTGV69a`WC+F z8`N1;`xYenh={{SLeT194oSorHRYVhLrwl<>cFx+c{w*!G!$@Ktj`X M{Ccnuyb-+jf6f)b{r~^~ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/locale.cpython-37.pyc b/env/lib/python3.7/__pycache__/locale.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..79b246522de9613c945dd85fd8b6f9834e1f28c1 GIT binary patch literal 34580 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 H6aIeyg%On* literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/operator.cpython-37.pyc b/env/lib/python3.7/__pycache__/operator.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..51c51313e70fd5272c5ece978af4ccb1ca57bd98 GIT binary patch literal 13925 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/posixpath.cpython-37.pyc b/env/lib/python3.7/__pycache__/posixpath.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35a575c23b12c6272d99b8b5bf4b934b2f183a6c GIT binary patch literal 10421 zcmbVSO>7)TcJBY_X^tpLruAo8Zp*Tyk?EoT?bRw;*^+EY-lY{ww!C9`C(WrIvdLlh zsJcfa$34cv)WY%}77h>?K@I_VF|t4qEP`MU!D0`42y)3KNcPZ&TmmF zeD8J73^`(8ASAk~y1Kf$UcL9e_fzx6o;{9&zYl);S0BD|PEr1zZU%oR(YSys{(-6} zLa8f4t*b(-Yp8Xh*9~FRO<~q8Vbx2bRJVmKtaiCx=Gv({Tu;;|xUSSIsLSojO+`3j zLR7>aF)8+nDX~xN7mtW(@u)Z;4vItKus9+f6Gz44;+S|sxZ+81Ts$RCh^NI#aY~#P zRdGfM8M(sG!~_UKW$6_lsA=Ueu5H zm8Iz=#ebxsh*!lP^gJqF6H}-Uh;NB~s1J&>;vnin;@jdd>cirkIEwm+_$~1`>c@oT z9mVyyI4_Rj{+RfVcmnkk;(~BdyW({*gZfGFhPa6OxbG}IB`z&%^%LSPaaq*vsr9GD zn_?EvP73RWQoZ8+BR2VBw6YR~Zq)ImmjqE5ySTd^#lf1}@sh>RTk+$X<6I5n#P@_7 zwcKE(6Uih97u;kqh~1S)blbiw0_iuC_WDfm+>K(_3xzBFmM`5Ta<&il@Rhhm^VeMW z=A!Q&FK&;!^g$QXdZFvJ0}O0McpV>diVqE!7q4SUEAh8!!BMh^uM|D*X}`8mbHC>` zXWUysD5BN4I^z^ya62-(8wfwfq`n)|*S66f;H&P67lt%j$8QF$pozs}td}^QwwGWv zD>F>k_BCRJ7v^gyR+%qh#cL9gGj5nrUByP;i0F&0eD9h>Wi#n|?e@Am@4MaDZ*|*5 zP#A^J=3E#Ml|<2uON2SJBUoe5>0&`(Sw5XV;v^|Z}RNyd=Q?U?Z%QCbG`Dc@bAus-FEwHQpKv8sb?}f1hGvo_A@hxz4p&ZAL zf;K-Zfdp#QZQ?q;U9V6J><@V^?vE2M$*g8q;wzce@wnDwzmt{dWo`(+#WPx7JE0CN zlIs#Sk@hgNrSG+Q$dS0)A$5rx-7siI!f(*0SgW#<^z%VZu|t@@36V_sKg?d8~8ZHG|tk3;B4V{%5%Bq$*K^#C=y|4-H%&#YY3}za%mY*uJiZKta z%`QR)XXpKJ_EOaBu0T%W+3PY|g8rhho-9Tos<-^;>h)PaygSi_avc zP&chqSt>2rTk3}TDMo=tt@p|tL=kw<^IZ~1l51K5?IRH63Sc6PT)))<32rwO&|X%a z-U|Z}K3#P^xxmD_E8RFDZHp7>LX~)vprTRYp8B|ds#?ypD9)@F3yUO+Bu}Bpbd1l+ zH`hDA8 zHW3GhEI*2yo!hjb_OTtCda7E^nv$rpbM+ zR8NgpF&p)#T523r^1EBgEhVfON@69Y#BS-!j{Hi+{Hl_ammHy|N=r-CKh%DLo==tU zE1~v*lIqwrqxTQjfMIU38WHPPBDouE#xPciq=R*I(%*>ncqGh=qp}Fk|bs}y-hF6 zS-PEkJxOFR5825@yz&MC$SqHXF!$NSf)BeGuu03N8qGz&x!izOH4^AVTs1S*%hXOT zQKxA-b$(p3XgzP^id__nNs?u#8m=jIKY+u6N;ulII*q$AnH%EA@8HFUWNxS!LOrPT zA%Q|mbGd`$EomoqiU3|d%b z&{D=3K&rclE1pE5=){0Y^$0fH8L2p75Mk9tT=6R?c5Zi~!w4M{KqH~`wa^wiT1H<> z3~Zy4ssdZSWndG{Ir%i+X8TlQ`y`2`9V89mRelSPfTaUZqN~=EqAS9C8v3WOA$CZjnl^3u+`8o=0#ZaFl6HQDQr+g3k z{s31lfCc51ovK78omk9FB*a~x9PWS$8+HgbOiT2Z1`BpFw_xPmeW0*1sY@1{daZZz z|1$N6c~<75Hlh@Am*1?GSmH9X&3P5~GxEM0jjK1lJNI^0ijxMS6(3T{ zXsrQD#-wvEUi%|lg~y@+EA|7VhcZg~MSN%SXp#|mDw*hMA`he;-%c92t^nAJyOEST z`GCa%S8vKL5R<$#87=$aPIBWnZ$ds<#mF6zS5QFDXd&a2>_gw5;@UhFyX=4%O#l#gK|&o!#eod#14xzU$}1p zz%4eTKTGzcmVn6gt@TOx!jma9zF#VYVlPzZuXCZGRl?n@CpL2Sqz>%yXM9#pWSXIhsHio zKYpP0S+BnSAN*CPchevE%~&Qfn+x-qCXp2*PY-z}`5wLxkoG;z6&T|FiumuMa3ctWC1Cykm(2}c}Dh` zGIb?Wm*j08aMx>heR+xA7;`ZmMc)Ake0&`Z=n|tnIq?*jSf~xy0z&-lJ=CwUzL8cr z@VP2{e@Lq!l61Hvy&LKmS%;w?`k%Ogv_YF7X(Q`!auCuWpaJ&xjc^KDq(X}{Q9_Rm zq(^828}J6@5(XB8a8`EmJ5ip-oWnbZ?&1zm8Ax3Ct=59lFRi_sTF8G~gU;B{Df0g; z`Q@E^xHFdZ_~)q^f0dTx&vE@KEr|)_PYiq)ZP+JZyQ*MpN#fcpZ6U{T=N=@x1h+ul zwAq3vSku3zYHChnoumt?()kT%Kq|fGM!7T!XpmHH2P=q4IolzkE)*e;PJQG-{G?gS zqc~!Zyo{o79vIFug+n?@Eq_fu#n(EG5-6(W-2|1h4w8b<%fK1 zbKT@1IMYRx;IJo3sNNfdK@xcF2FK2RTsKL~<9a#tR~vcLplV#iD0})gi5SH>6rvDN z(|;Z<=As4o)(!P2dg&?L4hYl~{^5l1MZMbuiijmz*NIz%fUJ>^HI=Bya?>)LWdd_yQS`JSDzU6p>xuyIkGyNzA z4Ri8`fE_w)qyg+O!wS$t2X??eWN!_7BF`Z)QW6SVDmB&n%G$3}6&7tjbQXRgY^V+! zT7osVKv`HoRk(IU)kk}B# zKY_iZr@$KE%&&nsHY_VJK`6^*`Ir2LO*vU%Q!0cKIH`ROp$r7r-YgU1AaEfbD`eZh zP-C0FF?@q?k>0p-o-C{=b3(<*(?1Vk#t<>ssv(3!=!;F|B)cT(&dQVxgQ`a%Lq#sq z6pP9p6%_FC5sRRh7q62!$_%7P;jhKMALhQ@VH!(GpWFtijd}?{LGmI~>K#)Fn)-8M z{1r6#6ayMxAOt&c21?)o!V??L9=UmwsL2d*5>vDB+}1RG688sSx+XD}7o1tbldD14 zB+#HgvPP7?VmbOZG*Tt5z)#~7k3`*sm&KN803bC=v<Zd2l4LC)M8&vLYAg^;nHy?a zI;6mkAlMXk9!rqjivK)?tRSSde*&Kh9-5O(B$Z@O%RtofFL~6GOm6NK6-bA=rH?Z4 zf})T;y{86nhvYULWZv~%q)X%CKr>HI_4eUhhe2bA7A#L}k_LtdOjFnzkr|pB+WY}T z-@xOTT=oU*^G6l(mnHV?ceOhRn@3WBvoo#sT&Av#x+J0A1Ls^DN04M#&i@U`2hD3K zy~m2vyV|*S1Za!TqcIrw|6har6tl|>D#qmV9{T=v^nLjh?yFOo^FFy&d6tJWA$;01 zQYZqxT#GJHi|{_zCrbEpUP!)%R<{3=kHd;4A1D_Ie@@BDvv>*v#4cZ(-eJAs=!ul8 zo}Vc-h;~xkWRaWf0@iU3+Rkssh@r**l8AW@4F!hR9-8Hm%2}ENWjmxE(x$XyP)70q z4?wMkyGwdRmyRob0n_c&Bg(8T5oS`-g=2hyNH_s9B3+|@j->VH3ewjmTGr>v`d@se zwg{u`doanYE9&~uq{O|XOGPgb7?uuE$uY>h0$KlYA?u2m*ic2~Q!PJl`b@!Wdw8~7 z^Hi96(kvZ1Lp72+eRHjrICK&LZ}2$q6&4_c=B3tQI+^$dqW4N3(e%yh%AH>TT{Zd7 z_o376U$@92|SV+_obGIXIbuI?&HX;_m#jY=L`E=RI_jpS2c0;>b_422@aaB-X7BG*SI8IBHX4T&haMkku2zLNCj zHzU329UCq58&#LwA37zCkD&l~9H3B;R(GX! z2%p=Klu>Z7oy3Z7oLrvBM{zYJe}uct z_|z?j#VG(@;fDYW_v1Q>o+*tENXhTm4^N~5KV=%dbXC>4>Zz>MXo#rUXyl9_oX*eC zST~5L@^LCiE~HBZ`&2r9Ym{eyiB6gXXV{qJ85%+Ua8931EmAy5PKqQa+wVtz>>3cKai+^BCW@5+ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/random.cpython-37.pyc b/env/lib/python3.7/__pycache__/random.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..722bac1a4ddc01baf698ca54e6fad6adac10163d GIT binary patch literal 19419 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 QGuk@x=S(ryc&=jpUwrLi0{{R3 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/re.cpython-37.pyc b/env/lib/python3.7/__pycache__/re.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1ba2acb8b1ac1d52226cc9da1c9bcc33c264cd9 GIT binary patch literal 13829 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 PzHu1MSKGPQaQHs~sP%+i literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/shutil.cpython-37.pyc b/env/lib/python3.7/__pycache__/shutil.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f602a892bd5e75d3e77b3564ecba5e62c2922b0d GIT binary patch literal 30570 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/sre_parse.cpython-37.pyc b/env/lib/python3.7/__pycache__/sre_parse.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..628b39158b246ca897a192b7e9c2a7e5aa4e06bf GIT binary patch literal 21382 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 Ikbd_60h2&7CjbBd literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/stat.cpython-37.pyc b/env/lib/python3.7/__pycache__/stat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8f66c2ac4d4f5df57a0386819138775bfc2582c GIT binary patch literal 3898 zcmb7G&3DsC5|$w@KcMTLa@+G?tbsPv_S--C8s&4(Nx>c=}v9Xwh zzs+C%^@o3)lcax>(*2F0u#9*6x*|y+F$rWQgTfRTU<05s6$aTLL|6od*bqcn6o%O_ z#8?bQVDzsN8-Xzx$95DZ*ceQ*aX7;!;4GVjbL zf%;9<=ioN`67H~hSY!*xF^*hsA@|!D#~qAk5$^=bN$k6e_OHy4!I)01%D*8RcnXbZjh>M|LJ;olx zGNdp|PcVw7n5l0u3(qjB?{FoSG13%9wu0G7@ab;a)qbeiXG8bJ(3AG)#=(!vgqCPwu#TJXz(N@(kCK#&MC-sGvdTuTkkQXmC=`>VigCnGigo=nVg=r=38%{2l!_oW zN{8khw0I{}=|7#=;<6Y;3jYsQP&M%*NHv?YXHf1k#pFniv`nB8{F&eOZOMqlXn$dJo)uPCm>twbIqxTOXc7;r0rADz!8{TR~#hbilAo)>C0ve^8=JA zyB3-g=o@lY#2J*|pWXKmdU`sc+D=7OYWR9+?G~>&m4*iVrBe&H+HsQUwNpu=`Cbo6 zEa#t2a_MxE)rMQ!{W!su_2;K$5zP;K2-1H2zKcZ59^b;D6mdW}nsY|441XyIy4}B060+nErK$CpA@teHp%T-?nU#|Ib%a?^O z|LDtYU$%Vtl`ng~Y`@C@ojP;}he{EJZRw5tYT1)A(w~;zD6j4vDky1xRNf4{Q4giV zfn~gR6)|-vzm*Twzss^zlzy1nkVpra^dDjy5-4w#L)5Uo4ZMDWXY5Ok$6w|6VdP>* z+Y@xacF!tT>}m6h;>TCve?B4Rkdu$I_!DI+-E_(SC~ zxV3Vb4Ow=XPA(Qf!N?baHlx2_QPlJ6M*exwQ!+9^yNWFhu?(gME-Bl{g;MUFlqM-S z|AO)^h>kc*Fhwv;aFO6L!7Krlb3x@&P)QP00|dQpg0{DyJ%x|OSCV)HLP(^n=kY8H zdtTU^fne&X3{oo_8>V6FL6^R%r$gJuW+@a(mKg{eU175;m>Zj`q0g#W41K!7W>-L; zLg-Vl*FvAJut~yjDO=7LGNoLRjiPAeawR*pvaSb)RI#Y%Gl5trrhZ@2*+}4C3e!D? zO1h9Mn!07_q1&2~$>@1DVr9!IGreZK!2VHGdgdilI4^nS3!TYGvGS>+wN|hN9ZkVD zVAEM+T`#9>+cZ{6HcH{F>{4HU50CSGCfp-NT4xvgyA4xM+XZv$ghkJ%&8?!1)cdFE zgm}tGI?+Wy{7z&7ByRFPOR1I=kLCE?=-QfjBr%J351lpJB5ne9BhZEUlC? zDLZu{9ffQbcfQUp^o^peRmiVzotVzliz(C6%f$kcW|#YhS)q}7PsCttS+<@#ku2;h z7R(f;v45#v7^Ypqs0YjR@#&8k!I!u$gxgybf-l_QdoTJFOU!1 zPc?1>7GTdAFku8Z-=nf%iKw*bn@=@`T_xVx+AD9&V5ev_bCfO4Uz}}O)(pz=C7GiA z;6^b_E9IPZKkyS&;t8LDWL#)fIZ=sPK^t=}t>FBj3_Vv`bIxMk&+{&ZLFX?zA?Ht? z<#$VK+bVichTd5*w#p1W-8uWFgooo$TLZRL_I^i|`JlQv&~A>;Hy3o-z3Glqa@ATn UYIRLucb|i#I3NLuNP=_x2PdLpdjJ3c literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/tarfile.cpython-37.pyc b/env/lib/python3.7/__pycache__/tarfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7285919dd331136b5f4139409049b86248125b8a GIT binary patch literal 61866 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�g7vSahju>xmc|jE|kd ze#A!(uM@2yoQkWm{)$g+mdQ+T{CQ* zNgYYHMIMp@%m!^A?+*tJ+Jp10R-i1tfw3XoOe1Pxk!fZ)VtAXD8R5cfp^}SrDMWrc zaCy(Q5%^OL9R71&&nlmU2gMFngXHj^xZ?aLTnS7XOuMUloEHUyY0u%$s)61UFLQa% z%ZbGcUXeGR!*G#7{e^!L@B2xwSLL2eT>gS9zl^}RR0x!9zwY%d<-PtOXwe^<(oLRw z_=n@u{soj@3I&qZ^PPGyW@rt_7QnI>Up$m#tLf#Qdd3@A?pcB|uk-_C1ANH=f!=t)7psSRN5*M8BBI|}Q3HiG@_!2xF!>AY<_!NI3Go`&MQJgZ7Q6S z`B$DjV!VV+InhMyQAWu+Q%+4WEIpCEAk1nJQT$VCV4A32rh!~L8^6un7c?7%WaY?I z%*YF7n6OK!v~-NPGl5j`i^17U1Te+#erXypHVvh)1h1X59fI4%OAFcBoYk}kD#d0% z7R7Mj)qU_55GfEkKRY*x(Em2rF9`9+*bOiY?ffgxoKSzUFgHCl+pu9;^X=^|0dcVI zwwDCG{kl5D1e;7tV!LF>v0D|6$cacvMEF0duS~AM+{;gEah7ile66mhzzV0Avv~S2 zlaX?>atWXmp@WpOgn=~3Nuos0L2N`I#4cnBY_?5`^;lj`c_`+$p>ofA&R>|&V;1Nt z+j{Yg=xmAbgpz!PIsu2jX10o`ivNeEZFi6$({O(Nq|P5j1n2mF%tAgs{D_Y7~GC<)=Ka6 z8qSrj_SwH-1yy$EzDMUAjjH`4GH`}`oN`1!MX`2T&wf*h5u39*`{zo2L5WSPmv#0$ z2~)^uLAPi_~xH@hkZGf*AxG4ZSF}S^)~)-Mn{MZW z7y1?5o>bD^b!bH+qF_z?m+Hm>1rym}WJHz=ZeH6_L7kBgjR;0WG&I^G8e;L7<`}w{ zlQpIe8X^>=$a;9ccxfa_NC1prR`MSjBNl;}90=(^BGI#wQ6K`V)L;_f*=W+mIeW42 zTFD;I6Su!Elg30dBGRD(t^TpSV|x#rfT)~6UUYNn2A|-prJ4_bq_Dn=AGuFwX}a8r z4dP*Zg+IbSUPkQL^AY}EPcHW}6#i-T^bj>9vM?d^wLD!4ES+fGwYJCC2saVR7pK?5 z?=Zi{6V&O6P#;kLuO=YTkGQyeI9KOD?+^he8eASgG)N&D9B`t6ms!Rx{%Yd#z$^T4 z;LVEJ_g{jM&mkA)7gwShKkI5-%BnsHJ}$ui8>$`W-aP0vhljnrOU!`ART_e&oFZC! z1z-X3B$HU~SuQT_KqQb?6@g+c-lZ6QE!FuNuEpHH{9_0OdBT@i3Bt*yyk4PW>gnT{ z;j8aDm9-48)uo{meDo$LrUO~Mhxd43phj*1kM@;Zfs=iAKG8K;1N|^X3gePE_h4P z|IggVifX#qYmBnYVVPg(8?xlMQ_$DkA+gW0nUuwANpzv}I z-}LKD$lKxfh`DzYqt8tYPi(jAq-8wX@B5 z=`PVFns8$LqY2l9y_Vz-4|CDERA9;?G$6;cbn*r$xZoBhpXZwf6L#} zaUxm^fuu}*7xVrkt|PWa4rMy%6S-NOoLe(3PL8Qn?zQKcQto+j`YZ>J%_yhea@Z#! z${Da6yg8$sLCb-Ui*kmz?6d&ijcV(-$aW#p?;N#70YMI@?o%_V{ z@HQ>ufVo^)^qbqg&9>TVdb#J?KD}uv4@%pzIpN;6Ty%NLA%AO>-;4Hyy)2q{SS*ci zIwUCssl6+m0NmFNa!=k%U?ozxr-j#rf*wzBZ28Vcvt^YVX1Gae_G>K z0)5`SnxM7g_BA{7HRSg$<;a`2ues-9-p+I0MxnhKLw=MH2YN?~zzCgq7Xkc6v7~J8 zftZ&1rYP?Qs+kX~acO4H)eIS zsbopXn@av$l3EfhQR`8ncxbibN?uT+fDE-iC-Ehb)n3<`{K8FjaYM$X+V7~y?<)CI zlF@q|-npVezo6tQ2_Y=-A#OS{y{Oz1N{q8SuCu3<7;>xWY*fkpN~AM!$`WHOZ|KsL zkH!e^(PhK~w+jbDW9U!l#-Ee42SVoK%&CK?iFa{Scb--9^SYgxoSU2V|3s(RTEnaP z?VK;nKJV0;lJL*40@(P6m-Lh{q*LjuLG3g;RL6V&kS_B)EAzFJC4Wg-1+7ifC`&C9 zYOC6XIlp#Z%bV7+e0lkjVHQYbK%e3p6B&71=_maNOYul^F&=u@+;PP>JHC1(vn`pk zXy+N8kcMTuAyE3xz zLr@@B!Q-vNZi{zVP%7#)>2uU^#_yfw1cfo4ZOzoQwg8a&l#bHkJIhySqdnx|kQ(LT zp3p2zOO1PsJ3ZkYmdsh1AV9&ZhcC>9OX2~d3r#KCQ7}4Lz=CK~1n&hom`SYO)tj(1 z7STqk7vfOQ;-BB?TCJ0_8O9z&2|r7M6O?r!Jg%8&#*`Oyt8>`!2UT{1@(0hHJaO>! z@iXN>m55)KJq*bX>zQ1r&9Z_3CECa6Aang#GXnm5sp=*5yvVs$pen|kEz?T1M#BD& z4{S65FdQAIb)t@QoW>;psGY$%RfDif^kuG~_)zjkfMkg>*qT>um7*ZKjLliykIgxW z%{e*Kw~AO{f@88ZeaiJV>|^jXu18@&(Rzg;gshXzfhgYnVd(Q%koF3GKb??+ow2~) zY+(LX_0w;Y2tQHO28gbH@zkl4r-^n_HWby)mCecD;Y$Pl!7|G?X0MgSFquZfxV&hZ zguazF9rVE3ad1*`4(Za`MF{PdTL6Cj(}z z2WZ#?G{`*GTFc(~Ke*JxFNK$PVW}rz^LQFIFL!w#OkP3S3S;upm)X!v)4QyxoLnic z(sl(jk{iiNAIE-4mrVBo*-Fc(M@^UUcnBj792}YptpoD}{E*P;SAv|F0BDljjg9n? zv+O)T@7Mm41XIqRD7OOyMz@R=F-9ojNBq4S;oni=uPXU%B^`*-JPpkCC3}d#s2qBP!=Bj^`%@7rV(9gOS15qSfUg!ypd?F&ttTa=3dd*5_L6 z>pCU^lmTjrCVdHFxZb3v(}j0a{(aod*^+;bD|uN}Ei?=s#3(9|wFqI<FpvY)$SYjg-?3lQxtPEqF#q179WL9p|TbFuJWU$4H0CQPDGqR+;_r&*X zT+J*Omx|3z7jsBDq9G$oNC;|4aJRQkWI*M{p6I1adZ~!21K5YdW4#`o*NE(?ReJL}ZG4XMS{M)ha0?7I9n$-iCsveOcea13sYNSk~a zsFCNsV%LLQ4+YnWmF-p@TbZaFBXmdePBAUWINVvei@L(^awSSjedUt3!QNQ}d~rY5Nn|XRp^gr>UW%rg78eGF+?zBxc=)iUa0)*y zb6Abz<+v`WLpvK=fyLLn2jY5{-5>n$YxNI3F#1}3+zd;BvZh_^=w>EzPB~)~Z#U16 zmU!wZ9(u|tY3`-kx5xG^i5z2Yc8sw!uQeFE7R%p~`$MOIJY|#nyEDyc_6V;tN`X+- zK^+}zV6;M1B$QLMu_8n!d8=7jDaQ(~W(g-@z3Iz;%eo-gUv z-Aaxqv5E~Fc2FXGN8-yuiRXAAksZmhS}Ik{OYX9Bt};1PR!CG9hQrpt+}jgIcd$4Q zSg!kw#G>j-7gJJh4W&vPhfsG>8-BE#4579*bTd%!Xpt66R$l##d79@0eMx3i}1J-g^38dG*A(!&3JWBXzg@DAFo2^a%(x6y17^=Er$i= zruQskqn$&LXowwTg1ZCP59mflTHJP;Xt_o>Lqo5Pv_Xg9WFqh0-|!7q)+35ic=TmM zhBqyxG7yFDZXot|24aeDvcFI`J;POFghb1rKh(EObaLr5e;{?4kv9$jZ{K6w z$FCtZwy&LBT*Fg-yZEH~TS(;TZR#!6oMRh{TlUcYu_v|P%xvRnPQpjmBFS$j_l*0( zuLc;fwCgFxkR(>$GCur z%`lfRcSV{H*w+=-6v$8m_aI&aK7|3zEPg<&EHen+U_{%&U19Y=4(akGID+VTv8Y`& z3Kl*+>oNeXTDAjrT@^Dpx;0Sd;s@H_yNUQ-HuS2K2he8!IZ+Izz~ z--cndFGg~VTeSfZWH<%i&+F`~N`70(nvp6vG~F4gZ%~N++O$_$!|}J8mF=7h+_VP9 z{L{4M4vnESj0vWq79`3-;H;iQ90?P7%W>VmFB;bz&-d^%Z2C1$7QYgi%YM{G5lm_p zg55Y|DllU9Iy}zhqC98dQx93LJTn;I=#Dtp*Vem(!)?yz*=C004_(8XLY{wmb~zj9 zttI4s)^T=TZaEw1t;O%A{C_HVFzz+0+NI}r?*uNA1{GSpQUEpdwB}B`U5Zfus#BdS zg96hzCpR3LVtx$4p11OyyHcB5=rU+Qd~VHrbx=tc8)M#IJL%4@T+?StW81ndhWJ@& zG;4PlRHsK)DA7B)LS5=MRdRt?i?-9OaTVs*M=AUxORORy-)U+QCzajG#%9j*j{{JCrm|l8^C$?^xHnbt#c`ow_ipbo_Uz3A_D!)=D{BmoF+>}tQS~W&TshqTbz-oSWgEe+oq~!*bVOYx%$R_y zQLyEhr_);QFp>j>cGLW9#;Ko0VVbPMXSON8M%v$|?g1O(meEX(ICqTlX$vx9Pf*IvB)c{jH9&xrUYF7jT$M0KfDXv`;u16`Y&K#&4%noFUQ^y zeU`hm{!3z?B>;{-%d9Qyzsr{w^{cTL#Xbg$%e#9|JAdZY=gskQ{Z&b5NgLNLeQ^D^ zap&E>?Zo(VZ~eB}`o#~e|2FQt+qWHl))w@v-;dG&PhIfK>%WaV@AhqnPQ1;xP0n7d ztp7Idyvw&0jvYUC@-4d30CIXxs5J!oE`a2g=9m7~ooCwbFNAyXg}3O#0`Org%&V~% zMQfeHn_aIGMl)UH*)cS(014UslHImGiNe$7e(J3ZVmR zwd?5qwTsdhc)OOmH)iLW4c6X$Lf3_PU;D5%ui5V968(uc?fds}&;OQ^zfhuv`+Z9O zUnPI3M9U=nZ<7#4T>;;m<;cHH?MIfx%!3Dcvo;mvr9 zshmx}C{2FCmr&)4B{!bV$@L;FPN`{fz53cvgkRO!c_lR^7nNL6Qdcskq(ji{Og1}P z#QkgF$;Mf(3b~8~^=*BbfsB3xLfA4iQ0OO=-u}K^VW@9=U$JjP-@|?H@7qZ327>Et zFH9GD3*0MgE))p2hj&W%zbWdC{`xsPz_0NyY0pgy`qRYbN)wkW!@~W7;&8E_O?HBX z`4a=x!HFU7HLU?55|OZF~~+lf|kH^)1?inqhN zhgRI_P11^;pHF)CdAr_7vpj!_>)l*y8Go8(`kpQ1PqI+IitI7Q9WCTfPweofgX@R9 zhq=DTd&GMWb>Hiq_a5~gqwbyFK*V7a=hO= z!g9N*);;=Ri8QE$TgAjii{te)}Hj9=?1`FBCd&G3BKVjeP? zg7{^`3|E|D3tfo!db6T9Xj2zh+8-$VO(S^B1g3G@hr~R(rlbYe-v)jnm4-Kd6yQW| zLvoaF_vbUq1L&IvkPq)<|1aF{ECh{0nvsvRAZulsb*x$&tH?xWn`s4Omxj1;*26Yg zMoX6v1)x7jzXy~aMHE98FN z@8kN5TvH37)G&ZxVoUlzY41Z%yPB-CD-F5CY$e4^Lft+7ub8=H5NT9bzoj5N?2N;% z@?8B15-)4z@x0O1U*Xe}zyk=EzKcERp8L>yvs;c<4V9%!ce(rchQa1W(?;*ZdnZxe zRL|L(`%P%iU72HO&J*R$OMSuhOK7aw8wYK2qP*3252-nd@sb-VZH)+@9V+dZ(oFYpQK%*PEkf%`a&mW$vR4tAUb(T+XZX>X|Vbx_+$JP2gb-pxjlL9}v0O~+?K>72yC zU1OzlitV{e&h=IH%3uM=E`JxXvEqt)#o!5q&{!P7U`p*N?W*X3l8cw@Vk+sfQ#4+e z`8#1H*mcz&axT&(7Lu?bgS&@PQeoBP{}8J~&ii3w1ewA;5B;1YbI_cpX`QEVM1)kOEy3@x0qz(Z7~U|V9s-3L3y%1hu=v#MNu-4Gil|Hc%BB96C@r%3sMNwn9ksTZFIBuP_x^OLs z?)s{4^g-uwRnv>I+LO3yyZr?`i-nbB_w32pX1xqIQ}=&>f^HL?UcKhyx{N$o+xf~Q zEF7D%m{H^f-TXb(+)K4p+fsh2+U{e|_c^~>mIHqy<{hN9+omsQXT9p=!ufWQKA-b# zA4#_}c(ALt3$vJa&O;40;LzHDs^@fGvLGNr)%lVJK0~+*2XR`Qf#GNM5@U>hUT5a< zW`=&L7#)jcI*iwJxlhTPB%>RgHp4zweYNHT{bhB=N0dmacV1|w`uHB@eN@T!l1yaP z!?@{I*Ikh(zVTz?KR?MyqR*Ln*<~U{gfGSOK+>0cE{0!Igve%*BQBWs2I%~3LndO$ z;fqFuYn9AlLU#Z9QaRHXs7_}Ok@mnvzQ&0pc`vpTg_D#LkGf6S62uS@E$+k+p^^3{ zmP^D`UD)^vU$~TPupL=r2=Zwt6orC(tiEg^tQ0D>fDxqGOunhG5-?exlF?*xIp0jb znXtS(9s;Rlk-!{e>J?0)8BEYU_~PT@%aSUX`=#us@znx#VW(o2izy^DD4@+CB*-ND=@2;{4aVJO@7r!!f};I z!1No$hll`pMo=H$iy}L_+x{vC1NOVE2GS8pH#2PSCRDvT`dU+%hj%`LP$_YDCE|y+HrNg zUW`B7y#>tL&$#-;I=$HS_*?hl)hE{J#jfXX>cy^aUkr$Ro0hvL6RBRYc{HlkkY8qmL;M#Ov2!sdtFXfv%6Y)fLn#1KvcUq(Y2 z?+A4*g=i<3x&TTXORZmh3`?$Q-WoJk>7H@)5RUO|EZ5!KHFb1GJNU$##`+yp(itsR z$<1T+wv}9chkc{o2&Q@0mt0+Xr@e9O8s2eV+`5W)+!O0nVLMdOyR6A&TXF)j z!xQ&+X-Cm*ByJO9Ce;TF0P-iXw^(xp!B34_tWJ%D!gQWIb#$EF7|%Y7j`OpW<}fU# zHB#lZ2asjTA)2pxcjl;9FTetFZ=k9fQ*9lWg6;=+OPW<{P9xLWX&BUPhU}t?7?~0@ zE=-9EO)n4&@!QEKoZb5~yyq=9f&F%JDd+~1d|I2=ib+NeukJc_lLXWnCWJoP`>J2B z5wqJk5lRUk>f-R6BT6AaiL&GbocvoDN(^mNS`2&TC5M(2o2{b z)Xr(UsPhf~`}C|jyq%e5l27zB*sR)9umb;rm2*?V?V+N<2nWX0tLpzhm%MO_lf+KU zq^L*xShgpFyfc}~c&Y%a+HBQwiIFf2mp^3J!7eyBk83rG_^?JhUgMu|iwLlkD>_-z><#_^EP%!p4XI@sZpV&uAzSWIo_0#pdpZx+@&;&C7i zuaRHhfjmr)X)rOpt~VN=)&O)=*Ve5Xypw`&etfJt#TMjPXV7rD1N>5!Z+eNcS zs3>#DALB{6V1F`T|EU>K=?%(BC;0}kKupjH#er)I4leN|V*YK{>q9{;zZ}-0eQ429 zxmtd)tCmpEVD~7M32R1-%A?kvaQqdjz6p-| zLO2G3w*x^EzaMuH#G2h0^aAHV?EDdfyNs9n6syq;6492gfy85i#Ae=R!Vg8zScpL* zn(`P-cc9VAtP72^28}ndDeoHX{4IjxTWyRkGOY18!agJliSq?u_mBx|Awaq}`cmm2teTE*7`zdQ_(;P0B?Z#Shv__IB~ z<$MbSYQf`8P^U$W26aIV>x11-QsaLWuzNPc>Xw-h@IJRL;Qipc20Vub*O5a0|APjt zakoH&uxX0(h_N~jdjYFH4bqEX?@I!Z4(t`Q?|cXNzO1|dAi{lb2Y3HaB@OPZ+V$Wr zw`geZhXi)_QF}MojTq1=V8N|WoqOE3sqy#qI!2t$fJtC2#9+GJwhZq79+wd-o#sLW z{xH9WW)bAHd$;CusGgE`hq=}bFJCK(H_j<+UXO62;cG1Sk-a0e&y#_rn9*q*CiGXyP;#56{p8K){??Q>IX?ju7} z_h?xpw>jbnmey9NeZ91qRLP!XTOgHTv>Offx3SU1%*6o5n|5iA@(c41Hs>D1JVtO8 zw{{>l_N|SY{TA_UC*gpgNcK56qZbKS7}!|ah45>_;rzHp^7oW<4`;h4dgxa)sG492 zR&i)Oy{*BpL5#{olTo0S;%5W7ofGF)r%5)GY{2O%4yauzx?r;P>DU_gz+hyWjt+dg z0J&kjneI_`p=RP8W#ulg?nyJGp~!j`SW1;BCwxWsm~^^vG{bse3;p0<=Tk7b$#&(x z&N(FiV|>rrekw+N(D;q0qmW79oni|LjgbxsGa8S4z`>W0*ach0anv(NrakiOCoTMV6j`G zdqITY3(5awI&eKO^A#rJkJN9flf@8`u7V~Am>V5^MP~^FL-EC1k4PbW^go96CNdV2 zI|Ny)Hxig-8jHxsEX@$aDmElg%9;fvw=MGX;NwzU75sabSc2VTrxrzeTuquMJVI^ zW+P(ob5r*iRK-w3{4S9MqiV!@8;fJ!MzVROO)P3&fP)Id~*jm`0vXQ zM*k!+(q+r{(0;r`$~!sU$8i^HMK_y=%a_R6P0nZ?Pk$Y`zMta*nBB7FJs9J%?OX;PF8F3UEE=bvn`I^ACG<$#0!21-;n!w=Ao5`d1hDi3}(sbnUsI8 zV?l#;2Ss)+-w~|!ykH{=yFfkeoT$Kdo?3Yit$dUfvDxxt^vvVY)q5@GO|kMTK=NTU zD`54COmSUAOfhdXXW{tpvk+!vKXiE)N?%5p=^F8+h`<@gfUGDp(*^5=B%+HdxPV+b z6QKz_O*9K^vO8atJ=7Slra_eY8XonY!@u@$5cT?;F3hdNl;#zCN3hUzzB%WMKE|sG zJU`AsQuWeZrLb;@9*v#FTdeN(ch~J`BV5;B+ZiriTSS;`XXLAxaNwcnB72t4YgR7G zDjD|NF89i4w*vYwUfZtlTlD=_PxwHv-JI(?tGt0JjaUaz=Sr!`s=jzV=mF{N4k2l$ zD_0lCE%r}4JF5{h-&ChAWyB#ZZl{+lzASV8=o9`5xz1nXBiwcl9z~1R>iO70Em#@B zh^zDM9Q6@r$Klg&sPJ_q=Hu{BRLgm*e_C(V${`?RPVsfjeFQJ?^6@h`(xW}q#s+hC z#Icrr5sCV)I1Tu%!e?R%7W+lr|Umyc7nFW+8w zh10Zi@|A~1Td!ZJc^0wAF3xjtzrBw;(SjIj)}>~Rn8~}j*@^1ePS0QU+Cuj8S5?mg zy88vaEPdWb3&f4{zUthg8(+3oP%&X9ueiWR|2@s zR+tqMFv!{`ZYa4W&9W`RxtV4dRze{}w02f^?JAXl!FK8*>4#`tiKra7j$j(t;H(};a@T=>Wmi%%B6v6R9q;@w45rKD_3azs}0mne^dloBk@pTW^` zQ^J*l{1HTsync7hRjxTeNP_eX&U!FQc?A~;?~%)*`jug7{7J8X^CbZY>}^T^o8;d{ zew!Nb0GSyH?xa^XlKV|^_2wYAx#>FWsX{i}^1!~z7P{pWb6Xl7+m2L7Sb-1~_*kM? za$%o`w(3$q_ZcY#Q&dxEW?e46kF*B zpDwiu79xfY9o_73;bj#PDl=1y6I^YQk1Ee*wa`V(1WwDZ9r+T>W5Z`G>J7toqC)PzJ1!w%C^i`+G_68d zAu9Xjpnm+FV`Z~iW9k2j;yj`WPW`=MEGdcvMVK1Blj)RtA#s|;dv$LqtBDVnrXXIF zaGW;Rk1jrouXVr+TL7HwjowXX2P%Ut&a?PlF{aO&1%0&o_&y3wHyJ9!TIiKwmrfbu4dzk;1 zCg)~rQ-nmVU))owHmAl$4HK+od*ao+YYymUZ4Uz3k)SO#?ZE`BtWWscp(#r}1*3YsOJ@my4exd|H<1EV-lHG~4shq+L@w8fvdcu>_v zI7d+9P0Vb#fiIX$jchLXM3U9W5a5;I_g=gvW=V_>#%oyHp+^smE0(yP>@J4;8DZJF zH^ML{Abn}X5C;5XhgI{x#58kD=v%iz7{xF>Q95(6hMCJ_hcDyVTHB*LFV?kI*euTu zOm_OMk?8JGIj`x3Jh(u`P}r~OFt{FrNBkYIO{VNkp7(!_Qx~q|?Djj(u#JN!SA$> zE6(s-)jxOE2O?82xg2(A%B5Sq^!+g*GTIUaauD{4*oU9yf*Bde(#<5nlqD6Cx?pC^ zY=TDxaS*l9FwT^bI+hjuM1y6mYl?N-lqwS0NcgYE|8e~Ph5r;Ws84InHUFE69n{wx zFomr)N@g7q67c6$ZYAFwYz{2tLWM0jkNwRgljH4=#MvBBc=O;rLrB)N(qYZfTt(Kv zg8>HNi(^1pI>(sT&^X#05j2L7rHxrSGE%Ke0n_nrZkOkZ7W$r3lz8IKOqp6FeHag6&0lR2{W&%Am3rgUSj~R#jvD!Q zz~4w61P)~f6G0nmX3H!OVj9TkY9;%mbTW{>yorS@nHlU9UiJ+ZJADeEq?Vl2r;DFl z(w0fD6F`|AZxwJ6wFN%X%eiY1RXAxyj3YM6r_x65`$96zbnFk$Urt=Uf?;<61My$5 zxCUK%YX{E`dIcuV*I!T6`I40(ExMBrbwI@7yO;AH$!odIsxB^>iBMc#@XDc z(A8xrN*ewzkrSzVITw&Sb+6DnV8VrM)@>RK5Wyk^*37y^si|O@?1>4 z8}ufS5?AoL;#7z0j3}p?;mB_<$kq|&oefrdXkEOEW@Na=6bkvEPBw3cI4kD5tR%7Z zGHz22(MqB!UjU}s*#$w7t^h5+$Q`#9o{pG;(F`G6^)yIb>tI1w`;bSiRt`evwz z7n;PNmK!qaBPULCi65brizV_bgzj>-j$B}9DFa%1x|ub)3nH2!&L8Ng=bDfJ`qbE+ z-hk6iiPFMn6YQ(m2ikzISg{XSF z^#R<#qp%_W#t66UDuvRB)oKbz2=iL5dMu>yact$J3vHvl4q6KcyTgHFCGl|ay>v~Pxet8AAI8zPjvP@lyOv~(`Q86Aa((}Q&5uy}o4=*(fHcZ0*?Rjq^0%r63y z)4$VfGz6kq5`->{qmkA?45z@ZvupHim?1gns-abZVW z#omc62&=GuqnXxUz5S%sgmQDvStf3pJaJHQC2u{C#I(C{2qfHibZPO#m3VDV*heQ< zn;Sc{V7vqSB59|Q&;bD`4^66LrIP@v?`#z&ymku(QMu?1&ben7(z=LtFkq$K=o&^% zO~#iSu5sTz9!i&MK=**)_XY!M5g^+|J>s5lP;F5ojFQX%>~s6w||*mV&__qyDkjyCP>ZF&L2y zd6wFMA(J7^t_lMx4Unv?9JRJzk@aD-p=G)zE*xw9IR_Sv-A39JB#v_wBwhgCii#(I zyl5e?L;6!!P;KrgU-XFb{gnT^2A`%aBO>gl$sHv3i{uVD9U8fdjILD>f6$Hjh?J?b;gMVeLNiB`9aR zi=HB9n{wD(O6zcBOW=87@P`!I_zrLSFr8M2~v$AZ0Cc=Ec8iu6JlJ`qZjpnD znh>YSZG<=tb;CMJd#oS6noO7+XEFgku#Azh-J<(7I)Uy0+D0XlHo&oDP%*DA(bHbtlUmsBOSL0n{-1k~e z)-4`}qQ*CZh~pfb9y${*hHCDi4XyWbOU-J!arV=Euytusfqa=4K+G( zQTuL!4g!qn>+~n7RFl=d^uwG)UpiuENTZGIct4@rC3a7eDGMbQC+R=R4%tYfCz;k* za&(^8IsJpPE!WUB%GaJ4Z^HmiN-uD9Tr;MPnl)`5pqF|Kg?GRhaSf7>lZtir?qpT zUeTIF>clf-ZuScMI8y=*Km+SqXb%`?pXCmP>jT+B{J##kQTq)7sD!;y$z z@c#ozdqYqdvLCDtHxHM0HgSKS8a^w?*~Uu}S?vx!#5SBmECGQ9F)2~Uj%%d)MGc5t zBZc0g$^3tD5l!Y_6%egr)WzWZt2T{ME6rq}x#`C1*S0jX{*%qD%*@&xNKw3(Gl0zq z08s!SPCI~bAVBFJf2P@^y_#UXU1^2<4NHHttMns)aUWp(WowI^DDgl+j6`|m7-0F0 zNTdv}sY!r1$a`_M)4%3Wd?A#@*T}cNc_!2|8%#tztyDI+5X%Ra{!WIhPS!R0C)~3$NUuT?k8u)QEuh&)BnD@UB zn2OhQo6h~T0M>b3@n+|rA$KhQe+zHSU)7BV^n}fa|E#;lXPdsns8JA>IAU!~gVRo) zZzmVlVn#jr&jjDQsWFjr5qPxAKn5mez&xNjXSie#nFna^EI^P3xC>uKp#C)VMWFuw zHFj>Xahz2g-<`d9ckS34=j!I>q)l75*rcr#RZ$wL4YgWSxlu7qWiE@|agw@@oy=|$ zXRzCfC|raJ5q&^N1=Zn&S9s=yOA$q?1V|vXDpCak37&X>7X*dh|D3t3T~q4S9)COY z%{Ski`7Y;vPFx>mK(R+_m?y-v22_~=^>8wvAT#roE!n*v)qpZeaD#$^Kob9FY-R7v z*pGPE``(58MyB9M@>gMeitQdbCQEMAmSb|$#-eL}F7yfS1@`p-LD5D8aigsf^h6JW z+JjoenZ+5BgedY0!N?|aPpEn+H9gp&=p&N&C zRy0FoVf>~nEAw^PY|mI(G4!CF_9kvioR!6Su|0z~F!A&W7KB{nR&izSI{UUM1{LEj zIE%GSwrBqsc{*}}_!u?%qaV;0asnZv*Zp{HE=@Pxc+lBqdhy`eoLC*&F1=JT>HNPK z|0oV+!;`f3lv?9A8vPH`p7a1b3I5Prv!CRBnDu2b{d({84er#mJ5Bol>bdSr>I2PS zTA-fm3!paa`4sany~9f%a0kU09JV{KP}!Bu52%e^;Y{H&_;70kdjAgh*+I4 zMRC_EQv#ps?>*x|w@pk93zDiIG_rGp0k^Q8-e6te@#wOpV01K#(!}l}_fFRM9+&(y z%G0Pz7p-{&_0(O0-r3}uG@JTV=cLR`5X~kc^4(X+hb9vq?m#9)?S_iTXB$LZJGOH4 zxf2L;Y}1Gvo@Z67-1OLP7oXqMlrr_cakoEW(0d$)PpM?=tgT5F)o@q!M6hf_5 zDzjN=-IK|zJh6xQ)T|_9TN%X2U~w>d_JGRmgQA!OVKma${lm8a-$>Z4gkhj#)WQMhxaM!ixJuP7%Y@eNEtvIA2{t z!b$!wNGtMW1Q-^O?&R{xL=7LrYm*3UQH!U zS;MO~*&kykH&)??tC8Je3tQ;OEX6J@W2~CDFoj0rHaM4MbVwc{qZ5vT2XeVWkV{4= z6LHhahORp9%Wbb+omyAT*+nIIwHGc)bGP3m^DRBYW;)>8R2Z)Fl1-dZA#5>v5MG~| zUp9GJ@JX5NbM6b5Ezbe{)7M_w5eh3}XY|@wh|TvfV9K+I`r>SM!KL`Dr2Wid5=EWA zV6z!(2IOZM;%)1f+I?|(`NeFmieKoR)rpxz4+^KzU1{9>iKD+57y^*04^OmY2xG!FXg5 zoMbUcD&|;;2aqB&2t6q0R6H^#mMm@8uq&!aTD*$;x!xAW{wxp)yZ`{PH`DTFWWE71 z9}+TIEs$bVnfb$>u0Z{naG$^omlf)0uG^6L90iyX223;&V&#T(gBa&IPc0@$@q@J! zYY#=b!4b3>Bs2ocCf$&|E)f_!dtZ$VDRr!M*^BLsl-WzF@r=!E;giV+>7LGPV@wl1 zQKApTAfa)gKD1yv^b&e;p4zEp$IKKP@8Q5#Qq6{Vm)fu;V}mgoAnwG|`rb#ty4C@pQF=EUk&FszZL2U0yy$87!65Ayh#YIBC#PT3U5aCzQLZZx-B(Eo*l1i&ZxY=Oo2<1Y%lU*0IS1`FQw5)9unIhpfw3RK=mH4hR9xYqz zwDNMzVo#i?4f7#C<$T$lJis(4)RyN9qHVCYLdbqDmEZka=MBXh>HKc3)zUp$t*3?7 zySb#`DJ#omVh!1vf!0_m2YHc{fmK#d)=Y)=_raeuuz?p4QG1$idq0592yDDqjNk%D zO~PUl7GDh#Bg#@daaR8Bh}DQ1dtRJ$;;_JkPrN74iRVv_;ayp)rzDmZpH-&$k+xI$ z387+*l80s>v6n1%OBdVcHxDGy6H9txbyVz4zGchYHXAKe%U6F<^uG2>pOBh3X>Gt5 z=_V&P-9k5}Uwgm2PHDoy+gWlPxCt;=3*UIK&7y=F)dIk?kmt*Fzseb8wo z*#k{IuiYz+ZS$aDQ}$=U+Erq;Q1lat&+WfOT-x#nRaC#o0z>bMy7FyMs{dc51rAS7 za%xhi9^NW>gOK>q$G$WJa@6L_`Xd_Mc?La zoz!0LyBCe^_5Xh&sl`IlgiJrb#;T>M3K$=B;N_@&zvfm6SK8-~TLuN1x z>EnBt?|!}q0%%{zhH7mWSsWU*Y9nlpHXmw?H1BQRT|2~8$2i&~vqP;mM23e0WO(SW z9dGQZH5&EWj@luvEN2r*IMwE9<9dR^btL|)>|kc`UDU|dq6oJoHRQe4Ef!%*=;Rh3 z=Mrv7wvM7KZ1*t=(`bWPZG0JdWxfX2vVG0m9}-zC?gZf?9#iu;UnMpeqwd3CJKpr9 z#;m&Q^GH%ohNA6UKhx11(}ra5Tezu-qH$J8=qx4teO|xyx1BE){Lz0)%c#H#i-omx zj}cK-dR1;a0s9U1yri!n2pFy_71kN8mZY)Zyu9cFC9wzxmApdcc6MZYIIM&fN>yQ3 zsFqSz>xB0si|v=xKlf#gav&=E<27L*Jxu&S5{EL5-=hK0CMBw{jp(C{F-(oq@A z%NzmOXx&Sl#zKF1NNYHBZ^2!6xOyOZ57J~*R>bb@N2*?&)WgH!5kI!h6$l%CN!_93 zuAf#py(_(#>@;PZ5#G5Te0`@PI4=yT zqoiEBNV+`56~4%9!y^%ooILM`BojNs6# zcjEfVaMJ0P z78Vbu;zN%oMy2V4^7y785N%EkdRx8J6B9X%huARQ7o0<}ikqG))AJ0chW;(YDKkSk?9(eBS5j@HCDZCE@f z+%jihdQvuK8!I#{S}Co(sqN@4Z}BMqZ0C;m*p=yR6MW%y8sES52@Q?qQ9GB}m`r#) zCxvpdIBDc;Elr${F`_}R|NgXgK==}M6}A~@o;|EL>)LWw!d2g z`IfJW5P*p@|Cw1Cgm(vU@@R1u=Z>XLcfWpJywbUXe&xC}Z618QWp?!4hBcwu?QU7P zkF+27_HkRt$%xaaqW5eF6Is$Ni+pmLp`=TUQV_}RiohzCz%rfbm#T8M)6#%8lA>Gn zhrq#|2<<{TW}}xDp`aOXqCU{V?9{FL0Yn3{XNo?~iEdflj6S1#+ycx5opaGXRqX@J z)EHJKLFpD--4diA<^2ON~mR{4wsI9YrV%i zEHEtg74;I_0mC9YsXGw#L`Q`a=v(!z)f#I>SLmAg^D5Uev5;D`R|ts?!QSm}wLmn9 zkx2>Gt<7D*5f>GmzgaWF5y#;otly~goWOa3?+Z)|nD@aG8U{ZU_?C`I5f;6s*Rf-2 zx$~sfNsY7l&@7{(f9UjWDt7BrOny5^j*J$gkJMxjsD-x#j8HA9@_YKp-du?OqtY&w z{-)BnO6LSZfeQi)0)N-pMM^WZ(@#%LD|cK})d}bgq!a=}0^0>15m2ItXi#8CpegXE zPRt2BDDYWQWntf^{qlQT2t_y}ufc&I>nus`7=_`P4b$M<9A$BBVvFL3b z8Qf^68@;PD#w^(Mv}vv3;~Yp%1X@XyAPz0QnVmYwueOj3oej%eu4qhe`Y=WnaZ!3T z`;S;MK>dzl5@yuuR&=dc?xYoOOTW{PAL)g~a@7Mpz^IqFnlJy$0~M#`ot|f&1<>YI z==Pn12Ws1zBelL-U$eBur*ClY;LC+;&4bMg!~M;d3+ZQHPuY(hsr8f0lMzHIgWSkVuevQr5Ws^8R@~TQXRsAEb%A+c~NmWw* z5m)I)lJ7gWyJrR(P?Qy*rlg!)yGK~MshvaV*H)rq( zMl8edjI!aGp5@t|<7K?8m-F)8kXP`Ay%BG8akOlDW8RLsRkr2ZDQDz6Th7UMzC0w~ zh4Qd`kCaF8JzgJM-BBJl4Jq4Mo{;ZdHDThsuW6P$lG0h(BE^*C>N#8 z9=!iAc>hrO;l_R`*^83@jgm)DlK1ZO?tjlHKkV)E_T&4ocfdP{??=4{yhHeY>{Y{i z&?~-Yc*R>*dD45xdl;ohyhpsl_@451xQ}~}dXM4$32)Lng72f=lsAO$W8UN52)?IL z=eYNTH;nre-cfH9-%omHylF4_j%JL?_yvbcNNJK;a*?O3qAC%qh=pTWpac~4{H zr!n%gczVWr7EjOO={fJ5_kw4l*7I1$N$=E({jnMRTim~}e9C)q#roJ(f9OA7ezCDz zR{YW}%YDh4@m}^Uw0RMIo%U?>Wuvc`@$`!4;K}h%-?GcEcss5bQ|H}Zunl9*Uu`v& ztJaGPwYncn7YcJrwV=4#^xAd5*iy|KHO~){ih2u8Rj4Z84Qq|XV%XoeH1lf8uZB%k!&t@Q*?PU$TquT1eorTbcvP=A zzm8Yk*;L&|ao#Vs1K%sI)xxD_J1j2vu3{Go!xyW~hF1$~%|=l0Z&v*lUN=>7a&?6> znZ$U>Z4sRY?fGR)r5HB1Hs(YN0lKey#YQts#(c3@3)wK89y_0Rt1D}+@-X&l3(KCb z)obB;vDv7v3oQMj=P$VJdRWBUrDDTf1(aOn7nL8jRRb$=F_lnZa+em0>&-Ui)oRt( zvG$NPgF>y*YKKRQEy}A+* z07s_e)sbh87AKE~t1W)QR{MoUt#NWvzuVHxlV(ACVWD>O<@w3D(tO&wHD5cqaAIkF zvL9>QdeBUugvB*i0R%U60X}~I-t!b2V>OeMj3&08*anpU-aF-xwUEPgL zXrZQpkkbM>_4n&G){6?rR%`gh1=U>bMarW@iex8%e*wrv$*ykgqls0kB5>HN0UACi zsS12)HVBXa6ya~Bm+3+@Q3Aera|sSEKxF<=myx*~@R$#wQJJs;*zFjh zxl&L?)8M~nUNNp2o^?g9%r0G=o3f<8C^viMf>KR2Wvctpi!4N64&X7$Rs5T^APna4 z5QsKlTIL95leN?#lvVMOKd^j(?W_0>zJZHpZkjj$OvgBHymM~T>R6t+l2`X%FJP8d zXhM#j?3kg2vZq4Zvu>I1njuXRa5n8XZ%5css-@I#|z?y>affW^<(o z5+>b;>n&24@H1B}g2h3Yc%)psTk=7%wbfRgBp!1+HkdALJUQbwCd1-t?PkIn(XP>K z9Mg;vOi&ms*>JPL9i0YR6ly`OfgNg8{U{?9BO8<-4b7ob4Np6AIF0hK98bY)fynJPEXOREdBB|4yp^?h#m96^^(fv~33vVxOH$nS@IY+nm>uhu zy$P%q*zNDww~S3-ygZ%i*aGPjp|xo=3ZZ@539UQkCiX|(UyI*g4l`(FHL_ur-@4b1 zz2IOEtc@3Dnyaf|HZ50yr9fVjK|^8#K8qqHSDWB|XWzIKP@eQi-RaU)PL`k^!fc~F zvA+)frFP5XLf|*5P4K*7JSu9N0DCs(A6YFrBAa|;7#tLmOaQzUw&Rt+Z9sBw_!XI8 zpwLl3L^rGvKru_G0+$84gs-WN;$4c>tVjr-!6!I@i*G=eHOhbxbXlwH_!;WF?}6^h zS!%w}&~ns%@eK_a5Gq8wDw=1JA!pMswfz1mb%%R=9iZlGZ`MM2XF z1SP$TRi>UTGG>=-Vt_5Yd1kKC~dIzJpBUJ`iba$08 zsY+p3TlJyIP{0maImX7+A=xq6rkXB4>dsf8@hmRYmRIVljb`gQq-y)d+RgQi6Hh+% z^fS*s_x#BhDk*y;tIyyw!;RyXlGWcK@`LG+06gQCy<)4!LXbqqs5l@Mqmts%jd8KqNSUUtcKas%^!_Tk+9G&5t-G zVWlACaY4e3`v!nu8gmi+Yw1|=cz`LJ9(bmE8l?vfkseBhN146_wHx3RO zDXEwa$I8Teegy9U7~?|>x@<06ADZtQ@0$yt0oVk2@M-&&c^(w7X?o6W0P+sGbEeeS z8K=C9osqg1(a}32o8|}R2Wa*k>pEcGojm30^a+@V?bX$FJebueTU}~G;_5n-OP>~A zszWT1DWCoxyXAzl#>R=kt84f-!%AiPC8|dC;52TM#y_GAjWFG)&_#0fGz!Zcv_}4} z+{U6GIm^vj15%TaF6ZjhXH=lUZ>i@{sGjFVq$VJ*hx~aI1suW3AW7D{K*uyrzb5Il|&=Euh#JVbU zjNAC8+C(u8WeSXO#Zqsh+`&`kcGk1+K)J$Q&U5aViGyG<%QlU1*3-^{MbtBm^$GR} zdd=T4_zZRCFw~i$u&`i3rTIjwG`i06Fl)SJG^}fyB1Sg8{whsMD#C7&+e{AGRgNiT zv{?$#kr<4cS87%S>aN6=RVCI^wHh9(_30_QoP|nz{?g^LGk4+jH_A4iBC8Q@?EdE4 zXIriFutwf~jY#(P90uCh`RJ9muAt)O+1a^Aby2Q*>TUMBk>w4(Gy2hy2Zy%PM*jE> zSH*YjK<=hSx?BjFW0ZAU&`G_>Ax1=5;I}+cRf%AuwxImb5K8XRUl5UlRoA>|>@3(< zZN439O+`I`4F-v|6+kj&M>%{EaOE5ZlI~f;n=QB$-B(Ego4~5VmcK}}p>}9Ej$MH2 z;uvH29>d+ZHEvtx1ph7dRn$mvj#NTfFF5xMcwJ~f-GCZPmE~je=6DC#_p$j-mRJ{B z%jDirU6!5O8Dih2b@Rtz)-%b9-uaK4c9^3wya|;CHS!&+<3PpFtV4agJ=DpB1<$%; zZ)P`M+IT!1ULNWIN9nryw*9l?o4HQz_J}9gdDZZ8Uo|d6dFCD3j&`IxeIDy%h=IU9 zsHMQt9l+2ZY7BkLxPA&H<0}QYR74Fo4a{bzmj`uxD)XA)%z1x%m#k^`9lTjP^#(9n z+U}9Idv$-h^cvn=HLmXlrR@#xTfW~L>X>_tTh_a#m!rDjUI*xA+g!=b%x%TDz(prcKxU<9=a2}HL!0vr00Wg`yN`&(UAZrQv;p(jhah$k#qr~xdE=P z8x!ftKg7OBJ6dg{OMnA%0j4N)OK-y+^;%;k+Cjtrf*5#Wv_w1J;2uJGZ#JYr(VUAi zwE!~&&k@i@&eh87PiU^OlO2?r;YChccag35N;R70?1j?oh0@$qzMK)>p=LS1$Jw6^ z?N#@j=g!FMeSBdpw6^k?-IW0x`L|FxIE9Nbl!f+A#xjCy9xTR^4_VCp);M&02hWZ< zZts=yEEKMBh+@lBK3b>Dhh32Y3G<d4EY#oNOr&L+=L~R!JZKem821bKgp{Cjb#P9UA^9h zxDtGbatc`NCfZO}#*5~m!PRBU>@=YFBpAcRaA@vW_!MCBsAZH?sU`ETfKMv(|1}WBsE3}uLPUaT4=*>^U42(f?+V5^=!D%z#v^l)bgSXP?%-simc%K1|n_r)R zVOi+pJGN(n;|@WZUj|nk2A^zbzP5H4^7}N(Mo{)Ex(t1diWc#G>2<6FO+exP_71pf z?B#Lr$?vZnZdmUovVTbG?d;_5Kry|7?Fom&iRE2%Q-d>7r_XGho`F3{e=6-&FqPPC zb+kxXElL5g86HtkU8=(FyFBM+iF_$g9IK4=um%xD#2k~44Zbcrm($0p9#=X)*KU> za$v+v&~9#_ULQSy8FtMTp%8Q9*c@!aL>_5lUdZFKtdM?u*fo!#lb&e`wu>H1RNaFi zv|VHMjcg|)kKl%eUufL|0s#rkjpx3|4Cq7GF7PS4XZJYvz)5kuecMdx%d?k5XNCVl ztR{k+J2_3*fjyIpC=#(+4Sandqzij-O!FQlJG);E;x88O(;kDYd zHl2>G4#A6Bz1hcx7ut<#;w|sdJYpZA3+GA=Y`m)` ziIO0zqneb2TXg7zDuxSB81$PX3*J#-22)gr;DcX)R7Z?rNqbD#0q7v8s#*)~jc(8e zk*Q`dP0_9S5czl9P_!66$2u3H50lytHpv=PwMy_%YRyFkkj4^2fN=mT25};Zc<5F~ zWhoLpSgUDw4d$7I92y87NPMPeG)=IdKia&%2o0t?o^H2wJa;Q2z#qvwq?W+nv@I~wESvqf$n08gHW}50gHCrBD|zViY5X|80$Vg zXmtSd2zEMI-<0T&vLk&Bp`+H8WF+BrwxxI_+7ye@G?;e#5vG;v_{ zT?B(VEEQg)@30@S;u+2XAPEfUE)*q*GoxNA4~%W17lBq9>!s3EymX$Cw`4wqeIIzZ zi3p#js%vq+7D_y@hL{+FVO^8Nm2Q%0_&5D(TgL7o8i2W5&glT$AggJicD9r*dT197 z2+~>ubPjVxqRZ8#THV9`XyXAjVyAcv3)p86!9+jh2M8+!HF|Ez)x|;)Lnr|k*hi!2 zVFsF@YM}x|CwnCOhZDShq`+Zy+`$6;GL%R8Yn{^r`r9-R^PGW5iet$L#SQ-HynUtUP0 zY=-9M07(JLlF*V6QEX&(+i1`DS+%Ich(dzUMu;P+-Wum32;XCGlbU-W#w3k^UxKT| zPMU5ln!dVU&L09Zjxq>b*VO0e-7fp7<1&@sLRgxl8hoFs*{aFM zEfhv2<|-+SYOOK48+voEUOm1=ug+4hK82bo3Fh#?PJ{%%ftxs1Hzvj!)Uprqc&CV6i zT`0bJ<-+-x?nT-Nny$Lq*M%eqaR07bD^^@|Qjo;k8Ppa{poO3Vl62s#O(Y}ZW->YE z^gzSLgvDos?ox`Zp$VIFkv`QCj9grDZ$L;Rg$nY7ZNsK?BWwst@RF7*rHzLN5gZrM zB{g`XMT1`k25z-wh1@Rjg*c?>2G)etrJvkZ`nd2UFcV({EUogX55Vi5$vvBw@#tdzvsT05;#@gKilsT2`$Uur@L+2x`+wZDI9QPL6;4PR(U{I2nBmPBQxF87o8Tq$d;KfLmxe_Rql| z$6B^}j*D7`YC*r8EXRTqG82u6KNbNCy0G=?=nB<~;Bw;7o+`7ne^uf%{S7XN2EGw{ z5XXRY8~X>HJ9|Lv%D4k9CV{po18ft;Wvq{T{W~0AAjBZz02Bl;rQ+am zxgr1t8?S-a1zidxTdko|7dC?@By;_z{kuD5&VePo!q#VaIm^pAUIbgD+Z%io<{-!; zV3r-Y$roLK%bn<>Azu7d4m6INyp2$$=~#t)AvabiIErtp_@sX}?#|#7aNs_gAD0{r zvn;vEpy^DUp^;_S5zjg1DdRg2t}ur0A<1Li8SUu@^Hs&5o7(tc3Vba$)^vHISwX9> z*4-e@=cG>{u9EO-5_f7sLZ#b6xiDuSJ1$95O;}?jM@c$h;QK3L*SPJlxe5c3*qn%z z)h5_GnYnNd(W`V?DeM;}Z9w8QeBYxANK>kxEs!+`TR4oH&$0!0QjkdmJ%UWaNzgXa zWfGcY~*OM)kH9G9)1~70;qf>4hXg@0jC9PWNibpkYw3^lH#(nabPgS z`$Z=4o*&XzKs39#oA5@!slXJjuVL@6=PC0wtWAM+EWslOvCXZy3X&D`f6}eb0tL5c zGJ-ZL>XP-ycdl7Io!bA0tN+pjUMmJrn8yd%){F~gj50q*N{|jqLagi z&(5rY@=PZyErvSzTbZ}5&BEp|yldIzTn9-zWNfe=t#4;GN5JStI&in#0+WNIWe84{ zk7B2a1?P+;*&s<_xKm)VLlSiJ$Pyj*_pnhjJer{ms?;FtMrTfc4?2xa~abK)C1{ zi)jbCq!=KEfA@ZlJ(+YOS*g8!Bn5ZxfcB<73NhL6*NC9$B;x0LZm-pGX$~n5IKY%l z#6ENn{n~@OMhp(Pq7z`u!HFF&W3Hz`Y=;xxv1jQBf);W}#REv;ZJrl z#KEsKGmh13E6no*8=;UN#fFSv4C`FPe7jI0IPqw%O zCHE)@QC;PQvP~kY<>A>1v%zLB;|zkhUez_eV=jhJcQkqq@%jsLatJXpZDI(^9E}_z zvHF-*{{k=H;icbitCg!K_(I&a61q*L@m5v?E@R|DlEOBP33zcGgf+bW#>GpoU8v^J1OI5MqzvfCco@Kda$rFD5J&FT4|k9X zy6l`|d_J?oI70?x-_C*s4N2r5xq*$x!CZ1+F4r`3@hsPZANL$e^C(@`r6@UZ%~;nNg9IKb(Kt)DGN7w?p zA#c)-L}5ip-lwkAM3jixrJrFwnxC+tB#c~yA}G`?giR7JO^tTBNHkta39oW>_VQ0$ z(R}4Eq9V@bRAw$;I6J4ax^`X)&Yn*WUFqzs2T)7%8gdiOddj#1pQ6I>Icz26DCMk# zj-Jv;;}49Hp>hW`lb^Q;AFe z$WYGU6Z|h+`mA)ErtqE@%iM&8t}XLyY?p7?a` zUYyQ-9An*w6S+t6eLw0R^QNVbeK?7G0%iNXlQ@I>6#Rz=yr;cqP;$_F)_V@$4|wpf zPraaQEPLY@273_Tv}M%Utuv>PC>B7(;y8w!4LrxAn3rY+EfEB|BIgV*&9a({Fd{M- z`wV}2%YB^5aEn!>hP#MUi!%Ehq3sX4+R$|t~yhAKGvS>ejzmrzam z{-TL~0|b0Km>LojH_9iqdj{_g*_{Rl-zs-$6l{=0CU9dQn`R`#EU7FAh5s853_4Hw zS(gU!gVZ*Ij~rZ~-J=Qw67F=${gIA%Jpp=09f93x-|2BCI_eWNRd;ZS5b&+nqdXT5 z?+}u^dtA8RXRUrRkFu5Ol3!i<87`xM_i)G<2m-_5xp83d^re1kb8_-Dt!45h+-#XV z60sIoW`ATla+C~yXX6_%LwIcDc1Gv><0*@$+#O&SqrV>g)7sRtOM;q6D%FepMGT<` zE%n!Uc?*{)4-bSktZ@{_Ur~P@g}n|mjRQyHVzHmyTnE!!8Es3RV$$YdgBMu0B zh*s*)^YSyi^rMs*$G^<^uw$G*+KvqF=Di>)5{`8GXoEkV#xr=a4IKFDZ{EYW`h?Wr z{rh|nZ13{;)t<5U4}^ce$AgH&k01_ttVW!^<^Bqaw^=S<{aQMtwGFvyEb3cq%Fa)s zhjlnSiLT-W;9;AmVnv-X6)^RE2AKVkcZGyKdmlCS26BC>lt_Onspa_1E)xI1U-BPi5}KSBq#*me2O$yN$@2>6_NL!hbpY}2b>~@ zG-6cQ*f$VBG^7Sk^Wj0$JQ(A8cY@-@6*Lx|m~-0(a(w@9?r~bQCk9XJ{~rlbhl=4E z9U&E;Xsb~DbQY-1{3(sLFX&KyY62Fc~{MVjI3>M>Q zSA%CkWv06e-I#MML4SbPcbfy>|F@nw4BiMTTIuljAjzVkpt%s@1XI=DhM@i)#{KW< zxYjl*OxjD|;Ao~L!FFs=>x6@4H`T@enGU=i=25RsqmUfWPR4u=H~6^)13zIQAqyR- zY8-;Q9X~Syh5fNaVdt*k=SOgkw!14@YU0Nb6e5A}sEZmeQY+phoG*tlvz1)_J_h|` zPMRw=AU;Rr7Y()%pGoKG0x0Ct1u$WUQ{yp9Jw5z>M0&(m!k}HgNR3%vSvaE@O-0`VUb? zsPs?w!GV&dI|?il%6;`$coE~dgg?du4-E_@eZqPYPa+hxe)2x=KH!B)td1_#x=(=N+&%u3W{ZlK58e)X_!u)` zuDdu?=6z(x)!uRrARSM7A|XS5PYceJ*ic(_8!l2R(BZ|{rGitj_yH3? z{+%rP|0F(=dU{gV9il57UJmW(Fc>TIZ+be8wY-U(aQYYZubp9{@vu5gJzb6@Fyaua z!cPb>G|O7>^rXM-f!GRMwLGK360onFF8QhOX;{xXC|$6Qcwk?3P|F&7TqcgqI@38S*Z#&cLMImPj zhRXNhZsKwQ0sLkZ@1h--{h--aRsX6kM}*0))&qU6@3%0-*6IHflV}KmVO2|)mh0`Gu87z{S z^rHM0k}D2ze&7yN%mxEi*Xx^IYTFV6FsE1{H19H^MAskc8SLP|UEG?fK{#-BvW?Va z6Js#(VaVZZU~0P+OD**wYTez1akyt1gV#L3fq^z%Wa65s45+<=OdzXX!JkpTgUZac z4Dkaz>UTMz-{WQb4N-r9_miBL;0n=v{{R5Rs4`_!4h;_!LZq2!Snxn6lq#a3`WL*s z&x;5n4%dUOU1`DLbDReyU%tTPhLMbx1yc@2MF@mr=ha8-Ar*>qUn%c!XYFhdiu#WQX7%yMt#ph*#mt|gBybSR|Y}RKyCH;Dok4#F^ zY&FNbke78{NO6KbIB&lm;8$YsBLw8C+F|;a_?8G7Wpy}Tgz2FDjq)$SlE$xgp1vQ| zgKy#D*xIRWiEA550aVW9pFgX`?Cc33WC3v^UJ(ut9#m20sL9fySbRCE0k(X0@1XgFr}fcVh$5 z+6yzciCD+(9}p3Hne$%vFYF(v@M-tNUzpQowgh-4c4FqV>d;rOtjx-+>g<~B>e3kg zUjO*7H~)w-_8)2-{}ik|!@vDXVhk8(Ab|`%P}UVLfuGBuavub^0zvMF5LZFt0SNOT zM0g0gxCT)kh8T}PH}8ToJPJKL2EDu+`uG{>=RGjMdts3G!4U6I*LomXJ z;XFSJ7x+22$VVW~&%-5t0Y>>n7~^rc%rC(>AB8J?46gFaFu}(m!LPt1zY5p*1YG9{ znBtQ#&96a{Uxyof3U2agxW$ujo8N#t{3hJxx8NSX4fpvSc);(%Lw*k)@%!)%e*iQ5 zAw1@f;0gZ*p7I%Z#velpX1`&cni%{8_RJX6AsQe749E-|k;3)wj%Ae63!yozl6~a}*1R+6~BwQn0CrlBh2}!~Y!cD?0!fnDG!d=2W!hOO6!b8F% z0>+=MQJCmQL89=?;ol~673Q*)(YJC_YRV3CWk))YEya~uGT>I*SaapS$sZKlKuJjD zgimM{yW(x&nkjshnjE)8pKPCz#@Iyi#82{SZ>209WlO67beQ`Af3)vmX~HnJ#d z(aa+LZK^QoH?;aYTCL|OoRF*>7QfU;aesyX-=|SNS*LEK7gL4jdf`{}lJ|f3N-tKu zA01RW?VkVtMmI2_u_|k}OQ|Wj(x!|lj(sl=v!?9I)}$+gG|U>;!PmsZ*Hj#zD<5DQ z+)}Izj**-M?*-^(*>FN&u`ft~}|J156+k*$CJW?XuIH7*0* zNeO`38gxl1@r5=>BOOK z+VNW5p+RT0Qj5Q@TidHne0$Z}GA-MpJhvYhx8slFNa z3k9`(6uzoi6H2{-4CISCg+i#d1N9w8_&-?{hol`#DCTa(5sGE5g7DjoDmKW4Mx{#M z=y@Yw(C1P`UHEY&Ya7D9Zq;`h7UdmOSGOD!gtBF#SyGM>7ye2O%w3_qqOU{8?rHzpi3D{e!&9zD`gZ2!(7w|AH@VFu5_YL9mlvZ))(6xqDU*}z&5SJ}; z9WAL|;B6jkSmwtvew2hl($=5IN`|cXu=8}5=ZLjLqiZy(w!@6x({~Q-;Yxkz(l2tn z@Rzr7Q&w<_y^CN{5TB^jEh$n2YcjH1>XSzBV>N_*GWL0t6)ZJ;R2&bYlqzdT4Oz>?;;dc}YOz$v8uKDx=*zjRfdg41ts5nwrgg7Wa!aX#PzoM%#TT&C*%Bxvwq!yRZrjpZ(MG=@U=qbG23BUg0 zC0_S@>3m59aD2`)pPMbD=5RTMb{WuLw8er(zSORTNKLyM>F8>={H1IztqW}~TbO&f zn91p{1RHMG(YExuy|J?Pk=p>|dCJZaY>on>}LJhwU% z$kBE+c51)f5j|N%N8ofNosQGxv^&C`4ljn?Up3mpatb4cG4$f67E*;mepv+dTrRs* z%oc^5UlN**orO~Vxo(I6?G*)AHgYIt%;nR#^*m^lz44-Vl@WpUYW>}6)y7xWF}H1t zE>%J`cO7~IRPT0Ydv_&^t~VClMNSSM-2m~N(bexO(CtbDXSVCGQ#GHEKKloRB1bfO c3H~n+y>8ws=aoKHipo(r=)*?|&T7(s0iK$IrvLx| literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/tokenize.cpython-37.pyc b/env/lib/python3.7/__pycache__/tokenize.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9212d2b6109fb389e16323d6915d9a56d966f327 GIT binary patch literal 17856 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 YDW(pkx>ED0-qhjLH;i-WeLiFUFX+iV{Qv*} literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/types.cpython-37.pyc b/env/lib/python3.7/__pycache__/types.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ff45f9ecb3001e71d3fb64ae013c04582ec5b0b GIT binary patch literal 8999 zcmb7J&5s*LcJD8eO%8{eFG-`ZB)4U2M^q$^*50)pt>Tq6vJ`JtTtyaQhqBRVb~R_3 z!|A4~n;Mbf1PhNAt6YrDE!aaK0l6%YTyn`NIV3<31PFp42oQ9DT!J9bA^*Uh@_VnF zJ=AE%j+?CN`hN9Zy{~$GV|KQp;Q8!V|McK*zN0ArMU}~8qHrB4`g2uLgwj%kDzu*3 zQiU#zCrV56bWht;TZX5Lf+#*wP%cngw}?^+CB18+R7OedR#2J|C1GM_6)n|08b2$_ zqJoy1SKFgp$6IY3^J>rLo-3*%W<(Xe^WHpq=g~Wl-i6zWm=(1rim2^rtwpph?kU|R z^c+X|1l}h-eM9LkqjU-_E8W*nI!z^vJA?9Blwa>!D7}HwxvnXWoub{miJFS{TSL=3 z|E2n=5?nPD@BCKf7plCXVn3?lsn5RiToH4pl-4RnuVVBCdUxw6T@+et^}*`zD}nZz zf>whm@f%#ag#OD9)Cbyw>Vw4xHE~WXh{Y#rt09)eap1Tn-V`UqNwi!M%iHI5EF88Xfrv;xg!+5LjD(}sd_jm$ExC^{FRs}e3p9_K6;+myzp~Z8qXAQ7 z`?}TK6Eqk}ktC3>thEk6=_ZwYlWOzm6?NO$c#W3KHdsEmD79aw0ZYg{1>z1-C(#GH z=|Tq$44lTgOJtyj-iPr5Z=tRxM&$K6Q~SxNwEYI=FCCiSqQ&*-&{M zDf$tzSQ$h7ca2ybD`R7c4J$NCt`O{HF{UmdICqR_4>;{wkp zcJ#6Kl?oc^qZ{keb7BaR<@TH?vcfj;yd{Rf!*`t?#BC7y!3HD|gZh0L_N7k~w!PTl zDUD{UX4|3kH|(|(d68|`wPaR$QP_LrrA^6fUwVCrvCT8;rNkgIB?X?47+X6cf&zZ* zxpq4g!&WVuEwbqb0ZX(XnxZHlP&x2+(ltLI>eP@anyD_RX7-b((2_F&k+O)yr2G>U zKuYMNT~(;Nn$ULj$B&4pd+JT)i|*&zuCZH)wQ(WV_cYmfxDp%VfbH@ibI9m;4g40=imGMFz`LR?t4rL&<6UA8dPrqb znUDMrQ5Zu@Y?-p=E4x}?f&t(h(BY4@ts*2xdj=hXW7UHbV^vJR2$d@mbcxHhj1O-xWTQ> zq@06D1!ZRH3`jH4*hKF`&z%Lk$TP?wOi+dHpa;gaX}Wx!x>k|Z3z94lv$-TAC{I$h zOj)kWQ_a7Kwl9#P)5w$=Q!Rp*O|_~SY7MEPgNxM#lq8LGX*NB?!MXmwfyx-1`}qAa zDXA;qJt&mS8fatU!E+BQP-0{kH2L-z$_aJwJS(LNsTy#hHaZU$Oc7!}*bbozgeQHF zdP=pA9_PfuSq7aRXmd54Fj4<>yiPtfH6pB7i2l}vAPg=?P+o3ax1vEiGcqZQ=W9c= z(JGJ$KaMQc6Lp=*PkLuEO_D7Jy_vwQR*E}*5O`9aM@Oqn^U~8fK=_O3-bG?xK_OCu z?5X-NR86ZIl18{l`9lQ1juibE*}i)L*J7UU6}V5pGp73lZWGykp_ttgO4)tDO#S~> zSsW8{a7!xe^)4pIZ>Gj|oeb`W(4c;M5POb+UEd2)vPi3PTjuFnA?fFoba80e_6CTL zF}B@E1^YfRKK^tLkt_Xv9Lh_u+c-;%7pae(uR8In$;|tmjtB3Wyy~4zFJKW#-D{e= zDZ{}A2`8jB)%_?>wWoV(Sk}jRH@oH}v<{~5azQA!o!%vQ>G0&!Zfpu`<{R1vlp#qn zY=M6O9+rY|fUe@jmS!wA&mLC^xD`(59@TtqYOo zSs%f$@_mO?)MIBGrnjE$tm%@((?f4c>qrqfIB+Nw8xo9Mg-uaxNPK@~tahmk8zYo0 z6D1=qkRw6f@E&vnT1tE?(3{DUZTpeahC~88$R7-jZQrV!iO~U5A&)p0UN0%xwg_D~ zwzJT`a!2~meQ1ES4ny>2JSZ<4~q+rPw!h`eM) zEz(b`!iJB|9x5A+$)wz@>zGH0N%JlWKo`i%m9f%QYnnY8lc?OxbIR7l8_o4 zE6-ropOc@ZHAhQ>04}g__&PZ`MyMY`EUCTBJd7dw2;0P*2t}(B?m!JOZyv-KR0O4L z`_C{V^-rODif~j&1DWdR%uxvQte5c3jlem=7kDyO3sYDTgJ{pS{1P}?bRD`m<52gd zt*)g<^d45pP?7HwK7~h4Z*b82A~wKu+x`nefV@NH8#d0PbL&N_I6o*0m7_NP9QT#% z?m9Y=ZW~|6; z=?z?Lq{-fS$1K}Se#V0EnQ#vy^IK?mWy|0NZ27Ozl^w$J*K9Z){Quf8L^>t>H*J`= z_R5ACjl(uvO4&gE?SUO1A*I>qy3xc#=R6}RSR?5kDvwddph-W;-=ypZlwG5Y)Vcg2 zW!EVqF`3Hfu;e9VUm-I1a`+k<8n-J!nM-zR0H%kpn15!jc|(=h}=oi4GIe0@;c+Heot0S7gAHJu+S? zmKOID0~+d}ev))W{});?+r-INH^B?#(HII-&{#&lf1MH!eEmXz7^aGX30Siz*9Z~@*P0^k15Ef4@Edz<6FV50`}1NdV<2A zM?h}^@_$Z2KYJ+je3h5rzrm$)Z2-15Tvw$5AnZvvoV%z_ngFiy9X(i|w zVk~;-oiiCJZ(=f8CGel1JYlwv(DM!O;dA4b_dghz*-vtnkI*eVv{_#~XoA@KkcMCh zWsynD?3y!_#Lbd;OVTk*qIObpB?~}eqQE?vR8Y!Jm|LA4$B*S*n)16e1uB-CY`nJQkuLtrGn`vRHYFGmPdYUhh-2 ztHnAz|6j(&Q(SlupViS)pceEMyQN*|HDO$bp?yl^S49D3?t>3k7;9YclEq#DvOq&cK{qy?l!q$Q-|d&i!tc9B*_6hQBt*wy)c@{i#AJzIVXRsM73 z=LiQ1Q;?i$(t>G8t)dUs9{!hV%FD#Jl1u-PYyIj=xA(B#}P*!vg z*;5$dv5KfAVwYVdMwB!{JQO9EWZ6JT?;1h{@lZyn8l-!w;M1Wdn_0Pp0C*F@ZA4T- zXpS>AWeY3U%W@sBWOjXm3t3-z6K%|ZV5!jV^qh?-4Y!qZE1i_{Da;skJuwhDjFRHk z4!v6j5d+dZ2b_C7kOFjzY^RNTDv@#DRwSj&9asb<*rif53b>un3|Q={Vd|rmoUn~+ zy%6+_K4@f<>Zh>BjKCa+N)f8w%8rWhA)g^J*Fk%(en#khPHi(l54&~4K@cbNsBGXDbbJKe>B|bu<3bIE zjxVFQ2M!8CUZ)p?vD4<+9qD;kA>xYb^?F<>GY8_DA4!MyUmz+(xW%+5D77@uYCtuY zGLm$-3p6+#LySeRGS>ZHR3q|d6&)c@(0u`tjzGR)YDI+ct9&0eaG{yQi5Mjci!RU0 z9gNR40fETxFBU2rP^DiivvlLr=g+iLiqN)n3BU1=wTC2QdXv9qBx&=Z@IB}5zzc?%#dqb$LmHLTd9X^(U1( z{B4yncmrb-(|hb9eAEdOEpE4F?<0uiwIM1D&Wzisv1*lXksn2kt)<&u{D~L83^+l^ zf1?++A>i0K_O{)IGI|Ly{%*)$k~kR80b;&#u@+*^L9vcgGjLJBpDXiN>Q8hYnYqo|Rgm^#g?7?p~7ykeR2 LwX3!B=GFfL#0Yrx literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/warnings.cpython-37.pyc b/env/lib/python3.7/__pycache__/warnings.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71cabf0b4d467be068b7d5491acbf7e32a5d7da4 GIT binary patch literal 13791 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/__pycache__/weakref.cpython-37.pyc b/env/lib/python3.7/__pycache__/weakref.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc5bfbd2028388cdcc538b1ada953cccb4f015e3 GIT binary patch literal 19135 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/dnssec.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/dnssec.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd9381e55bf64f49604758bddc100e555ef010fd GIT binary patch literal 12003 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/e164.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/e164.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..71042fdb361cd2b85f65679d488e1ba166b0bd2c GIT binary patch literal 3208 zcmai0&u`nv73PrC56iOGHC(j7{=gtu)RE)R>$KUTKoIOUNs9%#YHO$1RBb9znvq4B zBAFQ~u?(sO*17i3{sXm-d+uM-E3ZB6d2f5#?+q!*@unz+84cgeym{}<`#!#3ZfrCx zJoA73ojCz$V64tUbD`+Y>4{M7Hgt`x2D(->!OL#hOm#V*5>*4O#>rOuYlgmM=S`ieAUf%$vqb8=Iq_$G*%fjS3whp<*ys5w@x6gfyYP?$F4`kB zy^oFze{E&fW9x#=?aaQkt}JGyY;2Dm;as|zeZ?{++`p4S75_gt_fZ_Zlq%(ZRGJn| zCw-}S5b;!=rBgrT!&pu5p2pngZGR$p+#kz9%3qCQEgKxqOFx`S9%!D9B!ANW!{=PY z6CWxfT8{mg@Kau>_8MkSJC5#(;3P=3ISU)#Xb)_>G4~KAK(Az{{8!h z_YUvf+BbV|-8u9i^dR+&80HHsKocjPd~`6FrnAlpV)t`p4)_kQvXn=Ewlb z3*~0)ANC9P*!s$9vAh;&a~nuQ+xsYILRGNEbl)Bvq?6ABu zK7a|yEFHxWjSh^x$?V(4gD}wPAf6--DJ?abQnk+CAF6oLHH#jE@xTxDLvOV*XCCaR z7SU~0@|u#!Of7QGmQshv3&3_T_q~=ka@{#`%=^xDiFv75(264pwemqTiqU2C2fXw7fiTPrY z=C6WuWWY-sKmf%wn29H$AL)IrK?OinAxAE%f(GOyNRi3hr}WgpBnc%iD2>NMUVwey z937ltS$~FQyLWc^?P(NBt&J&ruly+OCgD_f$;RMpuYkg@kS)MhYXL$^2Q&2+AQT|H z$wP~sC43FwzYiiJg%Z91X9^M{zZbk_OuWWzC1}YQ(x+sIAioUG;T`A_QPc}%eTnEw zU>@oUoEF4eu0#$)*Jnc*1Y$Hq62&Wh#nl;Y(UQd88Yv1#KaN8XhSB#_O(lF1xD^v? zV;0!~3Nx<7Lt_qks0_EjqT*uT!Z-z4E^_bfRP!OAW2ol671g95oeL(cQ+q`_EvASU zTDBrc=1wRhjB6OHI(19_F)&v29sf1jf=u2`vnNW$N^Q`JA5ceB+p4H{XiRL> z*}8c@oth~1ZquSS{mW~mKZlsp#7x#soi*4N+h$FWRfD-iS?@x=WGsr+I@%*N{ZDim zN|)2R+D^eom-dx4x6R1G$Tx~rw#R*S@SBh&YPK&Reuh>Ur^P-=GDJepILvjUfgUqT9Y zbNs&{!oP{*Q&R`DKmFa)BYt$G%c=kbk;p+X43=59s0LQ@0&lv^I_aHwJcPb!a(nk$ zX|TJ`|FmnqElVc!Vs+v{UWiTYwEMhOlplLVj=xa^5QGT_#S|f!&LK+|+)Rx^&Ais_ig?iNqQFKGwgjkgu~R1*9fU$0qlIhOL}iJe z7TyqOuer3HO#5Ll=t{T&-BiLF2Mz4Z$=7T)_%#(q{lO#_(@;JnTx$xBYuAC+I@@xZ JPIG6Ie+L$%Zn^*f literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/edns.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/edns.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb4b31178ca819112e72ef895bff70bdc7c4bae0 GIT binary patch literal 7212 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/entropy.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/entropy.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..38f589d4168b0656748437a7006d8e2308c87c72 GIT binary patch literal 3306 zcmb7G&5s;M6|btU?&;~7on5at_S!MYLI5#VlEpUpLLo8s`0iE8d%5LxW ze7L$c@vM3jDeDtLC?~GWk`osW{3SWp35k=>+_;$EtDYT}Riub+)vH(EuipE;_v+o1 zm4xA&{rUU9`Es4He^TT0i^1GRDgOeZnBoQN*ER2R-xhtLgbIpaDEo34_CwC5Z9fwA z8xPs&nq)dYNX!SE(eFo^{l>4^NPNhC&XiQ)6Q)9)90&cDZXL6Jd)n4~zH-9)9jxEP z`cdNhg`BMSl!JDKlf`(n>smYcC^OU4PA7Um zY$F*s#-(c z^fFv@tve%Y#*^s><8jd&2y9MYh|)rN52gGEh~gDXp%GB-d0~UOJfU_ty`~^d5zRy; z<_+H$D}j+Fbn-jNYyzG9sn*G2Zfh1)!MuHL?#qk0U!3X>yROV+C6_Y;+O^hcO>IZX zitRTy*fB}CT0xS7runL3^EKP4_%T1>uw;m_3wC{e(Vw_6YO9EP{7p6#gEbmGLxy;| zL1Yc&U({p|?slJZ$pp$t^O4ezU8M3|U0T;1>BlzRnOg0V)b1IbsT}r`_r`+*vL$F^ zFDv(oe8eleVkjlE;c*th^wTrkp~x?reYb4}VfGbWolNrz(# zn;RFES}U!b7?&>E)pn9A7gJvft{Y;OE9m*eqFdq3o;ey9J z!QVNgjfO2Lx*R2yW!Q9&QFqCCU!W%I5q8j(F62{C>rM z#(sMnuwnav)_!mx%*!I0f1*X-jE-3Bhx|U8rk5{VQ#c((g>msGn>BO=t5_u?uOks1%3FgxB6A9OqBDu&Ish&)f^8i;G0PHf(JJkS%Hk4H|9 zC-5gpN_XL)7?&FUWQ~(HA8JDx!(1jpI`0PFTINOCjGJ?2ajkTiO?PxkE_4r5$}JEE zg9w0`K;9-!5WfjiCEi>|m(LpN%nnO?5uTO+|05b6el@raG$TmY=nD|N;_^B;f^rCu ze}p=kH*Ac$Sw}OQ_&!+K$2_>iyoH_s)+60gruXx~_??O&vz<<5^f?T_ukhv>MXhSDDvqv*!_0kOk1*I(EVJp1g~ zX8|*>VLX3^@M>NHhp0)5T=FY|hfjj$4Rm+~)mDlY0QxvLNVu}dh?e=0?n|-*GG+Go zybU`G3+-t8sYXD?jtg|P;kq$?a$2Gh@)Ba~)vqz{VsV%Ey8Lc8p#(U}hB{4=>eJy^ z9Tvp5)AZ3{R@5WrJ0v>=nA&3qX7yG4rG7%qt^XxH4N&HzxK>iCi5toDNhiJ-uf{;%zpHEK zC0u^3gf#Gbl#-Cfpt`p37hAp+$xles_fX0ofGi~2B*`ko7sAV_bkru^X8=*7rz_1* zvCO1Sq^dT(9cqLIvK{^T6b|X>qiHM{B01UUki~s-t literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/exception.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/exception.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e0e72ad2d183510872faacb811200cb1595645c GIT binary patch literal 4119 zcmbVP&u<&Y72erhkt>Q)9K{KoG-wB{(~4?L0dX%i(js>37Ht8hwH>q|k}j9KLvf}3 z<(Z)=veYGNk(FI}c6S>VKIi}V z@fXdvEbCunEIuwepWsnLG?CS{er-i8vj1vDwqO@d*M{vxE^JrWupQW2Q4My@*e>jP zM1(H>N3D#N382acGneK7go21Uj1upzzif_ z*Q=oDZdVX=8&&At9W#f*_PWilE!XN&(7R=G{ruoRIPhU#X&Ho?_X8!k@s+D#AVtLc z6m`O*B_6A20TajPHyQyJMJ~1CdYsc9aY(RL;pT;q0m1s9njWkkq!UGJAV?8t{inP!Zet0?# z;03`SnbkU{+;OFYEDB`Ae_!Q!nUQ(?IJYkbIo4vH!CGe8!CVIUV0VRbV z$qYviWS(LOD-K${p4kof&Hcng1JpcC{TAV;2 zgh3|8)t++~(vbqEMCHd4$0~2!45on&tE8gXz&#~2kCDv{m?%Ur%&!)rV)#R3cfJi} zS83!4+{siNEkIQw8MGHG%-I#cG9DN|zd21D3<)6vT8=_(!V5Tv09Ps9sZc677N%4p z4uPP+d%Z!bk;6^DKg3ZcJIE*1`8rg}Py_IURB|z*M!K?mbUdWv^Or(O#4_J}Bl^lC zaPs;?QG_`^28>x867Sd3UAYc@qq^;cY%VnM^Gy9S;Yi7$s*ld8_ zC7W5kt(}>5K|MF~Gz5vh!wfgFPCfY;y&8?pnC$Ah_Au8z*`BdWi&@$J;+t37wBic; zM;1hhby|&b*AIsxJoSywYH3zEENk=s4)RhuD2&pL;!u}$-$&K>ez^sdfEoo=dJ6?< zIi*WXC|%M5N%u^PmD|2=GUfaKwEp|EBb^pUMO@qie>8OC-beBMlb@d+tD~jrQSWG} zeC=W)=`OpEN8Ltau_klb9&6ejYv6I&zCC?=U1r-0hyD-r&uEjoXl6`#0Gn&{E*M(- zf}J`@CyQWzh3gPNIa3AoT)T1>+6!jpSpu;}n1=0HuID8(Cm!YeSI`(0KwBq#ETA@= zW+CK!Osq-cGoE925|>aSpM>_9N0WoPoMaM|ydLm^mTaMg8xj|6!=nz+fQ@$v*jMbzaQDPMwbfniMBwp>{SLnSip>}RwmZ{% zgPaf{5hgjpmAw|dss#AOD2C!Z;2)@#TRNClx|pQOowZVxZ{pyVU4?jEbmZZ0$wTvE z1lHVUHfwxCgcbdl5pH1}JtjhWYl^LN`|Qt%(7Li7TVFo?!ajG-UCm~$M#T>73tRpP zJy&nd+zU`^X3w0DEnTDk?;`$)o!YWjS+D9>pdXFD*qgbF-XHNDAvFCvXaqG}DDeE6 zH1{Ea20={MIQLYjQKD&p>Xld_Cwz$O6^sMF1fi?Iw~*8cLy%g!1KXA4n##N!oPBryfuzezVF~s zlvwX=*LGQrxpwmn&-3cuzKNLvS$=52CwNT8Hs7vEUCV8vw$Y~Py9jrA+v9dlgM{D| zQM=P}<&Ut5B-xf9P-Eg-v1A41PcWL|QIuG>wEKA`&I%FYb?8YJO~1e9l*l67M5E<+GPx02Ex0mTbB*j9xmJ6g z=a1s!>Gz)Ft?ab~>Ks2#;^P}RbO;9~YYvfpy+iL|WRp-s)^#KN7L8m`Ypbk3k5iG4 z^z{9OZ_A%XTw@3q_(-?QI`wJV{coAZgMk*3|7AY+92XVdSR>VG)vjgcs@|^S=uhGL zIR!}tN^dVUCh5CQ%QM6-x0gSTOhp+IOQMaW1W5wLELc_PN=!=c<4O~L`3|Njy6Ro~ K*5|j}>hFKsjW9R> literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/flags.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/flags.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3bda983bde3392a83183635d2476800dce4cf6cd GIT binary patch literal 2226 zcmb7FUvJws5GN_gmKEDc+%##ruFziEX!%&9Lph< zAn9aaK>7{#I$-wW-u8L;x~F`FJnfE7WXD*RjRNnEM@szt?vB)YrQ#82z26_bI+`Nn zFC1Jo7mR1n)t?|Z2??hmw4WCOaI2N9Eu z>{ef~9__J=X6#pXXz!3eh^)Y5U}?6zs_BWQr^aE##p+6W&|T@q-KDsr(x}~D`Xc`F z?brJ)wZc29dz!vUI%uuz83x_c3-1Y!n`tvS=sx`hcLpM)Kx7Tn|AjWf5m>ScACS{1 zFb<&(1JiHlki6>!imHYcEO004v)%$Il=n)osUs_^8_z zGH|q=ij!0>z@&Bz5?x4>ebG^xrjv-h`kqV<>iEWUctM#nM{Pjs(K#wV0$&qjh^+uU zFRHI#&_bk-G6qN=LTTAOCnK5t44CX&(#xzq$(#YDo1hhK$|SE+mqzPudp zY~7dWONI?^+v42XdVHk*~T@Q!FXbjbxMx?qfap$)1m~^bwDL9JP;x^5agL zzuCldoW31-XT zc>szgt$5cAdE&X%#mmgKU~on7GqA4_yg6fsBYHP+`3~>do6?4p2L4!ZCW-!Y?kaTw z*WN7&teQ1>77xcr;%UD|^53$ka+)1K=cE2xF7x$<=UC}Z^1LCT)tu-stFy!L?Wrvr z@|XGjd5rq!U~dHrx>&FCq*<>^yapxSEV76K?@L)ifhSbLkDo{^ZTT^ZB@}ZgK0&d9 z0xwnhDT-ATcw?DrG-pL(JxPqW#GS_unW;rnhVGMtgderVQ~Zx8yw_~UW@C?ITa1n# T*LK|+t66TrWv=C7^YHl_Ht*^l literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/grange.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/grange.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7c300c570f791b87896b3ae014e87678ad14f78 GIT binary patch literal 999 zcmY*Y&2G~`5Z+zeiQ~4Ys!)LoS|mVC)g~%PAS8q+ZN#mIrV>&Girwrcb>pnv-F1~l zwuB1rL3=^s1$YD=fTM-Da0+KmJu&Mh{H!&zGyZ13`7~a?SXl57to+0M*HssxA10YC z0>N`IbrT#z`-oviBD{~8#q9TJpD@x!b!U8gd#6obwsu;(n|m!P1JUQS8;cVzRTzuL z1Wu!!E;bviDwqSd1*U$1V>k!ioG>f5G9*_r#H?G0*#jb1G&;iPggF=Z43Ca7w2j^z zk*uSJ(wQ!|)rZzYJwpETuQ+>#(<|9peu^iI4M}z4MLjj@h-<^%t_o>o>=0h&vR7?ZmQCOkS zyw7FBE3;KYwYpZGR9gD}+Mfn#5dCHTpVzdW66|uFN}+&2r%A+(Ablt~2PM!6G@Jxc z$`zz5phoI75EUoJ^Q7+kjZ($LeC+~Bvt8o#@tw9QrQJY?SknUz?1J|L9iDJ1(%}J@ z6LZ@xadTqBK3>|2(}+=1oCH#FdQa7fG$j)YT)k3QOsJy9M_rz1xMjs$`&8&))RHom zg#}8BYN%M)4|Q>EQz8mZ*hX?;byHb5>6I3Lp`Y;wIYWB;^-$+i2T2IEqj%i~U)FW`nvoSpOBAzE6 zUc@eB74Wm&BiD(GJutVlc?^#w&Cgf2ifX6B;%=uSYmk>OOKtzS8vqpU(_zfgh(B9` LOqp5Q#3jE0BSj4L literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/hash.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/hash.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4a99c59d6f508a5adbb0ca2af0b6d55d84de948 GIT binary patch literal 645 zcmYjOO>Yx15VgG@*?e7kgOd-4Du-s(l%Q6M5QQFkp&<2uv_guUwaL2me#qWUl&akL zAGAmQlCPZj3!E4`Aehy>_pJ5o%$t2P9uE-2mv7HM9YzTKaEHGUf_M#S6aYsV;+PYK zGwhjUM39Go2O@kV7)g{x0^h_U;^6{;>Vb;9NT-1&t2PTK{rAhS;KYuK?!CA?I2yLk}J4oTEY0#2JbHBHoU$(KejR8 zZ1!T$^Ov4aPWR{e@hrz~1PI3g%6`UqpA&dol-w$IeM z*0L?i???}!=2x1wWs^3tIdZcwrH*Fuq?AoHPoJ!rNrp?XwLMiy+7V;0&A>brN)L%*@FwwXpzH8>+0kFl}@181|R}gAv_wt8T;9O_V>NdANBhlf%5o=H@<$m zPslI$Qx_LLK7=V4bJ9efHC4wGxrk#}s)}6W!N%D$K zM0eq-&nUr%x2Nt`B(c6E+~J+?$<*U6?}FXn9^U}l<2~L7+vnDV3#8M3`Z z3zZ1X0?w7lb9N}AOei*ACZU#Tl8??HPO^VSp&rtr8waZc;irnrD>n%VE$oGYwgvA! zc=NZQIwhJcEVZfWk@d87N}tgQw%O43CbYHdHtjrttwT^&z+jDgX>u%-X8KStEgtD* z5V3ixVwTQXz#!0XQ?+P%EpP^#EM1bO&$zsom>1s$rG?gFxmY2iN^n@5NapVgYB#ca=)jY{umLlBHOliBQg^ z;22htY7?qFA6?Ha^im}dI80w|Z8jSj-~C~y=-j>U@9pn?UbJ|U7q-lf-z~Zl&c+XP zniOu;y<@s|iffkyIJ63<+jxGS!IxV~SJ^ zXjoEXQ_||M?7W1R{}pXY0ym^lHb9};SUFHtxIy{^3KdCpu|o8QmfApvPPJFVi?SME zdr34HnB9Tjb--VOwh*NP3tF7lXu_xPvAU|s5q)Z%l4q0>-I@>^6~R;YOBpl$?WW(E z7;yv7&J$Y7TP1QvFHU~_Sb%uNK*h^a%?L(?`nHjfHGFCopwHGVlWXOnm1tH&Yptm> zv(EZ2f@mpToa|wcK#H>i!FU}gH%UBKX>3B4Nw(DW%yrH;VpW6Zp5vxEaEu1aqPzPj z6d7uC2_C{&c;{gasp_FK=Jf^q2Ep8i)9@>JC(xTCYGlKLthMQYme!%_I=tfT;pFsQ`Z6j6v~#ehgd-jqhRUix
    O%gxcf2wA`~UPfAmLEcXS7x0HK^m4C kfpOoDQ@)JE9rVpH9NTg&m%3KZb{va(5T)00ufy~5pNEBb-~a#s literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/ipv4.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/ipv4.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..046c0cdace0f34c815241d116ad1548ff5d685b7 GIT binary patch literal 1382 zcmaKsOK%%D5P(VUL#vhS6hWHA=mUFcPzA}#NDKo71S3e=0_`Cv>O)(hfwWn!?Uh#C z4M`c6AYI~|Q{)e{HqcA|60be^+*?kap|pZg6rsc+M>8A^XTII1TU#N4vHauSue$*u zf1^?l2Ad}^)gA~=`h-)?3fiZ3WqpS`+%4RR*Y_yl9{1mnzRw#xfVIKdA?Y;dx4--0 zbT2x|iYk-Q(Nv^5FNKP)AR>8wML~9`X}!!vB4-0VtFjb-!-1<0^BGL_EeK5(cXq&+yHj6l;C_$4pP9 zQ1&c_9u8w0_R59(&0AkgEWrYK~j&GbI6UN~}nPzsDW))V`v<_!NCuiSC zSxOV;Di=y8BF#+m}n_ACJBoAFD3J zuV(tB6u9f=)#+Yb%}g^FnH~sTCOdFmwLy@eO#>Rj+@|s)&^O(~3vIghCn(rGO`%ga z7vzFnk|pRD4yTuNiCv`7Sq7cm)!xV-HD1%R-hzHjUhFN|f?WicM15adz?*@$Gj`?v zf?=1rH)e9bw!hl{iOfFbK;j#MF@Oq3H%B247tZhOEigdsr}qDa2=+7KO<bs%9R~)ST<8unEZ#M4l}K$#Scw~O^nKVXa;4L9QXTX#9tQWx z{4?A6M3*A&6=j+f>Hs#ir*WUcc;2D%4!Cz(vIUDoV2z)NwB(ubR8{0!HqZcX86uk~ z@Xccyx#Ib8u8ps>oTeHROUE78xL7CSVVX*QjIJKytp1bp8cR&>OK?)3gCGGS8PXcg zfZkQfnkM<+0i!GM?PU?4vMy}t#h$D3!$W(gixibUJXSibGqYZ>5^B(ZcR Y=uJvKEwY1~peekX%K{eAHVbb23o3k6JOBUy literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/ipv6.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/ipv6.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db46879886ff9343deff745c02b309727006624c GIT binary patch literal 3057 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 Ksnss9K5CIeUi literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/name.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/name.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c2880069dcc66643594b6cae791e063d8ba7cdc GIT binary patch literal 28440 zcmeHwYm8jiec!$F+L_tmaEGLbzyoO_o$ z%h{Rbxp%eP>1=F^jO{$@v_{fL+AIt7Ls27f+`w@I+jWb;1so%viU7Unr>022AaDb? z$Okom`}_URy=U&s&QhXk7%k9Q+}FA1p6CDk&i{4JUf8y+XyLd1I|tu>ykl8^&WHGy z$IUq${%@x&%e5+&YrCnYy_Bk?Y~H7v=}KCznMy{k*-BQfxys1exZLF{c{fujeA;U5 z&RAaYMp3=Z-YTmbO>6FO65mmmaD-v@}tfSbDhf zux+gsz0Bf{$_}JAgY+Ijdf$!G%ei?ky|L3R+_iUDXDzq*nC0enTa_JgE|pzwuCm)L zRvvXnE04LQ%Hw~}a<{o-cPw|zD=qF>eBySxvKL|7-EoACo3M`{>>+moVG|POAl{P* zd)VE9upK6BAHp7ScOq=3ggu3L`w_Ow-Hou_Cf)&rJ?cJ&u*W2f`5r{r+5!XSOW5T8o_N2QHVf#$jG{T;8_akh-_YBfMgy#e9K|CMy4&nJQ zo}YFn@jNNdGu{z*>b6}u>K%5oxE{kbgX?kcSmlH_<7V6}kK38bv(Zylo<52v-0>~m zJtyxNmoY!)JzF{He%zgQpSfdKKJFfJ58tsWr`#F$2(F(%368qQP=aGp!qeVq_xN=i zd7kl3U$<~Q>z#4a^C|a)`z*eHK6?77`y8ImxgT>+B9-%Q`l>Z`sx$gR`KnW{EqVS- z@g50y$__^^tOcHb<<;`+<$E@RvSFs#Ze0&YuQggVwN?$*mc6hLc(($5n_Fo$>I*6? zE!Ebpc~#e|w_WcZhe2q+b`OKVx|ilDgHs)c`7!l#IQ(&(JgZ`3w4_`cqa%gVrNiQ- zrR8Al<=Qo`*?Hu=!?HH{;52;4QdWXY4W~Qt=?RzHKR8p z)vDXBSF8WpQV%09IlXt}NU*egWVx|?xY6>1TC;ihc;m$4$8TKskGL&=c`aCIw|IAi ziOejosWE)|ah8{L%G>h%Kou%nsJWN?dTrV3oIKxhJh^opwwKdrIW>ok>dd#*QY~=W z^HO7G&I&hL@6?(NmsM8VSqCA zGr9-r?WJYq`F^9_a+dWgef3%J)tYiqR6p=)E^BbDR=>fp2P*bX6!Uzd*nEDVVwX^C zA)8r{YUlXuf)^1ENtZ26Qj&&UZ745pa5VBt>qe`++IpbU?n3D?M7KupKcG#1nRS?BmiKkBsWffx7=G3bGc_9%){Hbt`)pC71bB~3&9WitqL)_Ly4 zhc4S=D9am(vhn$W%JxW1Fc;gcdM)r;wE!cs^O-FurnbE7wOpsx0;-{_oi?cgq)`+4 z5Q-5*jcEum9Ya^~XnCO4e;hUXl&N7#@%e#jm@l_qt0}J)bY9t_QrEqJ)a@)wG{Oy^ zRJ$EWHKbM`ZwB@%_du1{gF^p&q7r<5ph^_W?JF;o&mTW}^knB{-Z{K=mQ}k>3`I|H zU@GtCiU-Veoog$)N)5MFbM$0J@NcyPsZH&jS_1^w^d6`dPoUJ*L@oF{ycQ(G{)u?O z29ufwgPOsVoDH|J4wr7#y=5V{{ZgewZB(t{qZ*(dFOD=5jJ&(%Ba7xyj8M1J=X31jX3YHmdQ3wmH#zoBC_09}NW1wpF027|?IrV1Em+8=vntCnH@al-> zjFdl9C+EW-uRJc|@W~&!7LvBhQW@}K8Q*KpCu+u7oeWQ-)d;}$@GF+yvO5!|Ff;M% zy1c?$UQI6K%L40N@LG}+GI_Y%4z4UMH@zhcHqX7JR9j7@)ILNEvjTU6CCKR--9(Hy z|M6b_`lZR8)uOZ{bzHfu4{vn zCJ&h_ORL^$9X_nKA?q-|ywX}@Z%o{O54$Bl^OZ zta(VOZstw_qz|Ge=}Xv%o4=E<MqE%i~B0%W2B$z{M{80dINlK2Ye4;eCza!f{)~UrZEy5^&pZ% zrU{=lXKwCVyWO0dn{lqpJ9D#Y#hW|C6kC#{l(@d&)o%ciO+xt4ZMVQWF`D!X-p)AA z>;m4@0de)(3I_W;AbABGvD47=51AK}2GLzNg$tG}SctPbDd~7fcD}aK3|Ppy%izzv zxf$~%p?VA7PP1zW{COW$ZY%k)r(iIgrzqjPhyA)5GhVcaWy&45=1Z6 z<7oH?IQ$Y$RvHwKkyWx$%^m&K)ZJjnkR(W0;?K#B-0ZKoY{pc`oa0hRm$5=$U;$!?8XL_Q zrJ8kwnxBEFvk2;gsL^2%g2-cEJA5g)?B%&JEz$`%? zjlZ7t>I)$LTGJ$PHK?^*3e`_N`xms zdZ2s)D2D)InlkT8ezuQn zEOWVEb)C4HCJj_~GemAGACxxj)#@_fw_5Y-jmAJ3k%H+a0sC5{2UuNz#>(UcaoTVA z5HTS^v|H#*!6B!g?(w9j4dG4DXZmSh)o(1%RD=5R%s%ki zP-?bZyfmp$mn1Wr6f8U#1b{Bb*6ehQCtP5;?IynS#uC4t1bsJk-O;4#r)kg<%W%d;c9Y= zw7PW7v_6VyJ)4j`lG8dRsa#oRaGA@)tbozwXf~fJ>8?7Dk_z)4jxE&Q@v0)}vZ{&# zxsr~Rd3_XQ@$7R|5MQ*ocN3O zL~qKE+WdZulC<{wGD<HTQioH`ebY~;~LY4iizxq#=Quuz$Zg&J8L?Q8AQ z`?t1Xnn-ve%S~-dFikSZglQs`479L%fnnsP!W@tqCIxkwAw%0VW?lLjs1Wg^R*e~` zxK+o{uA5smVx%&c@tZ1a%}W_7(IOu04ZU8C%OY$PtN5>2j1o@yotcznkLB~Z{Fve! z8CLryr)EC!_PPCL=#Zx(;K|VWuej;j{w>#*;SDkDc1k^lp#wo|-MTd!0Pb#c_`kTG z?xusxjhwnbK^=m2`nJ8x`WSfLoBJV>rvVCc6wPl~xJK`zw-`3v^v)>mrvV~N{VL3t zQJy*E`RmAYMDl#GYazdL%+Jjs)ogf&08UGaUzL!o`r||h@(A)QQNl8gXmWU^s_W}ePLomg9fDL{k}T9mv~+EfFHU-Jk4vR8*xDpN0} zR+!6{Yjw|=JblJFdh7VnDVd0S*~#NMzP|I4P@~aM%DEkdOGK( zHND|31G+dHKnVm&ut6JdbRlO!Jbj~^0o_1b2|CH#e2g?8G_)9`qPSW0E~an*(QfNT zTD=>jp$4NOBVU7g-MUB)MR+o;Ef!#);Z1sMso}a!k1S%$MEca)qV*3+|3BJ%%hn1FuOB7FYT14Qfmw{m;SDI75bSri@c$5Sg1xY84!a4K?s` zZIlDdWSqm630*SgQ=Lv+aD1z4IN6x-W~6phn)j+PC1s|~pho5w+$2nVS`HYn9FX&j z74Omll1SV#x`qmEYu)<^ek#p7lAp|z_kMyqYB|zPuO))M*l5JA3cXxTH)&`$!)(xo zfi|=op}nZ-Hq~qnkZ3qw6$>ehAyxe)JRdCIK^|6#0&YyRkuK^#M+ zEG`Rr5r^o6Nu`2~V_hJZJf(nIU?Vot#4<7!5j!{!c|$T6jm{j0(;PHSvB9nZ?S7le zD6ynd9Yp~Jp&}b77){rt0edl=#T7q*L_zEjh?4hEps1HoJUys;qrdp6T60A!PB2w) zfDbm(?y9!ZMKI^op1ImpV4@p zg{0nx36WU=0zb5kP}LI*V$+<4hF}F+d<@6lNcKTtmuisx3{lpcnEGNvc)|uwdW_~2 zE!svlHEqx!tTmRFRsyj=Nhaz|P=nzvsM_T;Lo)HH(1LSP>JE5}7X;;df|Z*FZvkcf zUFgi9)CW6$+lF(K*qAymX>FmeB}?EXCRoKR34IV-G0I^r6Of&YMi?yD$x$Umqm*aH zG)u;r=PFA^?&&(l^k+(7Mp3%k_HU$aB5xTh7&j#QsZ^MnIU3rx1_sc3#nVmb3aHsR z`wE8)Q_fkPC)tZepqe?|Y(tCVpT$iaTbhdIED-`fgU`azYSs4wSojq@R5kIf+C>+C`KU!^AG5IoM{pX>2VEOLLeup<%4vUS6wK-!%F4 z8b!a^M5@v#6Ovg#t+usD#V;gXooPlg4Kw^Y%)6eq%)4a&gqbC8sXb6@x*x@nt5q@= zLMO1(Jrq^H_jc?0yD)_;S`8K@RgNnjk;6W=#X$X$DNN#E2{8j!f8J!8GMVIe-{jz~T0a012EGvhn zMKX??sP}$&6YY`GY7(Jdq7Bhy5rFe3^b$A7{%1OKSHLDw)*#`=JhZE=Ac8|d zH%z@GU&99JchC1!z;9^A-2rmORwM&3!rQ3VQ4-;3K%}$0zfUKPQl$}j?66*%Fmlnj z72$}HO2^e&Z8Y8I9cS_iS-q$^nqF;adpte;^z%~>Q1Kt5 z{MPgbsPqWx#e&>ORJbG~A$nnYm{hZr^&Ay$j)RdOdY(Ka4afGG8K| z?f~0QT1}m`x>`)IZ|;Nrc>L3xTCWrAFVU4W)Y9+I6aDr(p0iN%7h+D9 z^pH@48vzHNX2D1ignS$OGt^$PDMaSGG;Aj~b*Zs8i)i$i-s^JeE5YhVxq z#8?yz54M$N$nxM+C+yulFw-&2Af{=X16Ueu8sC94)h2dZu4&53ka&)EQ|e%VLG7mI zp}NBzTrK5JfDf`(1`TU3LXuvmnlroGg7gJ-AEc}bq^pq@!q!J1spWAL0(-r9>sPyY zhD7$axY{SJ^$|#5ydtJtv*wLDs@M@C8YfWH@%+k79^eT1=;mt zx7fuqOC~Wg>aQUg#xefeK#YQGL*gskY(nD8A(oW)E4C^Hx%FaehdgKSyeAmJb0)|q z)1S)J{si=Pk(L@tZL84FqxYeM*E~0M?ltGcVVRswug}d*Dz7OnSBJoRz`5g))6zo6 z6sf~RoQ|VS8w-d=q&VF17aGgZ#0RS$tjxqJoxMqc(j&$)4bkoSQy{<|Pk8>7OK)6y zxm+#3TD}A+!+bI<&ebGe0yzsyvG>)KqNi?6=& z%B$t`<%^fD&c6Cae|tz{31@fOIZEMnnl3KW&S_^_3=`9boU?r|&h}ogDbAcRMN58u z=1d$7EbMvo9Xki3nvJQ2tJT_?Hrb$&VH~NoOgb?dOJpsPT|-%PM*tU)4Ex1rQc=P% z=V|u=lL%vg8NYhzqNax^CY)r^c`%T<6#S&}Ol&DhA`#(8qX+@4EM0?h9ww(vGZtwF z`US=^lxm6~C55mK-gK$mO62e&9Y9Ilej8QrZq?}QL&=~_N{@_3lm_1*;>xj`QMO!9ZX$LO7jVk$-oVM@_Y`!2>$y@qCpZsB+=niP^n zIAb!wfzj`%zMe3-4@TAz1-!et~%(waxZpWU!!#Vo) z=wO+TMKz4SjXvo6HmYy$+yC>P5+zfQFN3a~esbZqauP0kY?_{>cbT{S;1%vLFA@kE zP9#Dj&Z)fri#$zP@9vtbE!#q%;7kj; zA;^7hOE2f3$HYFF4-#J^sYbwpBp}nUd_#Et*~>6-ejasIw|H8^3F1fOJ_pGrG_C)v*MCX4Xmfm*uv*@tWE-uEBAwO5C= zw)z4?-{t8xPXpZan6#$J{l9E#^M^SH&h*DJ!U$sb_-bm6D2#|kOGJ^|S~rpI)Qwmn z{D$_nz`U=g1x);$uAHXj}3{q2Z*O_aRHKLDLooCg-W3u6f~~l=u>5B zzuJCP7KbF{v(Mt9syy|#kD5c+U$aq|D%4m9q&Z9(;CDGpmGuF1F{NZ0e;MasWg{X_ zzBNS7GNf?`nC!<5m2;wa-vd|?k3;Gsw4h7h1JOlf%00yA$P~S}sER(1Bv90SxG0Xy zfy#%uYSp`0t^SCm6Ezy}ZX(r@6)8~V@!f|g8_PAUY_ktqwidKF|8tA7@!f|g8;uol z+0u!2gJ9a)eK>-P^1o%I*45uw!5f0OqV;w z)5dJ^o_!V?Wh~ExA-r0JnotI7KS)upOQT1%I>92~fKJRPyY-vl1)%nX*>jbFXf5HA z6OO>-MZ4Va%oKfzA4%k+)l^XddtU5BU@|{~RRL~dWwm%p?+jqhrq0QPLL;e8iGGp@ zmf;iP!0Z7Phpj$^QbL=>D>Rs}nQ}1O!}Qq1YS>`FaSzP8@s)(zJInwcqRY%BpBQEe zpE{GSM?MU?5zcI~;!3n1Q)1}u7ax)EEFwh?g(ewHkAsedNv2C%PJ7dzF!Z8tJg4FQ z1lnAlXUd{~g?F7%y~;Wb&Gu&&u|_pa)065DzKAt&WBqNRd2rhwm?6|};FH}X23iQL zBE22<;3(PSSV;tDX-ymvL6z&IeEwqM;ImIA(U1Y%=qJeknh+Ak@jk*h?gCpt6lG3& zAPQU)M3Ih&BK>77)W4Beb3yu-ur0ubHooTF!X0?R(B38_U#zX5_=7YOyBiOu6S!$?3ixGYO{{UshBI>lb+Hp-mecBP{o%sf&1=6ngfDgKV%TOpo#uX)x zAz7p8;zw03ps2n^4`DiN54wBCYM&kja}W&sP&;t!y|@tt@z(;=vKs7zaHub3qCAYP@lBlf+O(Megc*`V9dA;y=LEZTz`LozCi zNrZkYEHvE|X=7f6Uw@+G-*?2mXD5bhXh&n!pf$0aC`!Qhcj6>w*|Bx|%Rp_4k^S84 zG-4#VS)h5b*R^`^l1&%3_DT%mU~8Wewie?w@^%`^)MgU^A}WK2hjf?vD$5Y9`}$4h z^-p=C3@`a(R*?V}BP{lEJj~KC(3%*7aJ>hIMiC0!o$UkVGxI%>gojKs%tX(o{z;nV zZsh&ln(6oV&>xB`S44MDPQqe7pWQcqnR&CJ*&f&$cHg{^)SE%}1_SFdz;mgrmqH+WjS zn+eHf`iSC;E3L*ygb2qI=`;^_uK6&AQ>%%iF2flEn9)uY< zSl-a%^Mi=A96ws5wL1sdVKW$snr_8+Wte*g84B3&IPzr|1MGSN*9|e}g*otxP0Fs-nIPK#4|GQAMK{)`B{2E(wmnid|39f8(BQ1`DD-` zvyL_1>$zLs?Pg(Q{pR`z*v%|#XEs?;d_}uj7Iro;p+KI3`U)^+q?-pjT0q`7!+yu` z@4C5eVVAXD4DuTVccfdqo1)bZ4&S59>oqLajZ*llV6>aZl7cL(hku0_CD;d^=1*IQGlJYpOhHmCbW3-^1Y@CSNjyR4B<&G~+?<02ke0qlgl*Ga#$b|*wQml= zwgi|QqIaX;xQ3NKF(3)L!6DdC_Vj$C=@}CZAK;BdyGmk63CGM;{FCtHB~yR|YbJ$g zTOEhrPHD)BF#sO`ydn;H3Lc}>Iz}#n=6gVA04qVvbW8aO2Y^M58A|*V`bO(?TpyU# zn5c_|u{7KPgP3FdmI_sk?|>Qb0#Z7Y@m8f|=HLjJI{^)-6{pu<20c!GRzPZSJ8qU? zP)c8KQ@{T^K(uc{F=fLhOxl!@#_(@g--8=?>d6-yKYH_LlCd^ek69udTOD>hnWNTgvt?oV|WaVw+bB_WB^ z6;)^P7SlYybZp327(~ir$ZzpvIHDd~CZad#_BwI!9Aa5JV3iQNL=q2ad*GT>2wJc{ z$Q2n!x?d z*15#{GBjGQH|U#4e?s&mI(G?MU6~AH`%U6yU#282(^BLw$#_SZhNFO;Xnz^+eo8>p zv*xemw4#;Ox}@xik!#zywe`{f8*O11iXLvoZCCP!8<8&{I^drS`4gMw^yO6`S% zcWMz6;ygri_!7}nbzFyZEggn;bBz2z zJ1E0@MpqnStE^8IpBX3m3Ep*%N(Bvre&3vh?dS4JGZ@1(*mdQitHZ1;bx_>JN6;`@ zo)~5&gP|~$_1RV5AYBQwHcIm;R}Da7vr~kfVwrW6Xnj;>M72}MPK#=4H+HuGuM7Ig z;6BNSQA{HvX2*<}X!tnvQl0;aD#Wz0%!$=5}B@ht>u~iLgXGQa03m&f&!Sw2m;k4_a$*D zR-^yo5e|F+BGZgLm8yLK;~H91wgT(VR;hueV}}mRE-^b2`;!gpP&0B&I!0~;N@(^8 zEZM8H97=@xjFidU|94l;WOxSlYuFOxQ6vd()nqg zQR*p)iQxN2e;!fZNZF)kav=XXn0=h`++6R=M0NBaV524-*3i;PDk_6G?vNV9=tnY& zCn~Zn0}`3~eT4lP2}LY^qZ9VdRHS|}&DBpMX?$=IhyNH(dQAHhxXSwCK5F>oVbox{ zk_~r1Dqwe-M(Yu5G`tOI^fU<{h9ux)(%)eqiX;^b=_6C7xUWo6hLaSE^}=8-z0NhM z{S3$=rGbUea36{YONmDD{-Q@3T)`NbtCKNi>!b+&cs0~<5D!q=?}dvksUu>ddUOKU z*&c431f^)&c9Oe1uw~=^!GYe)*o=1l6`KHzXq$sksL zh!&6M1sUla+5^Kqe5k(Ah87)Si^jrW?QhL2F)AwpQ>9dAXPNW)rl@svll*u!bG!63 zcu2T4jdNijc*PyPd7Ta-n)kyDk*+=7>uI(`|5k;Bgaq34fp>rG;X_ULdLO6~7)?(N zk!+(q711&1wM5@I9(JdK*C~U{4vLgX5n$5m&GfqCgM}5J8ep&jQO%N>$AZ)Suv=_- z+zu+kOw}KtofVfjXe__aGK!pT$pXe-gydY%8ToGLciglnbs3TqCWvww3y8|IQ&Ynh z-gDn9zuCq{KULY6Loa2SXE7Fe;&y6ki6>!HmU$QO^m(3S>iI?9eUYax@$_Y$ewn9V z;pta-`Zb=u!V^u*Vp>$c&AWfe)4$>AYdrlfPhaQh8$5lJCqh_{=+(FQ_(we5XL|t7 zhG#*2{!6&Yk6`b^R4Jd&a67nsrj*I^SIWPfAH&}Wwhie0Ax80$;@;w(;wi*o{B-`2 z{Pz5Ke!Tdw?inge4GtFYki&5ihyN{PN%@L?JN^W0+~A$C{2HSI=88jj14Sg>9Ksve zu-~<>V;4Ut9~9F7qv2oYPo9AqG&S=ay|rQSjuqzdI;2O)WcEC*?~z@4wJ zTDSglm)i#X5K79d`Wq-Jb9n!|-TX!t=F<&u)lf4c)tpTLGN8Hhma}fj8pZE%~%y;;{gmizzl6J9-fQm_`a`T;T-raU1hqCR%_Fqt{GJiak zf+825Z(#3`jZ!yrSCp-+t9&sgaZb70d-X{Ry#sV90H!in{0Sba{V#MMT_0ogk7}36zdrFBpyWm$`q2HWO<*s_bY5)0r5NX~}VF^*Y>JMJ#PQ3LA98@snF9 zzzWORP4I=lLwg$}8yF#@w5MsIj&zsWBf#h`#dZxQ0-TZ*HY#5NQscQXQhoLdArL*I z5@@zIvU)_jCu^M{nPWKP^>46Dzxi2|HL*cbA7;iS@7X0|-D_L`)>1Yhqb9b$6nrJE zG1Ma6H^G|%NTbmhJ!pcKgfRJY^+8ms_nlxnM;onW?m^pj=2d$swwF#$8A-er?~D;` zR8j6c5w%@xOsmPd0?r*YkI6D*PRv7x{pMO`b z|Kr=guCL#@t6oI-takMn*WPNxoStB>H^&jPe2DdCu=X?pb(2vZ;feMWtsoe~9d^`_ z9g)>R25<0Wq)vE@zs7*OJc%(^1kM9^4D+(31}Hfk@gxUdeVWnE@zgJphNWZ+?&U<~ zB9=8lZ2}dT+7+8;-t(X#h|bzt=}G>RPTTq|^$)xo!+Tng#}QlaN{Eim8Km zqy8iEG4RY5Ht_tX33yg;Q|bbc;Z_8vKmlz+^JD;fP6D(q2xwzNRsRCsYz^8PsIM8I z{z?SY9Vp8(5m5gH6=t`&j4xczb6X&{02>n4k_p&NM9}?%ZegPU=>B$4>=u&H-2#ku z3kJF`>v;a31*3h?EnjVhZb08>Bk^GAiA#3#P6XXemdd0@=>8&rI!a4Gd(4$|5vK>*Ujt}w7Z)*t_V*2F ze;?m&55@u74@ICYyYPU?9IyRW0<;Aew*>3|52&*DrUHmVdiq%a>VbYhW%u-lg9xJH5%+cklM@M;BqHeDLX0Lewb zk1%UHH-Z}u zks2Py@Sb=48w5xK;zR_Hdi@IFwFi(TtcDSQ{A1)~G=ZEN3_#`+0NLYT1K0-OEMvjk z4Id@i4ZyX+>`wTErzUoumTiY{h6()}So)g6a@)Vbm0M!n0sjZs;~M2|c9-7e8rxkF zQWydVvax8EHitj$!sw3YT8X2Lpjq^M0X=mu_mO4fX^ePqQIljpWXXlSfp1>4)RDRD&0mZ=OjT?ETj z+=LE((Z-`F8hhMdSpvy0J!TkhxYn8Ohe)Q?2a(Jv-WCm`(-O?PcMf;=zQ@Nmc!#aS zE#Wn%Mm6kZ`AWd<-{P*4XR>ZBs8x!32c%U6pI|~8_5f_j!%lv&izmv?*nw&!s!BK# zQJmOdE8DL%uG0ms8vXy9N@k(G?1$NU8@*7;*2!=WGJ_iGSccyx)SX5K*2CJar1?P2 z-7(}b4Q)8b25-hFMy7CDp^CQpAxj7a#|8QCKVhoT)}8=_^DynN`RY3F#zc@nYx^@4 zNP3$`tBZU+ihcjF(~E58g6)<-DCS==C~374!{U~MF`Lw03-m?@(!j(`&0EvkODW0p ze7tdtBn&@-TC?tBEsFa6)j8W)I0p7VDb$|udV?aZs}bvW&R=mUMWC3wxk11 zKUGSAh~5_cyP4*rJW*9I|8Ybslb+z?UYy{xC0pI7CmAxs(b5jy!sAOdF*3e$eE;~xJiihNg9}C>eWZ#`es6x;_~$JCeYTj+r^Y@x H_Tv8r*JUwB literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/namedict.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/namedict.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..478cfb641ef6866944aa3cf2a1d2aa1a7f117fb9 GIT binary patch literal 3002 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/query.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/query.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5c42e2707366e8b5757f2ffeec5a7d5b3ebd22e5 GIT binary patch literal 17205 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 oR0v#l(ZOG(c(8mJ3bk literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/rcode.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/rcode.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d02380f3e5effb91f808b08ffa8499b749d8edf GIT binary patch literal 2675 zcmb_eTXWk)6yB9&OLm=m+N3EIJ!GIRsT115(3vzi7YD*nn~~E_t0~B?cax~LC3hva zO~!eE^cTP@GbE3^@e}v~`~to5yP%^yBkKs(pb?v-2;AJ;N@r87ODjEV~HhMK;GSK{>~i zGReMmFtJfAn-&k+jnG{884q$@I0z|rDPWdHTEq8ty9zYADuRZPKu99!2nIq50eR|< z17tIiUMv+Xt7Jv`X34q()yOCptb3cQTVF&*@%~2X&gxb%N)}7oTX(*UbgQs=w_MnW zj0gQL{lR_9Di^k4r9q{%y?S^1GhBPyE)@%rzP7q?uV9sHXf8fzB-*$RZ*T#?B^~nB z=tJd@9x5H$QNCB6Xl3#f5p&R)RU;+06w&7q-IpIEyj)rgo2|u`+q&j@L0D}xu3dL; zJib-m4HlUfwD!Y2-^1FXr~zfU*8a=%GIMKT&2P3=|Z&tnd zc)4`igy$;uTwO4$W~GAFN@c+e_qdz@=ju`63!De@`7Rew4!U=I(d?~cRo#FGung#w zi*-89ZKYzmJ96om-KNKzzUS6X(;S;*@vtqt0C%iZV9!b=CruTorTga?1WPs<>2AQ> zT{nzW7y{xv+IP_YNZsXOlxVkFTu6qqN~FmS`t+14C`gpr5q?w7`W%|lLrB`71|6pw z9feY(VgY(;C=Nbq@0A|61dR@4nmj>CJ|RralQjZ9uQ07nf_W$tbxkaUge8wCNP_XN zAN(F4?-UbHtBp1{xrZLe%t!m?PNTYu$7d!7E@i8)mTaJ018!ou&}-vqJ1%dq{_w&4 zGo}>Io->f~9-37U!WXf0gP>S8mrQVo74zoOtq#52y|mJhsaF9AR3X98!!#mdHaivg8U14U+D}qW;nowQ63GTQ3Zi z%bH=k)!^o{J-4>kQ#lx_-&aZ=<_wkMKVDZfDp{zu{m zsrA2d4cCrjH%ei8i~aoyuo0<2D1dp%_Eq@sY82?eG@kMsif%^QS8Gte>Gzs?(Y=ZA=;ye*w?yj_m*d literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/rdata.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/rdata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7980f98605d079fecba6951df8b4e1e74340ef8 GIT binary patch literal 13710 zcmd^GOKcp;dG5!&I2=+hE~VAJdZk^hC`**QyWaIfR^-(_ti+kMCBbV?v>6Sjnq&`$ z)1&I1B{?42jwO3Hj+4Ma5abesJO;T0IR?lz$RRL-0J$`B2;fU}N&q83AOuLh@2~Ej zA6zQnXD#ceyvcqQTwKKwUA8StSq)3s z%IVtcPQ$Tz?RMRUE9XL^Am?JEBNDYv0Gc8Y0Rw8HfGlkH4fR< zR!v$TZX9{f>OEbs{G)4C{Uh7rpS(HNIPy)a=X}FbrN*2;w`{Ajs@%65PvCyupU3@_ zs^b2*e?m>)vl~yUnwq(9HBPEobqMFD-m%nSb>zOKj`&aCa~sd#{-`>J`(yqyxPLaV z8qcY@hUXvId4AVwoKjDyd9*vNo>wQ-lj!*cbxNI7PvPoCw0&AVgSOB3rOuhoOK5*q zJ&Wsw&behrJ*Pa>`jm2SS_`L#)i>)mJ*`@CYw-c;yI?2fH@0Fwy8dqc0my4DxJhYK zw|XmnQj208^j4bjR^N}3so39)<@$k#dTj>|6QxHzI$QN-4cJ+gM~-?o*#<9uj+ zXk!$Pa_?7SR~6#INA^AYBkP{~rghKWwReiU7DiSae(PG;`@q++*YcKvUQ2Iz=JQ_A zi$gDnBX8B;^!#2sR2bBGZ%K!1e$N~9O@;RAptlxPJ^aFD&)fw=A6G5iYRA5gyvXn4 zI`);fw1uxk{Z`vwlomhZ%)K^C{y3!)j$=5Yr%|j}BkTRSZTlm8gujoh-~%UpnoCgMRBX!z3_7IO6PNH zE73*Oi~3vfYS`n|MYBBpt%udi-5`qF;d=kdB8MX5vWHJKL5W~_Yw>b7Y`4166U~tR#<99{%f!PlDI)r;r#EIL8zCJkQz--qgZez$Vp}q zn(9Ni`T~w@U7u~5Y5jtwEty)$)Y5COia7ZCDElP0>NyrqpujihdHskrt&YF<8C0EI z)|0#^yPdk76M_O>#Bq)9zKtS=RK)f@M;{$oJI=1PZJxOIoalwv9YMUep)R-W&99EE zH?8--yzPvfxUg2zUl~Dx$HkFz&pvLwZf)Cl7e`PKYen6`xv*y8Y@7G#TU(*_d|LNC zYh*)Zl!mXr6}4M^--}oG$a&C%bl)9>l=M`GY^(HFlY@O+0weTl}t68zI;|CZhKWPxQ+5%^OdAP6`9!W zF&7x&nKCV~u3ti@(FqimTeT}T4yVA-tf|3T(h$`9-6BH970Sf8l4em!k`KAgoN)w1Mg(M*GQnxEbp~uZ{6G z&G&DiSw!KriYM)wJ!fmGt2Q5GKlXeTNA!0ne5+vtPdLg3egFfmIKU6U1F*D3RZ?Y~ zORA!#a4xGwvEg>3qArRRw;NOHl2~!OQ8m`PF|Fp*6R2HN^XfRxGh(f+#;n+Ct8vI! z>c(O9ta=Xbk0?()kMmJj^V2vVQ!l6&ah_9W)Jr%&;m@m2tFvn1K5Qn?#JqZ0ol~EZ zyA$dabzWV7ZGTc#Ar7x5#T(S(!_#j-IeP7G3-n$NwJbw!^*u4>i%D54sgabl;-fa# zfIptecGqx3hf%=dSxsx?pae_dL(cGzulIsDXmx2{v7W|WRfQ*Lf6t|TpChYyckaM| z-?;-e5>AoIW^iCPvWJY?a6;Oe1N!*Jd`nh6pluym?;OUgKZOEFrV#nvu{c)KKK&Z7FOY7yoYU1I@AEa#KvSHE|X|u>21*O`+A}W zEDvoSTIPLm8BWPue03^q9)R4vtxrhM2UG}m5w`DT`seK&AEwHOJVo0}eYf6<51I}15Nq7IGiHxEoS$R$ zFuuOt@A~V04|w4%twX&~5cWt)p$=96nXB6Gg10|_x=Wn3js0v>j>9Iq{y{#&(s0Ji zFn!Y&)q>aAq$V^-KB+GsG^vdM3;)PT8DDANv^4#&Y#N2-pz9|Ux)B;SSQG0VGzWg` z_YRx`-{c_QMU@EW6)*c?q*L+-OkIEpTl$AGB>%cpP zx&Tn_6hJ-r!K9oqv8~U6_phz`?KMmmXh}5uKx;6mC{LWJCFHr#^(EN)!0#$hXhPsI zsX$E-1qNX&9MC6*f1jIfafc((L)6vA**3kMAJd*d5Sn=<41uAQ-x57eR45+-2!rjR zMUXF0U#Sq_a=o>NCCz&=U!JsuH(EgibofC_2jL*{{LQxCr}=`Rk?El$cGlM+NWQ+O zrI_0Yf?da#_DVoW(_x0QOZA;hE$eVyWOM=xAj$;8eV`$zWK-JZ5|dA?nG6+Vukw|p zJW#G>WtVYbi~$h29RnS7+%-p^gd61a=HT?;$xZ<>0&K3_Ko)(V- z;Y%&6Q|6PAgSsU=tq}L)x_q3HRjKQz@U@5b*@yPRuy~mk;i2sfE5_1(9yeDOri`j4 zG4w?imsoJ>&}yWOAh9u35*MyaCI!^;jUr+voAG{00CLiPUpJe7fjW_d?%>4K?2SGq9+-zc8&E{Y6YqB18ref1Kxq9MKa7ko2E~g(c z3$cqu7}+~Q-j0hq7pRuYbCyCU*9HBm0-$5COd+;|u+-mNgWeyd#L?1cK$JR+!xfy3m=t;#cv8?|7-vSKD1&LZ;XpTv7*C-0 zvp}KQUhn@k`iN#xSe04mz=~bq;S8%c1UIotzA{|5d}YXjh#x>i5G|M$`db~WPRChu zqcfrwZHSJm&zW~dXq2-?xb4>8HlAWpKZ}0!0*f5?>tDw$K#D-Tuke+GT=KX}Qi2D6 zx7qv&UZt#C#kf!4$nc)2@R&!=0IXZT^?w|B&u=#W@lhjZg@Z?Kg0qI^`V?rK(VN!@ z7zn-3#Nd0HBPuCnuZa<_n?aWjB6l*o7eaj!@^|5L{SzlaEnp!4a>AJ;K3_k^DTveh zs43{LViccf+@S4G_l$cF({vv%>5E_(=dp}?1p|BV@#E&}$4GA~&c`%vFv7n+V%+2t zS{43y&h0RrGKMF2>=+ifQ`klP1fznTDJBJi%dz&;zlyq=ZpOzLAJ{s!Xg2>Hbu#Od z#|X@;HnAOlJaZ&sesZ^kLL@d$aCr%V!)`QIScw~lYX+9ThNk<}mA;B+|AE7N+8G`) zx;4i%Z3Z&=zu z!-X-(cKBZA55VmNMqEdz(4+kU;4_xbm{fXnfca@C#5WN~6ZlA-F}P%ia^%*qE_BPV zi#Rz4P%}BwUJb*@2YfNz#9JJtnTTJZ~&$t#DvTAbTR>RaPZA$Qf)TZ zLp7idNNUaI-9f9Hz5#ksVH=MTI*z(w903_!06`2kdxcjthvJJEzWfqzzs%w~3mPl(3Dy&3Es!7~8U8B0PHyE$r7VA?3jbWkuE`;-+h~~oxXAoP9L(O>>WbYcd}tvriVWcW3Zkor z(u`@zFC&I3*-}I}E9!`vRyD*lr||r!no+Y7>#TkV(QZsbijF086M1O!{|INr9F;l_K#Qx-#L)UX zMdj?;-?LGxgj(elYrC>}W};0QZQlN>HLC1X*m7qIKDcdLcVB%EF2GK8RDqK)6;JQf zMpL+|#xtYpJ$qC}|366khh;(k43ax|M~GLf51remhcB!cHcdSQ6@uU3Gaw;_(5CSr zZlC@creF9%fS_T8%Q=A=Vu?*wzob%~0dCoRkoCMxahVhjExJ;$d7RQ-fZbH8xq8 z>3vp1e}nb&l}(B;V9Y0*aV8~`|4v+VVi;oIs$WI(d9L~?Tv!g%UnTs}eQ;1#P|g7r zR_RgVZ#ch)E5?>D(>R$_314sqbo0ojT+K|HoTRv+1IYHI41Erj_2*g0Z1#a&a^&iNj;Ep6 zi}#%EQm+u#sIH(W%Jm$(l7C54+Vkjb6tVUDpS9CWFLS#)&}x{jv-vCr#*GnQL%=a9NDO(ej6fTiUJdwpolH=}3@nl7DkK}B(KA#(VtI{$ z8t+`$)A*r%A+ei!fYyoorTRA)W|G;ondv>!t9U1>PLoUqH!-kHQFA&N#VO=3#eFqt+{9TP(o1ig<6hxX0z zGo-^JI)ZjXXrv~81yI9ixEj;_qU)HZp2c0kuE7V^KR}CHZN}I6qXUs^lpo>-42u{d zwp`4o0zu*6Rtm5&cmU!MmtdVX5r2nm1EV>#Y}A6Vkg#reQ|eSICbd|)?hp~p0VE%0nF7&E{tcMMVkYmgqcCP-c@PkthB2lUqq zr3+5$Be~{Lb9J(O#NMK6v>B*@4#<}{N8!lt(IFU z#Kq0v3^3<-IMLLlk!T`49qvs-4Q^Bu-v`w)Ql)Xc>&xCb7}|3t5TE6gF5QKh|Y~`Drf(LZLTw~Dd53-Eefth-nRB^CGN=_ji4T~?EW zMvxMbdRl;doQt=J8aU!RcbJA|g)B!WBRyvla1(9mQ7zU{pv74I2UBeNbL%~fGaCnU3g1aM%ivS+hU0^ifQgN3S(r&%%K2pUH=%ne< z38ya;oBtOYh9r1w8s?WI{~Ti~#91oVXbQf#kS2p6no(;d*BNO*>Hzf;E-!N%38F=^ z{Am_+$%pXum_AN7Pf$2TX=PeSB3lRaXPlNyIwyxD%?)Gy4^)xSAoTSz?PRj37*H1J zI#{PbQA6oJ1~sx!6rItia58iy8`bsJ){@`c(5=4F8Po}Tkk3J$#{ob`l*tdN1WM?^ zdYURgp0#xibJ9tdm};0U6oyShygLaT}n(iljh>BP3&ThhR-mjBBbX-Wc*>u z)D|+se7iVSUc+~8WlL2!jEPhTt_n zN+pqrXwDm17l>(K-|kA+kHcQthcV_rVm$>|X||P^?Gk1}+{%!*@y-T|X~Yg8JZxRd zz9e$Ww)AaYVg;W5O7&YRl|6@W3F=y7pAI-y__e&G5AM@Z;U>C8~~ZX?DoPA zG425j5GVqfxU)hk5wQ>(Om1zgLv-mW7}HN~)4#=n4u|CVlbMXn@;^2pX0!Rq3doh+ zTl)K`->6NJPsFQH6JY~M;jTsdVZe{j=r76eRa{s{xqF%Jjpp+#IDTHj3yBkiW}6M8 zA^I>1Y>5Q~%%fDPp5iltEo_v{_8`jKP3?TW&20{Zu+0{=GaZNjqCoc)dxhyuYe7zw zJp9L%Rca8-22O8&t?zR*htyzweQW%*G0Xqw(9Hk;hW!7A#*uWR{KRuYAnmbup2dqS z&Z5AkF>!%RPMZFuS($r$SNIA%Z~Xxu%IaO^m7udVTs3M?d~ap@Uqpw9lbbl#>q6X# zg~-)UQn_p-_X=I!=nWJFr^Xl>aM}28&Os;!e&(!GaBEc_cz>)iefT@pONY-F;CA5USZHZ)- ztM~!=5(ntH$TdLiV}br6UVF-4$RX*>QV%z7FGWdkc9-1Qotf{OS$;b_Tp(~A{dW1$ ziy|R^;-GispmPtN_zw`AID}JfG^s;%Yd9vSj>SzU!!0MvGfs|Y9h>Kzys$(@WJONc zBG2uYS*O7Byzrce!pYDnStiHSDMEiZoyCV7zX|z&@}p~h5G$|Qy!NGkW9QcHRy@apI66? zFZAmkJn%Xn7yz%S!)YetKL)!&xEJV%YD*5M7a7J_511dbb~>Y6Em?`}x`Edc zuA3BGw-xes6Z=KiebV-t-7h)UjR*oonur_;Bz7AX~Yq!)v zB+BO?Utec_YSuZ>Q`h?oJ;ZoaqzvUi=UlvyG(o7?-8*bv+kN{EyScD%W1(l3P;D8+ z@Ci(Vz^|{Db&RSKNgcFF7NmE6cvO2{C|v^>?=*5pe}upr57$*>(Ig@J#N+Lm4~qr)mcMAI;X@aSsX>6UL@mcaB%w0MFtJWtfC1C#&w6~F zWxndtOR#n<_$&jO3AqPMLgH$m{*AnUQ|y7=t(NEqQ0AiYxheO3i_F4O4P}9HQtRu(T@i+BXBIvf*>}s zUtWP;>5`m=CNZRNhOr8X{f3B?9|mv&1+m0G5ox2yqrhJlIfMcODldUZGQJY6Sbl>2 zY&(JzQ^?CW$l*!pH$_5M~5gV7In1Mi?)ksYls!Jt*DXcw<(%p^@Y~GBwAt(_se2kT)_Q`*bo?ho5^gn*QOvz;WZ)8;xV<$c>zlD?BF-9ajj@MO)c<^zq%tk5M{D2VvwneH!Qq zrnceWgG~it?8FD26S*VoAVS^cJyKhULgu^mu}ie&?Ah+Lt<>)I0*veR(nha03dLkd z^=7a4*~A@YPinoM2>ZR>KWdVsh>I`Zy&I3lcgOztZ9j-&cQ}0e9sk|IcMhLMcSR75 zkK=b~(4ZC@8PVZW$%ZLZfv8+dj>To=EBwheJhd`mbl^zKFRmbf8qqP8hs7jNL% zrJraPv(}(V6c12sL z#9FK;+KF*$oN2n2px!eR1ErOiC@YDD68HidjOqW}m!2C#tewC+DkPWAk|loZ_5FPx z`oPq%`Vu+Y4b~0PkFAW-tvh(??CtqMytj8}t_M7Du|Li5s_x6Pt8JgtJ6BZZ+43kb z>6{_EyPs?qba&ddv=U9mo|LO#8tJJY_;If%Tlgv0s34e;7f`e-sTFy{{d1q`X}#Cu zZDKGBHH-2^jC%)HL`_<=rC0eoy^x>!cD`bt&XYc*w8c@<*z!@%aF7Et(Q%mCz``BJ zIH=%W!M%z*E*zK5DJ5m=kW^BaOh9vuAy9t;Xvfo`7e#>NT!Ov$t;p$5r1XNgIDDQ# zE{QmahvPiTBp++_!ytA6zAylpX53-(meEkmhP4-!g=Q*g$g(ufg^)G5(>79b=mkpB z)S+-)oknpaX=5@5V0b;u_X)9>pj2x#aV`ygda*c_d9O~Nq=`NRn}uZk3x41b01X4} z(2TCqfuOD*n(}&VJl7N0)Wf>mPP9`1$C(ZgL66uP09Fr;=(mesH5}~oL_f99w3!*# z`LGSN#pq#k{|5ge*s+5awI(K3c^XwCTl24dK*LAdwb52KOBq;DXEvDNzBmBwzwg!g6mjncIAD z3z+#8vZIi7QNSL%e&j{vIpKtDzhuZkv9E-i;BxMY6&n>HyE-E`?jJDqi~VwyI)}OE zQ?TTXEv>J-MgM8w#uMokL=f2LnY$JC0J|pKK!y2Nsh8FHwDS>rP~D~<^&*_<(2K($t@MYUD@!12!k>hb z!)R(qp_G@5$IGz#O|%CR%^IK<)K{+H)rRIf+&t)Cpk`5Fi5`IKWv@ z03=}GC}}e@cNqZah;!-|U;q!CeHo4rn)v;LxrT&}I9o&3;_AZTzJgh=gHeB4 zFsp{6om+S{e!)Q@0k}`yAEN-I1C{~u>%y4n!DV5_`oMtMK>L|~MHAK)ZKjI~S}ks^ zaBKAneAKL8m0A+&Tf0K?YAe-EwJ-JCU+V2?<+~JQe5pIrMuF?^!^dIg>>6m0-$0Sp z;;a%QE;rmH%EPK7bq@m)H zrZ`M^kyd*>@3USn9$M0Ve2cl_g5e^wQ>7q6ncCo}KB-0R)B|aE{!Fe4l-P=sDzl zyK%`^+3~#0r=T>&c87}oL5M5~v}FkA{Bu7(hEc~rXB0{g)2cau(gj$BfpZWZIa{Ih zpZdWTdmUT(@Ts@u2=cz*@GIy2$USywwWyfD#l+soM-oSrXuB62QxeC|oVi2q_$ZWs zVfl12f}@W_6o!qFXM$e_63T92G4tMD1{t@>nS&R25SEwNB05S~T`*y9PlXB8kf(?C z_Bx2N2)&6`q(mZkhw&V<)nqDpgrw0CA~N1*X-hea=I&u>MF%{duR*SnVkk2|W9Qt5 zqJdF)>Jr1%^iRTYnD1k6Z&yy3b{4aBoyJS^Z|m1|YKS#1IjHw_pSeFM*1 z`i50P{7eq}lpv!IB_zn8Feu&vOOpzN&PGz1)c{IW1|DrzON>*bkcD+-AX-9-2Owku zg!TYtl=3kX>&(Oxiy#Tm0!Tt{^Q;0GGfr!XP2eG_upw3XEVgMpz^s1SAjkql0oG>q zXFpBqfT_O%Oucee0=DIOu|gAZ;Y!jd(~`9|lV-AV6(;{si~ciSrI_v<@ zwpAYha*0~%m+$zq=ReGLy`y5ox*MCXfIJB9kq=Bz0#nuvl7;itoRphYtx#72l1a3X z{vzz$%6l@99w8&F(2S<0M;U%Ow-Igl6fFY03YGfcIQF7PpE3xy%Y;!LRw9{^6X*9i zvz8H+KLyx2v5RDFP8+2#ipg`#z|z1B;qAMVVcfo>Fji?gMN|~TW~(j0Y_99Hi9Bef zO|dZmXqHfEo;t~PUC@xj6Jvh{TbPg5&B;>{cL6O01i9m}7YJ_wfBdqI+FI6JVpb^) ziFI&ZFbwJ>RTh){9nXbf;Aps@Q$1WtEMZ%_2be`ov_Bcb8OO^EWRnEHXeeCLlEsRm zu69Y-$btC`JYx zFO9-cTFbV;VQgx}-f)<x9|hl3MUn)eiJp|WL5*ZQ;j_PEQRXk=a(CFmF|J$ z7LFfhPLM^RQ;imL`*#XyqLc_}5t9D=7HxjYyARr?vV%o>JWG2lwJtF&t?fG}<4lDf@ZD1B{pI=ftUcH39Zdviqj_GlQ!5yG}20F;zak(6|ol)6?K56ZSk zhl-n2yiNsKY5A*EP+%dqsbH^xPF7M}kgjI={61tX&*_uB&l3$4L~yWl2bGBY9^0^t zrg3?rY1?b9TTKh!hHcwsvu>LRg?=5^cX&i`&SdN9t=N5m7Cu zSBNzDee^~<)n%&33<1j$+$z@T(eBQ+OU#lTw0)a6L_nt1_;(TU6F=x; z!QVxN(i!<%q8R@faiTwmi#Ic#y_e_^=f`~WVli3Eo^ups&dTtPUsB+{r= z5xJ9ae-pw@|EXY2|Kk70)vqPXnMCF`{OiiFijJ=Hxj3vOqX{%6^T6o86prcb9b3o7 z4=7?`v$mX=)3m0r|%&-xy}IAY{cZA>-4K4=y1a@d8$e;4HMcDgmH zBIT0SdgO?>G2<6PS~QtEUfiwk_@nXALp7}zt8|-4d45!^N$A1<384gm(1lfscPxqi u(pKq^BpImG{;v9WllSSM*-BXk2d60WZ_~8R&B~^=`A6E+zGye>jsF83=`bq* literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/rdatatype.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/rdatatype.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb7a47fdf64438762d9bc2698d09ce8776a54e22 GIT binary patch literal 5027 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/reversename.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/reversename.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..defb47f239fa750c297828e250e4f9d8b138b1c5 GIT binary patch literal 2526 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/set.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/set.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8c87dade943174a2c2410df2182001730accb212 GIT binary patch literal 7444 zcmd5>&2Jn@74M!IkK5yqIL^28)%kKf#&NRA@)5}H=4%&L0v|SkfW@lap4YZJ?&+R% z_pD>%TyTUqao~>Fy|F?WkL?29+AUx1ofyKm1C&KfMjM| ztZGlO5IxJ1ANc8pjdiX2; z2E~f8WjMx`DdyTxJoWVGmU-X!aO_!O%lO#bDtuy^#*@R3V6*_fu<5=Z`l;^*{wB3m zE6M;T=rc;z3>C-Py_l;2^!DQ7d=z?%i?iw-Ur(X740x({w6dIIzFLT>YpdvrREw=r z;swjPrNp718gUujpU+)Q>y4`ozj4J6lN399<+^|4@y)fBs$x^`_H^6iI0S!!*V!C;>mW^VKv+{ES3OPMT#gc+ zEt{+M+iC-kG>v_bI9kM8_BkQAR3VZrv5VPMIB6qcD-;tfksh`lgO>Drh(T_!f>@KT z)~TDT`JaktrF(Qu>}hXqWzKGfpzA84K`o>FHP35ca>gO3Q-@kPEFJVamRBvch8zHh z;O984LB|0g_)=nQ(HvA%F5W8Ef}~XhiaY$gRo3v|&8={>3|<^DwO{GZ+z82w z3$7qSlW@Zg+Y7up*e9_Sl}50V*j``tYpW`a2&0bOxk2o?f~+AkZD^ev)8;AtX1xiY zTp~kYQMoJ4R|i@ZA6BS6E9Sn(qb#@`DmGLz!x~WY#C<|YYeZSM(^P9&#ES{}(HN*8 z^jc<#MmA0;yNC6M^xJrCA4sRuBKWVg%?xG|8B75Xmk=mt*!uB62JuV|@rOGhRw3lo zK?b->fI#JUFAr}yK87WA;d+pd3S458fg2xZYd>fY`5|(w1e6H=$Pf-NIAOAqBU~J3 zigSz@_Zif3mKSE$dcgs~V-?qb0mcpv>2@OE*YqU2Yy+nvBFOo__Am>v{=c^MH9 zT$~~LBfQpQvsM8%dxUttFt!Ix@`2*WqxhmZk|x>C*K~N^T>n5tGx#3ESOWjkevGin zbt|`Eq+VQP9=x~+_ZK`Uhg)3iicoqU{Z``EJ>|>kMgwlmM$CuFJI0Bug!CJqK+%KB zA+|EZ?#fmNlo~%pW5OPztkUKoVxW4yz`B33_qw}Hb?5SP{(6ltFt6ShhLLWqex9Q- zsL)U>);-`0fb!`spyZo>rL*<3wm*k-heo1KP&q0fqkMc%Oh9guL<|J45x0{sgIlHJ zD8JZ&+E}k2<(Sc9a|h!63LS_C9i|!cNE&d{f+Ltdx+sR+VX|e%iEzC773FaRT- z)11R*RD8ol66p5y(zk5cCCwpqOv>^a+p9OyjXCN-qT1y^G*AmX zH~upPD>^G|s_?5?b8F=qa@M?!ho`4_Lx5~}BFlz(ZDdi4C)OkOnq9s6QfW%{=Esov z_a3$t)5-qs`6wvYd*V2MrH(XQqc{Rjwvghp%+8W(NUm@X%`@q36UazTAG{#ji>x3u z^c?3i4BJ8UY~FoC+IM-HrV6cM;Dvi_0B8y$9OrLcf-;g)?JqBh*O>cV4swX&{G&@& zo1aui4}b*m9!Kgp`51BXL=K-aDa{lu)8Coc4Li{f-~|Qj3LO9+XD^ zCMJZ|D0g{}+Wz*CSA<62GiYdVJ=h1DZ|#Hzw{rha;NTuY-4sHn&-=oo^2p90=7^Vg z$sXb)guAecg*IV-G~{FRZ1E&UyPYx#b;UAEY7hw&*B1$i!3g&m|}66#WV|2T|C2Lmc<;4 zYb@Siah(M(y}KMrCB6JXLER!u;7f8Jg=LirwqOecUp_qsG1Q!7PQLx+Ew3Ebh7MRbj!M>v3*;~hj`;Z@*Qrp literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/tokenizer.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/tokenizer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62ccb20e7f0e6ca2d78666cfaadddcfecdde8f0c GIT binary patch literal 14095 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 bm$NI5iPFuu4kCEz7rBTI=DzMsVOsqk!9Hy@ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/tsig.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/tsig.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37573f638767e2e44f0320edf3bc9afb0828e9ea GIT binary patch literal 6223 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/tsigkeyring.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/tsigkeyring.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a4a55b0073db9eab07efc621179c05329d2f5073 GIT binary patch literal 1080 zcma)5&2H2%5VoCUH{I?+)dLdh#V6Dtx+}G)0#uDH2iyiqhD0)8-G`g>IES z!F#aFjaSN*6R*ID8K;#BRBA2F*fX}j8P7LE=d?;p;X zA;)yiYPO&=$2fD>cr~fnee#8Z$F1F(*3J(3*n3NA3W?G4?|WtONh-r*F4DxLWf7|> zPs+l?X^|F3eBH=1a~fxSe|*4;IG2z3VXWo$W3FYQqzQNxr%LxYjI@B~#r!a}An-Va z2%jfuGU1b0^L0_^Az}>2El_*#FQB1C+Er#+$!9jFpwl>Tv2pQcv-Clgd4x$doi>rC z-_zlguudEL2T^z6*6;0+$*WP7RvT%dO`K&Lo9Wi^ z(~~1Tf&{9mnUn>tMnT6Gs!E1=dv{;x9b1WQdfibR=2QMionj*>F3Vq-I~O<|+MkG$wXarE)GvDzCe*l+z8yo-t literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/ttl.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/ttl.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cbc5e3e282ada314f650aa2960fc7dbf69e8bbbb GIT binary patch literal 1346 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/version.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..af7f2febc1a7770841f304df47c05fd0f15b6e06 GIT binary patch literal 475 zcmX|6O;5r=5Z&EwOXVXH4#tBqTp%G4YVc%Yh+ukvAS5O6urX)1rYUdh&mG z_AmA7iND~K_pkcnhf2s#Tx6l4xWx=U5r7B+R8U}ofg%*( zf+MSv179%z5>!bglgdmvAwqL6&{xnOfOhbuI^)Sn1#+pw(NkkjQqVg@GGHCjBT|8* zggN9BR(nL`pfDkgVps<^@OGQ|+O7I>DW`#~zDYlDuy)+p+FwmKs9SrABk#*GV3PeY zLa5iEmF%#Pscj9yVpi0!+MmYP^%yw9sG&zW+lKX%Z433jI~ZF?{n3H$tg$Fs=Fsd; z5FX5-&?ctU?+&9}I#iUO%WbN^iC@5$3H-K=&B`-8$7?!nu$eBG&9-y(a=myCjQ=0T m%19r#yj`T!dbR-R;D^-w9GJ-bNUB)CUHgp literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/__pycache__/wiredata.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/__pycache__/wiredata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9ee8c45a4e367d409e0853be03d127eabb6cd1b GIT binary patch literal 2267 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 16) & 0xffff) + return total & 0xffff + + +def make_ds(name, key, algorithm, origin=None): + """Create a DS record for a DNSSEC key. + + *name* is the owner name of the DS record. + + *key* is a ``dns.rdtypes.ANY.DNSKEY``. + + *algorithm* is a string describing which hash algorithm to use. The + currently supported hashes are "SHA1" and "SHA256". Case does not + matter for these strings. + + *origin* is a ``dns.name.Name`` and will be used as the origin + if *key* is a relative name. + + Returns a ``dns.rdtypes.ANY.DS``. + """ + + if algorithm.upper() == 'SHA1': + dsalg = 1 + hash = SHA1.new() + elif algorithm.upper() == 'SHA256': + dsalg = 2 + hash = SHA256.new() + else: + raise UnsupportedAlgorithm('unsupported algorithm "%s"' % algorithm) + + if isinstance(name, string_types): + name = dns.name.from_text(name, origin) + hash.update(name.canonicalize().to_wire()) + hash.update(_to_rdata(key, origin)) + digest = hash.digest() + + dsrdata = struct.pack("!HBB", key_id(key), key.algorithm, dsalg) + digest + return dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.DS, dsrdata, 0, + len(dsrdata)) + + +def _find_candidate_keys(keys, rrsig): + candidate_keys = [] + value = keys.get(rrsig.signer) + if value is None: + return None + if isinstance(value, dns.node.Node): + try: + rdataset = value.find_rdataset(dns.rdataclass.IN, + dns.rdatatype.DNSKEY) + except KeyError: + return None + else: + rdataset = value + for rdata in rdataset: + if rdata.algorithm == rrsig.algorithm and \ + key_id(rdata) == rrsig.key_tag: + candidate_keys.append(rdata) + return candidate_keys + + +def _is_rsa(algorithm): + return algorithm in (RSAMD5, RSASHA1, + RSASHA1NSEC3SHA1, RSASHA256, + RSASHA512) + + +def _is_dsa(algorithm): + return algorithm in (DSA, DSANSEC3SHA1) + + +def _is_ecdsa(algorithm): + return _have_ecdsa and (algorithm in (ECDSAP256SHA256, ECDSAP384SHA384)) + + +def _is_md5(algorithm): + return algorithm == RSAMD5 + + +def _is_sha1(algorithm): + return algorithm in (DSA, RSASHA1, + DSANSEC3SHA1, RSASHA1NSEC3SHA1) + + +def _is_sha256(algorithm): + return algorithm in (RSASHA256, ECDSAP256SHA256) + + +def _is_sha384(algorithm): + return algorithm == ECDSAP384SHA384 + + +def _is_sha512(algorithm): + return algorithm == RSASHA512 + + +def _make_hash(algorithm): + if _is_md5(algorithm): + return MD5.new() + if _is_sha1(algorithm): + return SHA1.new() + if _is_sha256(algorithm): + return SHA256.new() + if _is_sha384(algorithm): + return SHA384.new() + if _is_sha512(algorithm): + return SHA512.new() + raise ValidationFailure('unknown hash for algorithm %u' % algorithm) + + +def _make_algorithm_id(algorithm): + if _is_md5(algorithm): + oid = [0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05] + elif _is_sha1(algorithm): + oid = [0x2b, 0x0e, 0x03, 0x02, 0x1a] + elif _is_sha256(algorithm): + oid = [0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01] + elif _is_sha512(algorithm): + oid = [0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03] + else: + raise ValidationFailure('unknown algorithm %u' % algorithm) + olen = len(oid) + dlen = _make_hash(algorithm).digest_size + idbytes = [0x30] + [8 + olen + dlen] + \ + [0x30, olen + 4] + [0x06, olen] + oid + \ + [0x05, 0x00] + [0x04, dlen] + return struct.pack('!%dB' % len(idbytes), *idbytes) + + +def _validate_rrsig(rrset, rrsig, keys, origin=None, now=None): + """Validate an RRset against a single signature rdata + + The owner name of *rrsig* is assumed to be the same as the owner name + of *rrset*. + + *rrset* is the RRset to validate. It can be a ``dns.rrset.RRset`` or + a ``(dns.name.Name, dns.rdataset.Rdataset)`` tuple. + + *rrsig* is a ``dns.rdata.Rdata``, the signature to validate. + + *keys* is the key dictionary, used to find the DNSKEY associated with + a given name. The dictionary is keyed by a ``dns.name.Name``, and has + ``dns.node.Node`` or ``dns.rdataset.Rdataset`` values. + + *origin* is a ``dns.name.Name``, the origin to use for relative names. + + *now* is an ``int``, the time to use when validating the signatures, + in seconds since the UNIX epoch. The default is the current time. + """ + + if isinstance(origin, string_types): + origin = dns.name.from_text(origin, dns.name.root) + + candidate_keys = _find_candidate_keys(keys, rrsig) + if candidate_keys is None: + raise ValidationFailure('unknown key') + + for candidate_key in candidate_keys: + # For convenience, allow the rrset to be specified as a (name, + # rdataset) tuple as well as a proper rrset + if isinstance(rrset, tuple): + rrname = rrset[0] + rdataset = rrset[1] + else: + rrname = rrset.name + rdataset = rrset + + if now is None: + now = time.time() + if rrsig.expiration < now: + raise ValidationFailure('expired') + if rrsig.inception > now: + raise ValidationFailure('not yet valid') + + hash = _make_hash(rrsig.algorithm) + + if _is_rsa(rrsig.algorithm): + keyptr = candidate_key.key + (bytes_,) = struct.unpack('!B', keyptr[0:1]) + keyptr = keyptr[1:] + if bytes_ == 0: + (bytes_,) = struct.unpack('!H', keyptr[0:2]) + keyptr = keyptr[2:] + rsa_e = keyptr[0:bytes_] + rsa_n = keyptr[bytes_:] + try: + pubkey = CryptoRSA.construct( + (number.bytes_to_long(rsa_n), + number.bytes_to_long(rsa_e))) + except ValueError: + raise ValidationFailure('invalid public key') + sig = rrsig.signature + elif _is_dsa(rrsig.algorithm): + keyptr = candidate_key.key + (t,) = struct.unpack('!B', keyptr[0:1]) + keyptr = keyptr[1:] + octets = 64 + t * 8 + dsa_q = keyptr[0:20] + keyptr = keyptr[20:] + dsa_p = keyptr[0:octets] + keyptr = keyptr[octets:] + dsa_g = keyptr[0:octets] + keyptr = keyptr[octets:] + dsa_y = keyptr[0:octets] + pubkey = CryptoDSA.construct( + (number.bytes_to_long(dsa_y), + number.bytes_to_long(dsa_g), + number.bytes_to_long(dsa_p), + number.bytes_to_long(dsa_q))) + sig = rrsig.signature[1:] + elif _is_ecdsa(rrsig.algorithm): + # use ecdsa for NIST-384p -- not currently supported by pycryptodome + + keyptr = candidate_key.key + + if rrsig.algorithm == ECDSAP256SHA256: + curve = ecdsa.curves.NIST256p + key_len = 32 + elif rrsig.algorithm == ECDSAP384SHA384: + curve = ecdsa.curves.NIST384p + key_len = 48 + + x = number.bytes_to_long(keyptr[0:key_len]) + y = number.bytes_to_long(keyptr[key_len:key_len * 2]) + if not ecdsa.ecdsa.point_is_valid(curve.generator, x, y): + raise ValidationFailure('invalid ECDSA key') + point = ecdsa.ellipticcurve.Point(curve.curve, x, y, curve.order) + verifying_key = ecdsa.keys.VerifyingKey.from_public_point(point, + curve) + pubkey = ECKeyWrapper(verifying_key, key_len) + r = rrsig.signature[:key_len] + s = rrsig.signature[key_len:] + sig = ecdsa.ecdsa.Signature(number.bytes_to_long(r), + number.bytes_to_long(s)) + + else: + raise ValidationFailure('unknown algorithm %u' % rrsig.algorithm) + + hash.update(_to_rdata(rrsig, origin)[:18]) + hash.update(rrsig.signer.to_digestable(origin)) + + if rrsig.labels < len(rrname) - 1: + suffix = rrname.split(rrsig.labels + 1)[1] + rrname = dns.name.from_text('*', suffix) + rrnamebuf = rrname.to_digestable(origin) + rrfixed = struct.pack('!HHI', rdataset.rdtype, rdataset.rdclass, + rrsig.original_ttl) + rrlist = sorted(rdataset) + for rr in rrlist: + hash.update(rrnamebuf) + hash.update(rrfixed) + rrdata = rr.to_digestable(origin) + rrlen = struct.pack('!H', len(rrdata)) + hash.update(rrlen) + hash.update(rrdata) + + try: + if _is_rsa(rrsig.algorithm): + verifier = pkcs1_15.new(pubkey) + # will raise ValueError if verify fails: + verifier.verify(hash, sig) + elif _is_dsa(rrsig.algorithm): + verifier = DSS.new(pubkey, 'fips-186-3') + verifier.verify(hash, sig) + elif _is_ecdsa(rrsig.algorithm): + digest = hash.digest() + if not pubkey.verify(digest, sig): + raise ValueError + else: + # Raise here for code clarity; this won't actually ever happen + # since if the algorithm is really unknown we'd already have + # raised an exception above + raise ValidationFailure('unknown algorithm %u' % rrsig.algorithm) + # If we got here, we successfully verified so we can return without error + return + except ValueError: + # this happens on an individual validation failure + continue + # nothing verified -- raise failure: + raise ValidationFailure('verify failure') + + +def _validate(rrset, rrsigset, keys, origin=None, now=None): + """Validate an RRset. + + *rrset* is the RRset to validate. It can be a ``dns.rrset.RRset`` or + a ``(dns.name.Name, dns.rdataset.Rdataset)`` tuple. + + *rrsigset* is the signature RRset to be validated. It can be a + ``dns.rrset.RRset`` or a ``(dns.name.Name, dns.rdataset.Rdataset)`` tuple. + + *keys* is the key dictionary, used to find the DNSKEY associated with + a given name. The dictionary is keyed by a ``dns.name.Name``, and has + ``dns.node.Node`` or ``dns.rdataset.Rdataset`` values. + + *origin* is a ``dns.name.Name``, the origin to use for relative names. + + *now* is an ``int``, the time to use when validating the signatures, + in seconds since the UNIX epoch. The default is the current time. + """ + + if isinstance(origin, string_types): + origin = dns.name.from_text(origin, dns.name.root) + + if isinstance(rrset, tuple): + rrname = rrset[0] + else: + rrname = rrset.name + + if isinstance(rrsigset, tuple): + rrsigname = rrsigset[0] + rrsigrdataset = rrsigset[1] + else: + rrsigname = rrsigset.name + rrsigrdataset = rrsigset + + rrname = rrname.choose_relativity(origin) + rrsigname = rrsigname.choose_relativity(origin) + if rrname != rrsigname: + raise ValidationFailure("owner names do not match") + + for rrsig in rrsigrdataset: + try: + _validate_rrsig(rrset, rrsig, keys, origin, now) + return + except ValidationFailure: + pass + raise ValidationFailure("no RRSIGs validated") + + +def _need_pycrypto(*args, **kwargs): + raise NotImplementedError("DNSSEC validation requires pycryptodome/pycryptodomex") + + +try: + try: + # test we're using pycryptodome, not pycrypto (which misses SHA1 for example) + from Crypto.Hash import MD5, SHA1, SHA256, SHA384, SHA512 + from Crypto.PublicKey import RSA as CryptoRSA, DSA as CryptoDSA + from Crypto.Signature import pkcs1_15, DSS + from Crypto.Util import number + except ImportError: + from Cryptodome.Hash import MD5, SHA1, SHA256, SHA384, SHA512 + from Cryptodome.PublicKey import RSA as CryptoRSA, DSA as CryptoDSA + from Cryptodome.Signature import pkcs1_15, DSS + from Cryptodome.Util import number +except ImportError: + validate = _need_pycrypto + validate_rrsig = _need_pycrypto + _have_pycrypto = False + _have_ecdsa = False +else: + validate = _validate + validate_rrsig = _validate_rrsig + _have_pycrypto = True + + try: + import ecdsa + import ecdsa.ecdsa + import ecdsa.ellipticcurve + import ecdsa.keys + except ImportError: + _have_ecdsa = False + else: + _have_ecdsa = True + + class ECKeyWrapper(object): + + def __init__(self, key, key_len): + self.key = key + self.key_len = key_len + + def verify(self, digest, sig): + diglong = number.bytes_to_long(digest) + return self.key.pubkey.verifies(diglong, sig) diff --git a/env/lib/python3.7/site-packages/dns/e164.py b/env/lib/python3.7/site-packages/dns/e164.py new file mode 100644 index 0000000..758c47a --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/e164.py @@ -0,0 +1,105 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2006-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS E.164 helpers.""" + +import dns.exception +import dns.name +import dns.resolver +from ._compat import string_types, maybe_decode + +#: The public E.164 domain. +public_enum_domain = dns.name.from_text('e164.arpa.') + + +def from_e164(text, origin=public_enum_domain): + """Convert an E.164 number in textual form into a Name object whose + value is the ENUM domain name for that number. + + Non-digits in the text are ignored, i.e. "16505551212", + "+1.650.555.1212" and "1 (650) 555-1212" are all the same. + + *text*, a ``text``, is an E.164 number in textual form. + + *origin*, a ``dns.name.Name``, the domain in which the number + should be constructed. The default is ``e164.arpa.``. + + Returns a ``dns.name.Name``. + """ + + parts = [d for d in text if d.isdigit()] + parts.reverse() + return dns.name.from_text('.'.join(parts), origin=origin) + + +def to_e164(name, origin=public_enum_domain, want_plus_prefix=True): + """Convert an ENUM domain name into an E.164 number. + + Note that dnspython does not have any information about preferred + number formats within national numbering plans, so all numbers are + emitted as a simple string of digits, prefixed by a '+' (unless + *want_plus_prefix* is ``False``). + + *name* is a ``dns.name.Name``, the ENUM domain name. + + *origin* is a ``dns.name.Name``, a domain containing the ENUM + domain name. The name is relativized to this domain before being + converted to text. If ``None``, no relativization is done. + + *want_plus_prefix* is a ``bool``. If True, add a '+' to the beginning of + the returned number. + + Returns a ``text``. + + """ + if origin is not None: + name = name.relativize(origin) + dlabels = [d for d in name.labels if d.isdigit() and len(d) == 1] + if len(dlabels) != len(name.labels): + raise dns.exception.SyntaxError('non-digit labels in ENUM domain name') + dlabels.reverse() + text = b''.join(dlabels) + if want_plus_prefix: + text = b'+' + text + return maybe_decode(text) + + +def query(number, domains, resolver=None): + """Look for NAPTR RRs for the specified number in the specified domains. + + e.g. lookup('16505551212', ['e164.dnspython.org.', 'e164.arpa.']) + + *number*, a ``text`` is the number to look for. + + *domains* is an iterable containing ``dns.name.Name`` values. + + *resolver*, a ``dns.resolver.Resolver``, is the resolver to use. If + ``None``, the default resolver is used. + """ + + if resolver is None: + resolver = dns.resolver.get_default_resolver() + e_nx = dns.resolver.NXDOMAIN() + for domain in domains: + if isinstance(domain, string_types): + domain = dns.name.from_text(domain) + qname = dns.e164.from_e164(number, domain) + try: + return resolver.query(qname, 'NAPTR') + except dns.resolver.NXDOMAIN as e: + e_nx += e + raise e_nx diff --git a/env/lib/python3.7/site-packages/dns/edns.py b/env/lib/python3.7/site-packages/dns/edns.py new file mode 100644 index 0000000..5660f7b --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/edns.py @@ -0,0 +1,269 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2009-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""EDNS Options""" + +from __future__ import absolute_import + +import math +import struct + +import dns.inet + +#: NSID +NSID = 3 +#: DAU +DAU = 5 +#: DHU +DHU = 6 +#: N3U +N3U = 7 +#: ECS (client-subnet) +ECS = 8 +#: EXPIRE +EXPIRE = 9 +#: COOKIE +COOKIE = 10 +#: KEEPALIVE +KEEPALIVE = 11 +#: PADDING +PADDING = 12 +#: CHAIN +CHAIN = 13 + +class Option(object): + + """Base class for all EDNS option types.""" + + def __init__(self, otype): + """Initialize an option. + + *otype*, an ``int``, is the option type. + """ + self.otype = otype + + def to_wire(self, file): + """Convert an option to wire format. + """ + raise NotImplementedError + + @classmethod + def from_wire(cls, otype, wire, current, olen): + """Build an EDNS option object from wire format. + + *otype*, an ``int``, is the option type. + + *wire*, a ``binary``, is the wire-format message. + + *current*, an ``int``, is the offset in *wire* of the beginning + of the rdata. + + *olen*, an ``int``, is the length of the wire-format option data + + Returns a ``dns.edns.Option``. + """ + + raise NotImplementedError + + def _cmp(self, other): + """Compare an EDNS option with another option of the same type. + + Returns < 0 if < *other*, 0 if == *other*, and > 0 if > *other*. + """ + raise NotImplementedError + + def __eq__(self, other): + if not isinstance(other, Option): + return False + if self.otype != other.otype: + return False + return self._cmp(other) == 0 + + def __ne__(self, other): + if not isinstance(other, Option): + return False + if self.otype != other.otype: + return False + return self._cmp(other) != 0 + + def __lt__(self, other): + if not isinstance(other, Option) or \ + self.otype != other.otype: + return NotImplemented + return self._cmp(other) < 0 + + def __le__(self, other): + if not isinstance(other, Option) or \ + self.otype != other.otype: + return NotImplemented + return self._cmp(other) <= 0 + + def __ge__(self, other): + if not isinstance(other, Option) or \ + self.otype != other.otype: + return NotImplemented + return self._cmp(other) >= 0 + + def __gt__(self, other): + if not isinstance(other, Option) or \ + self.otype != other.otype: + return NotImplemented + return self._cmp(other) > 0 + + +class GenericOption(Option): + + """Generic Option Class + + This class is used for EDNS option types for which we have no better + implementation. + """ + + def __init__(self, otype, data): + super(GenericOption, self).__init__(otype) + self.data = data + + def to_wire(self, file): + file.write(self.data) + + def to_text(self): + return "Generic %d" % self.otype + + @classmethod + def from_wire(cls, otype, wire, current, olen): + return cls(otype, wire[current: current + olen]) + + def _cmp(self, other): + if self.data == other.data: + return 0 + if self.data > other.data: + return 1 + return -1 + + +class ECSOption(Option): + """EDNS Client Subnet (ECS, RFC7871)""" + + def __init__(self, address, srclen=None, scopelen=0): + """*address*, a ``text``, is the client address information. + + *srclen*, an ``int``, the source prefix length, which is the + leftmost number of bits of the address to be used for the + lookup. The default is 24 for IPv4 and 56 for IPv6. + + *scopelen*, an ``int``, the scope prefix length. This value + must be 0 in queries, and should be set in responses. + """ + + super(ECSOption, self).__init__(ECS) + af = dns.inet.af_for_address(address) + + if af == dns.inet.AF_INET6: + self.family = 2 + if srclen is None: + srclen = 56 + elif af == dns.inet.AF_INET: + self.family = 1 + if srclen is None: + srclen = 24 + else: + raise ValueError('Bad ip family') + + self.address = address + self.srclen = srclen + self.scopelen = scopelen + + addrdata = dns.inet.inet_pton(af, address) + nbytes = int(math.ceil(srclen/8.0)) + + # Truncate to srclen and pad to the end of the last octet needed + # See RFC section 6 + self.addrdata = addrdata[:nbytes] + nbits = srclen % 8 + if nbits != 0: + last = struct.pack('B', ord(self.addrdata[-1:]) & (0xff << nbits)) + self.addrdata = self.addrdata[:-1] + last + + def to_text(self): + return "ECS {}/{} scope/{}".format(self.address, self.srclen, + self.scopelen) + + def to_wire(self, file): + file.write(struct.pack('!H', self.family)) + file.write(struct.pack('!BB', self.srclen, self.scopelen)) + file.write(self.addrdata) + + @classmethod + def from_wire(cls, otype, wire, cur, olen): + family, src, scope = struct.unpack('!HBB', wire[cur:cur+4]) + cur += 4 + + addrlen = int(math.ceil(src/8.0)) + + if family == 1: + af = dns.inet.AF_INET + pad = 4 - addrlen + elif family == 2: + af = dns.inet.AF_INET6 + pad = 16 - addrlen + else: + raise ValueError('unsupported family') + + addr = dns.inet.inet_ntop(af, wire[cur:cur+addrlen] + b'\x00' * pad) + return cls(addr, src, scope) + + def _cmp(self, other): + if self.addrdata == other.addrdata: + return 0 + if self.addrdata > other.addrdata: + return 1 + return -1 + +_type_to_class = { + ECS: ECSOption +} + +def get_option_class(otype): + """Return the class for the specified option type. + + The GenericOption class is used if a more specific class is not + known. + """ + + cls = _type_to_class.get(otype) + if cls is None: + cls = GenericOption + return cls + + +def option_from_wire(otype, wire, current, olen): + """Build an EDNS option object from wire format. + + *otype*, an ``int``, is the option type. + + *wire*, a ``binary``, is the wire-format message. + + *current*, an ``int``, is the offset in *wire* of the beginning + of the rdata. + + *olen*, an ``int``, is the length of the wire-format option data + + Returns an instance of a subclass of ``dns.edns.Option``. + """ + + cls = get_option_class(otype) + return cls.from_wire(otype, wire, current, olen) diff --git a/env/lib/python3.7/site-packages/dns/entropy.py b/env/lib/python3.7/site-packages/dns/entropy.py new file mode 100644 index 0000000..00c6a4b --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/entropy.py @@ -0,0 +1,148 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2009-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import os +import random +import time +from ._compat import long, binary_type +try: + import threading as _threading +except ImportError: + import dummy_threading as _threading + + +class EntropyPool(object): + + # This is an entropy pool for Python implementations that do not + # have a working SystemRandom. I'm not sure there are any, but + # leaving this code doesn't hurt anything as the library code + # is used if present. + + def __init__(self, seed=None): + self.pool_index = 0 + self.digest = None + self.next_byte = 0 + self.lock = _threading.Lock() + try: + import hashlib + self.hash = hashlib.sha1() + self.hash_len = 20 + except ImportError: + try: + import sha + self.hash = sha.new() + self.hash_len = 20 + except ImportError: + import md5 # pylint: disable=import-error + self.hash = md5.new() + self.hash_len = 16 + self.pool = bytearray(b'\0' * self.hash_len) + if seed is not None: + self.stir(bytearray(seed)) + self.seeded = True + self.seed_pid = os.getpid() + else: + self.seeded = False + self.seed_pid = 0 + + def stir(self, entropy, already_locked=False): + if not already_locked: + self.lock.acquire() + try: + for c in entropy: + if self.pool_index == self.hash_len: + self.pool_index = 0 + b = c & 0xff + self.pool[self.pool_index] ^= b + self.pool_index += 1 + finally: + if not already_locked: + self.lock.release() + + def _maybe_seed(self): + if not self.seeded or self.seed_pid != os.getpid(): + try: + seed = os.urandom(16) + except Exception: + try: + r = open('/dev/urandom', 'rb', 0) + try: + seed = r.read(16) + finally: + r.close() + except Exception: + seed = str(time.time()) + self.seeded = True + self.seed_pid = os.getpid() + self.digest = None + seed = bytearray(seed) + self.stir(seed, True) + + def random_8(self): + self.lock.acquire() + try: + self._maybe_seed() + if self.digest is None or self.next_byte == self.hash_len: + self.hash.update(binary_type(self.pool)) + self.digest = bytearray(self.hash.digest()) + self.stir(self.digest, True) + self.next_byte = 0 + value = self.digest[self.next_byte] + self.next_byte += 1 + finally: + self.lock.release() + return value + + def random_16(self): + return self.random_8() * 256 + self.random_8() + + def random_32(self): + return self.random_16() * 65536 + self.random_16() + + def random_between(self, first, last): + size = last - first + 1 + if size > long(4294967296): + raise ValueError('too big') + if size > 65536: + rand = self.random_32 + max = long(4294967295) + elif size > 256: + rand = self.random_16 + max = 65535 + else: + rand = self.random_8 + max = 255 + return first + size * rand() // (max + 1) + +pool = EntropyPool() + +try: + system_random = random.SystemRandom() +except Exception: + system_random = None + +def random_16(): + if system_random is not None: + return system_random.randrange(0, 65536) + else: + return pool.random_16() + +def between(first, last): + if system_random is not None: + return system_random.randrange(first, last + 1) + else: + return pool.random_between(first, last) diff --git a/env/lib/python3.7/site-packages/dns/exception.py b/env/lib/python3.7/site-packages/dns/exception.py new file mode 100644 index 0000000..71ff04f --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/exception.py @@ -0,0 +1,128 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Common DNS Exceptions. + +Dnspython modules may also define their own exceptions, which will +always be subclasses of ``DNSException``. +""" + +class DNSException(Exception): + """Abstract base class shared by all dnspython exceptions. + + It supports two basic modes of operation: + + a) Old/compatible mode is used if ``__init__`` was called with + empty *kwargs*. In compatible mode all *args* are passed + to the standard Python Exception class as before and all *args* are + printed by the standard ``__str__`` implementation. Class variable + ``msg`` (or doc string if ``msg`` is ``None``) is returned from ``str()`` + if *args* is empty. + + b) New/parametrized mode is used if ``__init__`` was called with + non-empty *kwargs*. + In the new mode *args* must be empty and all kwargs must match + those set in class variable ``supp_kwargs``. All kwargs are stored inside + ``self.kwargs`` and used in a new ``__str__`` implementation to construct + a formatted message based on the ``fmt`` class variable, a ``string``. + + In the simplest case it is enough to override the ``supp_kwargs`` + and ``fmt`` class variables to get nice parametrized messages. + """ + + msg = None # non-parametrized message + supp_kwargs = set() # accepted parameters for _fmt_kwargs (sanity check) + fmt = None # message parametrized with results from _fmt_kwargs + + def __init__(self, *args, **kwargs): + self._check_params(*args, **kwargs) + if kwargs: + self.kwargs = self._check_kwargs(**kwargs) + self.msg = str(self) + else: + self.kwargs = dict() # defined but empty for old mode exceptions + if self.msg is None: + # doc string is better implicit message than empty string + self.msg = self.__doc__ + if args: + super(DNSException, self).__init__(*args) + else: + super(DNSException, self).__init__(self.msg) + + def _check_params(self, *args, **kwargs): + """Old exceptions supported only args and not kwargs. + + For sanity we do not allow to mix old and new behavior.""" + if args or kwargs: + assert bool(args) != bool(kwargs), \ + 'keyword arguments are mutually exclusive with positional args' + + def _check_kwargs(self, **kwargs): + if kwargs: + assert set(kwargs.keys()) == self.supp_kwargs, \ + 'following set of keyword args is required: %s' % ( + self.supp_kwargs) + return kwargs + + def _fmt_kwargs(self, **kwargs): + """Format kwargs before printing them. + + Resulting dictionary has to have keys necessary for str.format call + on fmt class variable. + """ + fmtargs = {} + for kw, data in kwargs.items(): + if isinstance(data, (list, set)): + # convert list of to list of str() + fmtargs[kw] = list(map(str, data)) + if len(fmtargs[kw]) == 1: + # remove list brackets [] from single-item lists + fmtargs[kw] = fmtargs[kw].pop() + else: + fmtargs[kw] = data + return fmtargs + + def __str__(self): + if self.kwargs and self.fmt: + # provide custom message constructed from keyword arguments + fmtargs = self._fmt_kwargs(**self.kwargs) + return self.fmt.format(**fmtargs) + else: + # print *args directly in the same way as old DNSException + return super(DNSException, self).__str__() + + +class FormError(DNSException): + """DNS message is malformed.""" + + +class SyntaxError(DNSException): + """Text input is malformed.""" + + +class UnexpectedEnd(SyntaxError): + """Text input ended unexpectedly.""" + + +class TooBig(DNSException): + """The DNS message is too big.""" + + +class Timeout(DNSException): + """The DNS operation timed out.""" + supp_kwargs = {'timeout'} + fmt = "The DNS operation timed out after {timeout} seconds" diff --git a/env/lib/python3.7/site-packages/dns/flags.py b/env/lib/python3.7/site-packages/dns/flags.py new file mode 100644 index 0000000..0119dec --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/flags.py @@ -0,0 +1,130 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Message Flags.""" + +# Standard DNS flags + +#: Query Response +QR = 0x8000 +#: Authoritative Answer +AA = 0x0400 +#: Truncated Response +TC = 0x0200 +#: Recursion Desired +RD = 0x0100 +#: Recursion Available +RA = 0x0080 +#: Authentic Data +AD = 0x0020 +#: Checking Disabled +CD = 0x0010 + +# EDNS flags + +#: DNSSEC answer OK +DO = 0x8000 + +_by_text = { + 'QR': QR, + 'AA': AA, + 'TC': TC, + 'RD': RD, + 'RA': RA, + 'AD': AD, + 'CD': CD +} + +_edns_by_text = { + 'DO': DO +} + + +# We construct the inverse mappings programmatically to ensure that we +# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that +# would cause the mappings not to be true inverses. + +_by_value = {y: x for x, y in _by_text.items()} + +_edns_by_value = {y: x for x, y in _edns_by_text.items()} + + +def _order_flags(table): + order = list(table.items()) + order.sort() + order.reverse() + return order + +_flags_order = _order_flags(_by_value) + +_edns_flags_order = _order_flags(_edns_by_value) + + +def _from_text(text, table): + flags = 0 + tokens = text.split() + for t in tokens: + flags = flags | table[t.upper()] + return flags + + +def _to_text(flags, table, order): + text_flags = [] + for k, v in order: + if flags & k != 0: + text_flags.append(v) + return ' '.join(text_flags) + + +def from_text(text): + """Convert a space-separated list of flag text values into a flags + value. + + Returns an ``int`` + """ + + return _from_text(text, _by_text) + + +def to_text(flags): + """Convert a flags value into a space-separated list of flag text + values. + + Returns a ``text``. + """ + + return _to_text(flags, _by_value, _flags_order) + + +def edns_from_text(text): + """Convert a space-separated list of EDNS flag text values into a EDNS + flags value. + + Returns an ``int`` + """ + + return _from_text(text, _edns_by_text) + + +def edns_to_text(flags): + """Convert an EDNS flags value into a space-separated list of EDNS flag + text values. + + Returns a ``text``. + """ + + return _to_text(flags, _edns_by_value, _edns_flags_order) diff --git a/env/lib/python3.7/site-packages/dns/grange.py b/env/lib/python3.7/site-packages/dns/grange.py new file mode 100644 index 0000000..ffe8be7 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/grange.py @@ -0,0 +1,69 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2012-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS GENERATE range conversion.""" + +import dns + +def from_text(text): + """Convert the text form of a range in a ``$GENERATE`` statement to an + integer. + + *text*, a ``str``, the textual range in ``$GENERATE`` form. + + Returns a tuple of three ``int`` values ``(start, stop, step)``. + """ + + # TODO, figure out the bounds on start, stop and step. + step = 1 + cur = '' + state = 0 + # state 0 1 2 3 4 + # x - y / z + + if text and text[0] == '-': + raise dns.exception.SyntaxError("Start cannot be a negative number") + + for c in text: + if c == '-' and state == 0: + start = int(cur) + cur = '' + state = 2 + elif c == '/': + stop = int(cur) + cur = '' + state = 4 + elif c.isdigit(): + cur += c + else: + raise dns.exception.SyntaxError("Could not parse %s" % (c)) + + if state in (1, 3): + raise dns.exception.SyntaxError() + + if state == 2: + stop = int(cur) + + if state == 4: + step = int(cur) + + assert step >= 1 + assert start >= 0 + assert start <= stop + # TODO, can start == stop? + + return (start, stop, step) diff --git a/env/lib/python3.7/site-packages/dns/hash.py b/env/lib/python3.7/site-packages/dns/hash.py new file mode 100644 index 0000000..1713e62 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/hash.py @@ -0,0 +1,37 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Hashing backwards compatibility wrapper""" + +import hashlib +import warnings + +warnings.warn( + "dns.hash module will be removed in future versions. Please use hashlib instead.", + DeprecationWarning) + +hashes = {} +hashes['MD5'] = hashlib.md5 +hashes['SHA1'] = hashlib.sha1 +hashes['SHA224'] = hashlib.sha224 +hashes['SHA256'] = hashlib.sha256 +hashes['SHA384'] = hashlib.sha384 +hashes['SHA512'] = hashlib.sha512 + + +def get(algorithm): + return hashes[algorithm.upper()] diff --git a/env/lib/python3.7/site-packages/dns/inet.py b/env/lib/python3.7/site-packages/dns/inet.py new file mode 100644 index 0000000..c8d7c1b --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/inet.py @@ -0,0 +1,124 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Generic Internet address helper functions.""" + +import socket + +import dns.ipv4 +import dns.ipv6 + +from ._compat import maybe_ord + +# We assume that AF_INET is always defined. + +AF_INET = socket.AF_INET + +# AF_INET6 might not be defined in the socket module, but we need it. +# We'll try to use the socket module's value, and if it doesn't work, +# we'll use our own value. + +try: + AF_INET6 = socket.AF_INET6 +except AttributeError: + AF_INET6 = 9999 + + +def inet_pton(family, text): + """Convert the textual form of a network address into its binary form. + + *family* is an ``int``, the address family. + + *text* is a ``text``, the textual address. + + Raises ``NotImplementedError`` if the address family specified is not + implemented. + + Returns a ``binary``. + """ + + if family == AF_INET: + return dns.ipv4.inet_aton(text) + elif family == AF_INET6: + return dns.ipv6.inet_aton(text) + else: + raise NotImplementedError + + +def inet_ntop(family, address): + """Convert the binary form of a network address into its textual form. + + *family* is an ``int``, the address family. + + *address* is a ``binary``, the network address in binary form. + + Raises ``NotImplementedError`` if the address family specified is not + implemented. + + Returns a ``text``. + """ + + if family == AF_INET: + return dns.ipv4.inet_ntoa(address) + elif family == AF_INET6: + return dns.ipv6.inet_ntoa(address) + else: + raise NotImplementedError + + +def af_for_address(text): + """Determine the address family of a textual-form network address. + + *text*, a ``text``, the textual address. + + Raises ``ValueError`` if the address family cannot be determined + from the input. + + Returns an ``int``. + """ + + try: + dns.ipv4.inet_aton(text) + return AF_INET + except Exception: + try: + dns.ipv6.inet_aton(text) + return AF_INET6 + except: + raise ValueError + + +def is_multicast(text): + """Is the textual-form network address a multicast address? + + *text*, a ``text``, the textual address. + + Raises ``ValueError`` if the address family cannot be determined + from the input. + + Returns a ``bool``. + """ + + try: + first = maybe_ord(dns.ipv4.inet_aton(text)[0]) + return first >= 224 and first <= 239 + except Exception: + try: + first = maybe_ord(dns.ipv6.inet_aton(text)[0]) + return first == 255 + except Exception: + raise ValueError diff --git a/env/lib/python3.7/site-packages/dns/ipv4.py b/env/lib/python3.7/site-packages/dns/ipv4.py new file mode 100644 index 0000000..8fc4f7d --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/ipv4.py @@ -0,0 +1,63 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""IPv4 helper functions.""" + +import struct + +import dns.exception +from ._compat import binary_type + +def inet_ntoa(address): + """Convert an IPv4 address in binary form to text form. + + *address*, a ``binary``, the IPv4 address in binary form. + + Returns a ``text``. + """ + + if len(address) != 4: + raise dns.exception.SyntaxError + if not isinstance(address, bytearray): + address = bytearray(address) + return ('%u.%u.%u.%u' % (address[0], address[1], + address[2], address[3])) + +def inet_aton(text): + """Convert an IPv4 address in text form to binary form. + + *text*, a ``text``, the IPv4 address in textual form. + + Returns a ``binary``. + """ + + if not isinstance(text, binary_type): + text = text.encode() + parts = text.split(b'.') + if len(parts) != 4: + raise dns.exception.SyntaxError + for part in parts: + if not part.isdigit(): + raise dns.exception.SyntaxError + if len(part) > 1 and part[0] == '0': + # No leading zeros + raise dns.exception.SyntaxError + try: + bytes = [int(part) for part in parts] + return struct.pack('BBBB', *bytes) + except: + raise dns.exception.SyntaxError diff --git a/env/lib/python3.7/site-packages/dns/ipv6.py b/env/lib/python3.7/site-packages/dns/ipv6.py new file mode 100644 index 0000000..128e56c --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/ipv6.py @@ -0,0 +1,181 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""IPv6 helper functions.""" + +import re +import binascii + +import dns.exception +import dns.ipv4 +from ._compat import xrange, binary_type, maybe_decode + +_leading_zero = re.compile(r'0+([0-9a-f]+)') + +def inet_ntoa(address): + """Convert an IPv6 address in binary form to text form. + + *address*, a ``binary``, the IPv6 address in binary form. + + Raises ``ValueError`` if the address isn't 16 bytes long. + Returns a ``text``. + """ + + if len(address) != 16: + raise ValueError("IPv6 addresses are 16 bytes long") + hex = binascii.hexlify(address) + chunks = [] + i = 0 + l = len(hex) + while i < l: + chunk = maybe_decode(hex[i : i + 4]) + # strip leading zeros. we do this with an re instead of + # with lstrip() because lstrip() didn't support chars until + # python 2.2.2 + m = _leading_zero.match(chunk) + if not m is None: + chunk = m.group(1) + chunks.append(chunk) + i += 4 + # + # Compress the longest subsequence of 0-value chunks to :: + # + best_start = 0 + best_len = 0 + start = -1 + last_was_zero = False + for i in xrange(8): + if chunks[i] != '0': + if last_was_zero: + end = i + current_len = end - start + if current_len > best_len: + best_start = start + best_len = current_len + last_was_zero = False + elif not last_was_zero: + start = i + last_was_zero = True + if last_was_zero: + end = 8 + current_len = end - start + if current_len > best_len: + best_start = start + best_len = current_len + if best_len > 1: + if best_start == 0 and \ + (best_len == 6 or + best_len == 5 and chunks[5] == 'ffff'): + # We have an embedded IPv4 address + if best_len == 6: + prefix = '::' + else: + prefix = '::ffff:' + hex = prefix + dns.ipv4.inet_ntoa(address[12:]) + else: + hex = ':'.join(chunks[:best_start]) + '::' + \ + ':'.join(chunks[best_start + best_len:]) + else: + hex = ':'.join(chunks) + return hex + +_v4_ending = re.compile(br'(.*):(\d+\.\d+\.\d+\.\d+)$') +_colon_colon_start = re.compile(br'::.*') +_colon_colon_end = re.compile(br'.*::$') + +def inet_aton(text): + """Convert an IPv6 address in text form to binary form. + + *text*, a ``text``, the IPv6 address in textual form. + + Returns a ``binary``. + """ + + # + # Our aim here is not something fast; we just want something that works. + # + if not isinstance(text, binary_type): + text = text.encode() + + if text == b'::': + text = b'0::' + # + # Get rid of the icky dot-quad syntax if we have it. + # + m = _v4_ending.match(text) + if not m is None: + b = bytearray(dns.ipv4.inet_aton(m.group(2))) + text = (u"{}:{:02x}{:02x}:{:02x}{:02x}".format(m.group(1).decode(), + b[0], b[1], b[2], + b[3])).encode() + # + # Try to turn '::' into ':'; if no match try to + # turn '::' into ':' + # + m = _colon_colon_start.match(text) + if not m is None: + text = text[1:] + else: + m = _colon_colon_end.match(text) + if not m is None: + text = text[:-1] + # + # Now canonicalize into 8 chunks of 4 hex digits each + # + chunks = text.split(b':') + l = len(chunks) + if l > 8: + raise dns.exception.SyntaxError + seen_empty = False + canonical = [] + for c in chunks: + if c == b'': + if seen_empty: + raise dns.exception.SyntaxError + seen_empty = True + for i in xrange(0, 8 - l + 1): + canonical.append(b'0000') + else: + lc = len(c) + if lc > 4: + raise dns.exception.SyntaxError + if lc != 4: + c = (b'0' * (4 - lc)) + c + canonical.append(c) + if l < 8 and not seen_empty: + raise dns.exception.SyntaxError + text = b''.join(canonical) + + # + # Finally we can go to binary. + # + try: + return binascii.unhexlify(text) + except (binascii.Error, TypeError): + raise dns.exception.SyntaxError + +_mapped_prefix = b'\x00' * 10 + b'\xff\xff' + +def is_mapped(address): + """Is the specified address a mapped IPv4 address? + + *address*, a ``binary`` is an IPv6 address in binary form. + + Returns a ``bool``. + """ + + return address.startswith(_mapped_prefix) diff --git a/env/lib/python3.7/site-packages/dns/message.py b/env/lib/python3.7/site-packages/dns/message.py new file mode 100644 index 0000000..9d2b2f4 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/message.py @@ -0,0 +1,1175 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Messages""" + +from __future__ import absolute_import + +from io import StringIO +import struct +import time + +import dns.edns +import dns.exception +import dns.flags +import dns.name +import dns.opcode +import dns.entropy +import dns.rcode +import dns.rdata +import dns.rdataclass +import dns.rdatatype +import dns.rrset +import dns.renderer +import dns.tsig +import dns.wiredata + +from ._compat import long, xrange, string_types + + +class ShortHeader(dns.exception.FormError): + """The DNS packet passed to from_wire() is too short.""" + + +class TrailingJunk(dns.exception.FormError): + """The DNS packet passed to from_wire() has extra junk at the end of it.""" + + +class UnknownHeaderField(dns.exception.DNSException): + """The header field name was not recognized when converting from text + into a message.""" + + +class BadEDNS(dns.exception.FormError): + """An OPT record occurred somewhere other than the start of + the additional data section.""" + + +class BadTSIG(dns.exception.FormError): + """A TSIG record occurred somewhere other than the end of + the additional data section.""" + + +class UnknownTSIGKey(dns.exception.DNSException): + """A TSIG with an unknown key was received.""" + + +#: The question section number +QUESTION = 0 + +#: The answer section number +ANSWER = 1 + +#: The authority section number +AUTHORITY = 2 + +#: The additional section number +ADDITIONAL = 3 + +class Message(object): + """A DNS message.""" + + def __init__(self, id=None): + if id is None: + self.id = dns.entropy.random_16() + else: + self.id = id + self.flags = 0 + self.question = [] + self.answer = [] + self.authority = [] + self.additional = [] + self.edns = -1 + self.ednsflags = 0 + self.payload = 0 + self.options = [] + self.request_payload = 0 + self.keyring = None + self.keyname = None + self.keyalgorithm = dns.tsig.default_algorithm + self.request_mac = b'' + self.other_data = b'' + self.tsig_error = 0 + self.fudge = 300 + self.original_id = self.id + self.mac = b'' + self.xfr = False + self.origin = None + self.tsig_ctx = None + self.had_tsig = False + self.multi = False + self.first = True + self.index = {} + + def __repr__(self): + return '' + + def __str__(self): + return self.to_text() + + def to_text(self, origin=None, relativize=True, **kw): + """Convert the message to text. + + The *origin*, *relativize*, and any other keyword + arguments are passed to the RRset ``to_wire()`` method. + + Returns a ``text``. + """ + + s = StringIO() + s.write(u'id %d\n' % self.id) + s.write(u'opcode %s\n' % + dns.opcode.to_text(dns.opcode.from_flags(self.flags))) + rc = dns.rcode.from_flags(self.flags, self.ednsflags) + s.write(u'rcode %s\n' % dns.rcode.to_text(rc)) + s.write(u'flags %s\n' % dns.flags.to_text(self.flags)) + if self.edns >= 0: + s.write(u'edns %s\n' % self.edns) + if self.ednsflags != 0: + s.write(u'eflags %s\n' % + dns.flags.edns_to_text(self.ednsflags)) + s.write(u'payload %d\n' % self.payload) + for opt in self.options: + s.write(u'option %s\n' % opt.to_text()) + is_update = dns.opcode.is_update(self.flags) + if is_update: + s.write(u';ZONE\n') + else: + s.write(u';QUESTION\n') + for rrset in self.question: + s.write(rrset.to_text(origin, relativize, **kw)) + s.write(u'\n') + if is_update: + s.write(u';PREREQ\n') + else: + s.write(u';ANSWER\n') + for rrset in self.answer: + s.write(rrset.to_text(origin, relativize, **kw)) + s.write(u'\n') + if is_update: + s.write(u';UPDATE\n') + else: + s.write(u';AUTHORITY\n') + for rrset in self.authority: + s.write(rrset.to_text(origin, relativize, **kw)) + s.write(u'\n') + s.write(u';ADDITIONAL\n') + for rrset in self.additional: + s.write(rrset.to_text(origin, relativize, **kw)) + s.write(u'\n') + # + # We strip off the final \n so the caller can print the result without + # doing weird things to get around eccentricities in Python print + # formatting + # + return s.getvalue()[:-1] + + def __eq__(self, other): + """Two messages are equal if they have the same content in the + header, question, answer, and authority sections. + + Returns a ``bool``. + """ + + if not isinstance(other, Message): + return False + if self.id != other.id: + return False + if self.flags != other.flags: + return False + for n in self.question: + if n not in other.question: + return False + for n in other.question: + if n not in self.question: + return False + for n in self.answer: + if n not in other.answer: + return False + for n in other.answer: + if n not in self.answer: + return False + for n in self.authority: + if n not in other.authority: + return False + for n in other.authority: + if n not in self.authority: + return False + return True + + def __ne__(self, other): + return not self.__eq__(other) + + def is_response(self, other): + """Is this message a response to *other*? + + Returns a ``bool``. + """ + + if other.flags & dns.flags.QR == 0 or \ + self.id != other.id or \ + dns.opcode.from_flags(self.flags) != \ + dns.opcode.from_flags(other.flags): + return False + if dns.rcode.from_flags(other.flags, other.ednsflags) != \ + dns.rcode.NOERROR: + return True + if dns.opcode.is_update(self.flags): + return True + for n in self.question: + if n not in other.question: + return False + for n in other.question: + if n not in self.question: + return False + return True + + def section_number(self, section): + """Return the "section number" of the specified section for use + in indexing. The question section is 0, the answer section is 1, + the authority section is 2, and the additional section is 3. + + *section* is one of the section attributes of this message. + + Raises ``ValueError`` if the section isn't known. + + Returns an ``int``. + """ + + if section is self.question: + return QUESTION + elif section is self.answer: + return ANSWER + elif section is self.authority: + return AUTHORITY + elif section is self.additional: + return ADDITIONAL + else: + raise ValueError('unknown section') + + def section_from_number(self, number): + """Return the "section number" of the specified section for use + in indexing. The question section is 0, the answer section is 1, + the authority section is 2, and the additional section is 3. + + *section* is one of the section attributes of this message. + + Raises ``ValueError`` if the section isn't known. + + Returns an ``int``. + """ + + if number == QUESTION: + return self.question + elif number == ANSWER: + return self.answer + elif number == AUTHORITY: + return self.authority + elif number == ADDITIONAL: + return self.additional + else: + raise ValueError('unknown section') + + def find_rrset(self, section, name, rdclass, rdtype, + covers=dns.rdatatype.NONE, deleting=None, create=False, + force_unique=False): + """Find the RRset with the given attributes in the specified section. + + *section*, an ``int`` section number, or one of the section + attributes of this message. This specifies the + the section of the message to search. For example:: + + my_message.find_rrset(my_message.answer, name, rdclass, rdtype) + my_message.find_rrset(dns.message.ANSWER, name, rdclass, rdtype) + + *name*, a ``dns.name.Name``, the name of the RRset. + + *rdclass*, an ``int``, the class of the RRset. + + *rdtype*, an ``int``, the type of the RRset. + + *covers*, an ``int`` or ``None``, the covers value of the RRset. + The default is ``None``. + + *deleting*, an ``int`` or ``None``, the deleting value of the RRset. + The default is ``None``. + + *create*, a ``bool``. If ``True``, create the RRset if it is not found. + The created RRset is appended to *section*. + + *force_unique*, a ``bool``. If ``True`` and *create* is also ``True``, + create a new RRset regardless of whether a matching RRset exists + already. The default is ``False``. This is useful when creating + DDNS Update messages, as order matters for them. + + Raises ``KeyError`` if the RRset was not found and create was + ``False``. + + Returns a ``dns.rrset.RRset object``. + """ + + if isinstance(section, int): + section_number = section + section = self.section_from_number(section_number) + else: + section_number = self.section_number(section) + key = (section_number, name, rdclass, rdtype, covers, deleting) + if not force_unique: + if self.index is not None: + rrset = self.index.get(key) + if rrset is not None: + return rrset + else: + for rrset in section: + if rrset.match(name, rdclass, rdtype, covers, deleting): + return rrset + if not create: + raise KeyError + rrset = dns.rrset.RRset(name, rdclass, rdtype, covers, deleting) + section.append(rrset) + if self.index is not None: + self.index[key] = rrset + return rrset + + def get_rrset(self, section, name, rdclass, rdtype, + covers=dns.rdatatype.NONE, deleting=None, create=False, + force_unique=False): + """Get the RRset with the given attributes in the specified section. + + If the RRset is not found, None is returned. + + *section*, an ``int`` section number, or one of the section + attributes of this message. This specifies the + the section of the message to search. For example:: + + my_message.get_rrset(my_message.answer, name, rdclass, rdtype) + my_message.get_rrset(dns.message.ANSWER, name, rdclass, rdtype) + + *name*, a ``dns.name.Name``, the name of the RRset. + + *rdclass*, an ``int``, the class of the RRset. + + *rdtype*, an ``int``, the type of the RRset. + + *covers*, an ``int`` or ``None``, the covers value of the RRset. + The default is ``None``. + + *deleting*, an ``int`` or ``None``, the deleting value of the RRset. + The default is ``None``. + + *create*, a ``bool``. If ``True``, create the RRset if it is not found. + The created RRset is appended to *section*. + + *force_unique*, a ``bool``. If ``True`` and *create* is also ``True``, + create a new RRset regardless of whether a matching RRset exists + already. The default is ``False``. This is useful when creating + DDNS Update messages, as order matters for them. + + Returns a ``dns.rrset.RRset object`` or ``None``. + """ + + try: + rrset = self.find_rrset(section, name, rdclass, rdtype, covers, + deleting, create, force_unique) + except KeyError: + rrset = None + return rrset + + def to_wire(self, origin=None, max_size=0, **kw): + """Return a string containing the message in DNS compressed wire + format. + + Additional keyword arguments are passed to the RRset ``to_wire()`` + method. + + *origin*, a ``dns.name.Name`` or ``None``, the origin to be appended + to any relative names. + + *max_size*, an ``int``, the maximum size of the wire format + output; default is 0, which means "the message's request + payload, if nonzero, or 65535". + + Raises ``dns.exception.TooBig`` if *max_size* was exceeded. + + Returns a ``binary``. + """ + + if max_size == 0: + if self.request_payload != 0: + max_size = self.request_payload + else: + max_size = 65535 + if max_size < 512: + max_size = 512 + elif max_size > 65535: + max_size = 65535 + r = dns.renderer.Renderer(self.id, self.flags, max_size, origin) + for rrset in self.question: + r.add_question(rrset.name, rrset.rdtype, rrset.rdclass) + for rrset in self.answer: + r.add_rrset(dns.renderer.ANSWER, rrset, **kw) + for rrset in self.authority: + r.add_rrset(dns.renderer.AUTHORITY, rrset, **kw) + if self.edns >= 0: + r.add_edns(self.edns, self.ednsflags, self.payload, self.options) + for rrset in self.additional: + r.add_rrset(dns.renderer.ADDITIONAL, rrset, **kw) + r.write_header() + if self.keyname is not None: + r.add_tsig(self.keyname, self.keyring[self.keyname], + self.fudge, self.original_id, self.tsig_error, + self.other_data, self.request_mac, + self.keyalgorithm) + self.mac = r.mac + return r.get_wire() + + def use_tsig(self, keyring, keyname=None, fudge=300, + original_id=None, tsig_error=0, other_data=b'', + algorithm=dns.tsig.default_algorithm): + """When sending, a TSIG signature using the specified keyring + and keyname should be added. + + See the documentation of the Message class for a complete + description of the keyring dictionary. + + *keyring*, a ``dict``, the TSIG keyring to use. If a + *keyring* is specified but a *keyname* is not, then the key + used will be the first key in the *keyring*. Note that the + order of keys in a dictionary is not defined, so applications + should supply a keyname when a keyring is used, unless they + know the keyring contains only one key. + + *keyname*, a ``dns.name.Name`` or ``None``, the name of the TSIG key + to use; defaults to ``None``. The key must be defined in the keyring. + + *fudge*, an ``int``, the TSIG time fudge. + + *original_id*, an ``int``, the TSIG original id. If ``None``, + the message's id is used. + + *tsig_error*, an ``int``, the TSIG error code. + + *other_data*, a ``binary``, the TSIG other data. + + *algorithm*, a ``dns.name.Name``, the TSIG algorithm to use. + """ + + self.keyring = keyring + if keyname is None: + self.keyname = list(self.keyring.keys())[0] + else: + if isinstance(keyname, string_types): + keyname = dns.name.from_text(keyname) + self.keyname = keyname + self.keyalgorithm = algorithm + self.fudge = fudge + if original_id is None: + self.original_id = self.id + else: + self.original_id = original_id + self.tsig_error = tsig_error + self.other_data = other_data + + def use_edns(self, edns=0, ednsflags=0, payload=1280, request_payload=None, + options=None): + """Configure EDNS behavior. + + *edns*, an ``int``, is the EDNS level to use. Specifying + ``None``, ``False``, or ``-1`` means "do not use EDNS", and in this case + the other parameters are ignored. Specifying ``True`` is + equivalent to specifying 0, i.e. "use EDNS0". + + *ednsflags*, an ``int``, the EDNS flag values. + + *payload*, an ``int``, is the EDNS sender's payload field, which is the + maximum size of UDP datagram the sender can handle. I.e. how big + a response to this message can be. + + *request_payload*, an ``int``, is the EDNS payload size to use when + sending this message. If not specified, defaults to the value of + *payload*. + + *options*, a list of ``dns.edns.Option`` objects or ``None``, the EDNS + options. + """ + + if edns is None or edns is False: + edns = -1 + if edns is True: + edns = 0 + if request_payload is None: + request_payload = payload + if edns < 0: + ednsflags = 0 + payload = 0 + request_payload = 0 + options = [] + else: + # make sure the EDNS version in ednsflags agrees with edns + ednsflags &= long(0xFF00FFFF) + ednsflags |= (edns << 16) + if options is None: + options = [] + self.edns = edns + self.ednsflags = ednsflags + self.payload = payload + self.options = options + self.request_payload = request_payload + + def want_dnssec(self, wanted=True): + """Enable or disable 'DNSSEC desired' flag in requests. + + *wanted*, a ``bool``. If ``True``, then DNSSEC data is + desired in the response, EDNS is enabled if required, and then + the DO bit is set. If ``False``, the DO bit is cleared if + EDNS is enabled. + """ + + if wanted: + if self.edns < 0: + self.use_edns() + self.ednsflags |= dns.flags.DO + elif self.edns >= 0: + self.ednsflags &= ~dns.flags.DO + + def rcode(self): + """Return the rcode. + + Returns an ``int``. + """ + return dns.rcode.from_flags(self.flags, self.ednsflags) + + def set_rcode(self, rcode): + """Set the rcode. + + *rcode*, an ``int``, is the rcode to set. + """ + (value, evalue) = dns.rcode.to_flags(rcode) + self.flags &= 0xFFF0 + self.flags |= value + self.ednsflags &= long(0x00FFFFFF) + self.ednsflags |= evalue + if self.ednsflags != 0 and self.edns < 0: + self.edns = 0 + + def opcode(self): + """Return the opcode. + + Returns an ``int``. + """ + return dns.opcode.from_flags(self.flags) + + def set_opcode(self, opcode): + """Set the opcode. + + *opcode*, an ``int``, is the opcode to set. + """ + self.flags &= 0x87FF + self.flags |= dns.opcode.to_flags(opcode) + + +class _WireReader(object): + + """Wire format reader. + + wire: a binary, is the wire-format message. + message: The message object being built + current: When building a message object from wire format, this + variable contains the offset from the beginning of wire of the next octet + to be read. + updating: Is the message a dynamic update? + one_rr_per_rrset: Put each RR into its own RRset? + ignore_trailing: Ignore trailing junk at end of request? + zone_rdclass: The class of the zone in messages which are + DNS dynamic updates. + """ + + def __init__(self, wire, message, question_only=False, + one_rr_per_rrset=False, ignore_trailing=False): + self.wire = dns.wiredata.maybe_wrap(wire) + self.message = message + self.current = 0 + self.updating = False + self.zone_rdclass = dns.rdataclass.IN + self.question_only = question_only + self.one_rr_per_rrset = one_rr_per_rrset + self.ignore_trailing = ignore_trailing + + def _get_question(self, qcount): + """Read the next *qcount* records from the wire data and add them to + the question section. + """ + + if self.updating and qcount > 1: + raise dns.exception.FormError + + for i in xrange(0, qcount): + (qname, used) = dns.name.from_wire(self.wire, self.current) + if self.message.origin is not None: + qname = qname.relativize(self.message.origin) + self.current = self.current + used + (rdtype, rdclass) = \ + struct.unpack('!HH', + self.wire[self.current:self.current + 4]) + self.current = self.current + 4 + self.message.find_rrset(self.message.question, qname, + rdclass, rdtype, create=True, + force_unique=True) + if self.updating: + self.zone_rdclass = rdclass + + def _get_section(self, section, count): + """Read the next I{count} records from the wire data and add them to + the specified section. + + section: the section of the message to which to add records + count: the number of records to read + """ + + if self.updating or self.one_rr_per_rrset: + force_unique = True + else: + force_unique = False + seen_opt = False + for i in xrange(0, count): + rr_start = self.current + (name, used) = dns.name.from_wire(self.wire, self.current) + absolute_name = name + if self.message.origin is not None: + name = name.relativize(self.message.origin) + self.current = self.current + used + (rdtype, rdclass, ttl, rdlen) = \ + struct.unpack('!HHIH', + self.wire[self.current:self.current + 10]) + self.current = self.current + 10 + if rdtype == dns.rdatatype.OPT: + if section is not self.message.additional or seen_opt: + raise BadEDNS + self.message.payload = rdclass + self.message.ednsflags = ttl + self.message.edns = (ttl & 0xff0000) >> 16 + self.message.options = [] + current = self.current + optslen = rdlen + while optslen > 0: + (otype, olen) = \ + struct.unpack('!HH', + self.wire[current:current + 4]) + current = current + 4 + opt = dns.edns.option_from_wire( + otype, self.wire, current, olen) + self.message.options.append(opt) + current = current + olen + optslen = optslen - 4 - olen + seen_opt = True + elif rdtype == dns.rdatatype.TSIG: + if not (section is self.message.additional and + i == (count - 1)): + raise BadTSIG + if self.message.keyring is None: + raise UnknownTSIGKey('got signed message without keyring') + secret = self.message.keyring.get(absolute_name) + if secret is None: + raise UnknownTSIGKey("key '%s' unknown" % name) + self.message.keyname = absolute_name + (self.message.keyalgorithm, self.message.mac) = \ + dns.tsig.get_algorithm_and_mac(self.wire, self.current, + rdlen) + self.message.tsig_ctx = \ + dns.tsig.validate(self.wire, + absolute_name, + secret, + int(time.time()), + self.message.request_mac, + rr_start, + self.current, + rdlen, + self.message.tsig_ctx, + self.message.multi, + self.message.first) + self.message.had_tsig = True + else: + if ttl < 0: + ttl = 0 + if self.updating and \ + (rdclass == dns.rdataclass.ANY or + rdclass == dns.rdataclass.NONE): + deleting = rdclass + rdclass = self.zone_rdclass + else: + deleting = None + if deleting == dns.rdataclass.ANY or \ + (deleting == dns.rdataclass.NONE and + section is self.message.answer): + covers = dns.rdatatype.NONE + rd = None + else: + rd = dns.rdata.from_wire(rdclass, rdtype, self.wire, + self.current, rdlen, + self.message.origin) + covers = rd.covers() + if self.message.xfr and rdtype == dns.rdatatype.SOA: + force_unique = True + rrset = self.message.find_rrset(section, name, + rdclass, rdtype, covers, + deleting, True, force_unique) + if rd is not None: + rrset.add(rd, ttl) + self.current = self.current + rdlen + + def read(self): + """Read a wire format DNS message and build a dns.message.Message + object.""" + + l = len(self.wire) + if l < 12: + raise ShortHeader + (self.message.id, self.message.flags, qcount, ancount, + aucount, adcount) = struct.unpack('!HHHHHH', self.wire[:12]) + self.current = 12 + if dns.opcode.is_update(self.message.flags): + self.updating = True + self._get_question(qcount) + if self.question_only: + return + self._get_section(self.message.answer, ancount) + self._get_section(self.message.authority, aucount) + self._get_section(self.message.additional, adcount) + if not self.ignore_trailing and self.current != l: + raise TrailingJunk + if self.message.multi and self.message.tsig_ctx and \ + not self.message.had_tsig: + self.message.tsig_ctx.update(self.wire) + + +def from_wire(wire, keyring=None, request_mac=b'', xfr=False, origin=None, + tsig_ctx=None, multi=False, first=True, + question_only=False, one_rr_per_rrset=False, + ignore_trailing=False): + """Convert a DNS wire format message into a message + object. + + *keyring*, a ``dict``, the keyring to use if the message is signed. + + *request_mac*, a ``binary``. If the message is a response to a + TSIG-signed request, *request_mac* should be set to the MAC of + that request. + + *xfr*, a ``bool``, should be set to ``True`` if this message is part of + a zone transfer. + + *origin*, a ``dns.name.Name`` or ``None``. If the message is part + of a zone transfer, *origin* should be the origin name of the + zone. + + *tsig_ctx*, a ``hmac.HMAC`` objext, the ongoing TSIG context, used + when validating zone transfers. + + *multi*, a ``bool``, should be set to ``True`` if this message + part of a multiple message sequence. + + *first*, a ``bool``, should be set to ``True`` if this message is + stand-alone, or the first message in a multi-message sequence. + + *question_only*, a ``bool``. If ``True``, read only up to + the end of the question section. + + *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its + own RRset. + + *ignore_trailing*, a ``bool``. If ``True``, ignore trailing + junk at end of the message. + + Raises ``dns.message.ShortHeader`` if the message is less than 12 octets + long. + + Raises ``dns.messaage.TrailingJunk`` if there were octets in the message + past the end of the proper DNS message, and *ignore_trailing* is ``False``. + + Raises ``dns.message.BadEDNS`` if an OPT record was in the + wrong section, or occurred more than once. + + Raises ``dns.message.BadTSIG`` if a TSIG record was not the last + record of the additional data section. + + Returns a ``dns.message.Message``. + """ + + m = Message(id=0) + m.keyring = keyring + m.request_mac = request_mac + m.xfr = xfr + m.origin = origin + m.tsig_ctx = tsig_ctx + m.multi = multi + m.first = first + + reader = _WireReader(wire, m, question_only, one_rr_per_rrset, + ignore_trailing) + reader.read() + + return m + + +class _TextReader(object): + + """Text format reader. + + tok: the tokenizer. + message: The message object being built. + updating: Is the message a dynamic update? + zone_rdclass: The class of the zone in messages which are + DNS dynamic updates. + last_name: The most recently read name when building a message object. + """ + + def __init__(self, text, message): + self.message = message + self.tok = dns.tokenizer.Tokenizer(text) + self.last_name = None + self.zone_rdclass = dns.rdataclass.IN + self.updating = False + + def _header_line(self, section): + """Process one line from the text format header section.""" + + token = self.tok.get() + what = token.value + if what == 'id': + self.message.id = self.tok.get_int() + elif what == 'flags': + while True: + token = self.tok.get() + if not token.is_identifier(): + self.tok.unget(token) + break + self.message.flags = self.message.flags | \ + dns.flags.from_text(token.value) + if dns.opcode.is_update(self.message.flags): + self.updating = True + elif what == 'edns': + self.message.edns = self.tok.get_int() + self.message.ednsflags = self.message.ednsflags | \ + (self.message.edns << 16) + elif what == 'eflags': + if self.message.edns < 0: + self.message.edns = 0 + while True: + token = self.tok.get() + if not token.is_identifier(): + self.tok.unget(token) + break + self.message.ednsflags = self.message.ednsflags | \ + dns.flags.edns_from_text(token.value) + elif what == 'payload': + self.message.payload = self.tok.get_int() + if self.message.edns < 0: + self.message.edns = 0 + elif what == 'opcode': + text = self.tok.get_string() + self.message.flags = self.message.flags | \ + dns.opcode.to_flags(dns.opcode.from_text(text)) + elif what == 'rcode': + text = self.tok.get_string() + self.message.set_rcode(dns.rcode.from_text(text)) + else: + raise UnknownHeaderField + self.tok.get_eol() + + def _question_line(self, section): + """Process one line from the text format question section.""" + + token = self.tok.get(want_leading=True) + if not token.is_whitespace(): + self.last_name = dns.name.from_text(token.value, None) + name = self.last_name + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + # Class + try: + rdclass = dns.rdataclass.from_text(token.value) + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except dns.exception.SyntaxError: + raise dns.exception.SyntaxError + except Exception: + rdclass = dns.rdataclass.IN + # Type + rdtype = dns.rdatatype.from_text(token.value) + self.message.find_rrset(self.message.question, name, + rdclass, rdtype, create=True, + force_unique=True) + if self.updating: + self.zone_rdclass = rdclass + self.tok.get_eol() + + def _rr_line(self, section): + """Process one line from the text format answer, authority, or + additional data sections. + """ + + deleting = None + # Name + token = self.tok.get(want_leading=True) + if not token.is_whitespace(): + self.last_name = dns.name.from_text(token.value, None) + name = self.last_name + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + # TTL + try: + ttl = int(token.value, 0) + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except dns.exception.SyntaxError: + raise dns.exception.SyntaxError + except Exception: + ttl = 0 + # Class + try: + rdclass = dns.rdataclass.from_text(token.value) + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE: + deleting = rdclass + rdclass = self.zone_rdclass + except dns.exception.SyntaxError: + raise dns.exception.SyntaxError + except Exception: + rdclass = dns.rdataclass.IN + # Type + rdtype = dns.rdatatype.from_text(token.value) + token = self.tok.get() + if not token.is_eol_or_eof(): + self.tok.unget(token) + rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None) + covers = rd.covers() + else: + rd = None + covers = dns.rdatatype.NONE + rrset = self.message.find_rrset(section, name, + rdclass, rdtype, covers, + deleting, True, self.updating) + if rd is not None: + rrset.add(rd, ttl) + + def read(self): + """Read a text format DNS message and build a dns.message.Message + object.""" + + line_method = self._header_line + section = None + while 1: + token = self.tok.get(True, True) + if token.is_eol_or_eof(): + break + if token.is_comment(): + u = token.value.upper() + if u == 'HEADER': + line_method = self._header_line + elif u == 'QUESTION' or u == 'ZONE': + line_method = self._question_line + section = self.message.question + elif u == 'ANSWER' or u == 'PREREQ': + line_method = self._rr_line + section = self.message.answer + elif u == 'AUTHORITY' or u == 'UPDATE': + line_method = self._rr_line + section = self.message.authority + elif u == 'ADDITIONAL': + line_method = self._rr_line + section = self.message.additional + self.tok.get_eol() + continue + self.tok.unget(token) + line_method(section) + + +def from_text(text): + """Convert the text format message into a message object. + + *text*, a ``text``, the text format message. + + Raises ``dns.message.UnknownHeaderField`` if a header is unknown. + + Raises ``dns.exception.SyntaxError`` if the text is badly formed. + + Returns a ``dns.message.Message object`` + """ + + # 'text' can also be a file, but we don't publish that fact + # since it's an implementation detail. The official file + # interface is from_file(). + + m = Message() + + reader = _TextReader(text, m) + reader.read() + + return m + + +def from_file(f): + """Read the next text format message from the specified file. + + *f*, a ``file`` or ``text``. If *f* is text, it is treated as the + pathname of a file to open. + + Raises ``dns.message.UnknownHeaderField`` if a header is unknown. + + Raises ``dns.exception.SyntaxError`` if the text is badly formed. + + Returns a ``dns.message.Message object`` + """ + + str_type = string_types + opts = 'rU' + + if isinstance(f, str_type): + f = open(f, opts) + want_close = True + else: + want_close = False + + try: + m = from_text(f) + finally: + if want_close: + f.close() + return m + + +def make_query(qname, rdtype, rdclass=dns.rdataclass.IN, use_edns=None, + want_dnssec=False, ednsflags=None, payload=None, + request_payload=None, options=None): + """Make a query message. + + The query name, type, and class may all be specified either + as objects of the appropriate type, or as strings. + + The query will have a randomly chosen query id, and its DNS flags + will be set to dns.flags.RD. + + qname, a ``dns.name.Name`` or ``text``, the query name. + + *rdtype*, an ``int`` or ``text``, the desired rdata type. + + *rdclass*, an ``int`` or ``text``, the desired rdata class; the default + is class IN. + + *use_edns*, an ``int``, ``bool`` or ``None``. The EDNS level to use; the + default is None (no EDNS). + See the description of dns.message.Message.use_edns() for the possible + values for use_edns and their meanings. + + *want_dnssec*, a ``bool``. If ``True``, DNSSEC data is desired. + + *ednsflags*, an ``int``, the EDNS flag values. + + *payload*, an ``int``, is the EDNS sender's payload field, which is the + maximum size of UDP datagram the sender can handle. I.e. how big + a response to this message can be. + + *request_payload*, an ``int``, is the EDNS payload size to use when + sending this message. If not specified, defaults to the value of + *payload*. + + *options*, a list of ``dns.edns.Option`` objects or ``None``, the EDNS + options. + + Returns a ``dns.message.Message`` + """ + + if isinstance(qname, string_types): + qname = dns.name.from_text(qname) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if isinstance(rdclass, string_types): + rdclass = dns.rdataclass.from_text(rdclass) + m = Message() + m.flags |= dns.flags.RD + m.find_rrset(m.question, qname, rdclass, rdtype, create=True, + force_unique=True) + # only pass keywords on to use_edns if they have been set to a + # non-None value. Setting a field will turn EDNS on if it hasn't + # been configured. + kwargs = {} + if ednsflags is not None: + kwargs['ednsflags'] = ednsflags + if use_edns is None: + use_edns = 0 + if payload is not None: + kwargs['payload'] = payload + if use_edns is None: + use_edns = 0 + if request_payload is not None: + kwargs['request_payload'] = request_payload + if use_edns is None: + use_edns = 0 + if options is not None: + kwargs['options'] = options + if use_edns is None: + use_edns = 0 + kwargs['edns'] = use_edns + m.use_edns(**kwargs) + m.want_dnssec(want_dnssec) + return m + + +def make_response(query, recursion_available=False, our_payload=8192, + fudge=300): + """Make a message which is a response for the specified query. + The message returned is really a response skeleton; it has all + of the infrastructure required of a response, but none of the + content. + + The response's question section is a shallow copy of the query's + question section, so the query's question RRsets should not be + changed. + + *query*, a ``dns.message.Message``, the query to respond to. + + *recursion_available*, a ``bool``, should RA be set in the response? + + *our_payload*, an ``int``, the payload size to advertise in EDNS + responses. + + *fudge*, an ``int``, the TSIG time fudge. + + Returns a ``dns.message.Message`` object. + """ + + if query.flags & dns.flags.QR: + raise dns.exception.FormError('specified query message is not a query') + response = dns.message.Message(query.id) + response.flags = dns.flags.QR | (query.flags & dns.flags.RD) + if recursion_available: + response.flags |= dns.flags.RA + response.set_opcode(query.opcode()) + response.question = list(query.question) + if query.edns >= 0: + response.use_edns(0, 0, our_payload, query.payload) + if query.had_tsig: + response.use_tsig(query.keyring, query.keyname, fudge, None, 0, b'', + query.keyalgorithm) + response.request_mac = query.mac + return response diff --git a/env/lib/python3.7/site-packages/dns/name.py b/env/lib/python3.7/site-packages/dns/name.py new file mode 100644 index 0000000..0bcfd83 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/name.py @@ -0,0 +1,994 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Names. +""" + +from io import BytesIO +import struct +import sys +import copy +import encodings.idna +try: + import idna + have_idna_2008 = True +except ImportError: + have_idna_2008 = False + +import dns.exception +import dns.wiredata + +from ._compat import long, binary_type, text_type, unichr, maybe_decode + +try: + maxint = sys.maxint # pylint: disable=sys-max-int +except AttributeError: + maxint = (1 << (8 * struct.calcsize("P"))) // 2 - 1 + + +# fullcompare() result values + +#: The compared names have no relationship to each other. +NAMERELN_NONE = 0 +#: the first name is a superdomain of the second. +NAMERELN_SUPERDOMAIN = 1 +#: The first name is a subdomain of the second. +NAMERELN_SUBDOMAIN = 2 +#: The compared names are equal. +NAMERELN_EQUAL = 3 +#: The compared names have a common ancestor. +NAMERELN_COMMONANCESTOR = 4 + + +class EmptyLabel(dns.exception.SyntaxError): + """A DNS label is empty.""" + + +class BadEscape(dns.exception.SyntaxError): + """An escaped code in a text format of DNS name is invalid.""" + + +class BadPointer(dns.exception.FormError): + """A DNS compression pointer points forward instead of backward.""" + + +class BadLabelType(dns.exception.FormError): + """The label type in DNS name wire format is unknown.""" + + +class NeedAbsoluteNameOrOrigin(dns.exception.DNSException): + """An attempt was made to convert a non-absolute name to + wire when there was also a non-absolute (or missing) origin.""" + + +class NameTooLong(dns.exception.FormError): + """A DNS name is > 255 octets long.""" + + +class LabelTooLong(dns.exception.SyntaxError): + """A DNS label is > 63 octets long.""" + + +class AbsoluteConcatenation(dns.exception.DNSException): + """An attempt was made to append anything other than the + empty name to an absolute DNS name.""" + + +class NoParent(dns.exception.DNSException): + """An attempt was made to get the parent of the root name + or the empty name.""" + +class NoIDNA2008(dns.exception.DNSException): + """IDNA 2008 processing was requested but the idna module is not + available.""" + + +class IDNAException(dns.exception.DNSException): + """IDNA processing raised an exception.""" + + supp_kwargs = {'idna_exception'} + fmt = "IDNA processing exception: {idna_exception}" + + +class IDNACodec(object): + """Abstract base class for IDNA encoder/decoders.""" + + def __init__(self): + pass + + def encode(self, label): + raise NotImplementedError + + def decode(self, label): + # We do not apply any IDNA policy on decode; we just + downcased = label.lower() + if downcased.startswith(b'xn--'): + try: + label = downcased[4:].decode('punycode') + except Exception as e: + raise IDNAException(idna_exception=e) + else: + label = maybe_decode(label) + return _escapify(label, True) + + +class IDNA2003Codec(IDNACodec): + """IDNA 2003 encoder/decoder.""" + + def __init__(self, strict_decode=False): + """Initialize the IDNA 2003 encoder/decoder. + + *strict_decode* is a ``bool``. If `True`, then IDNA2003 checking + is done when decoding. This can cause failures if the name + was encoded with IDNA2008. The default is `False`. + """ + + super(IDNA2003Codec, self).__init__() + self.strict_decode = strict_decode + + def encode(self, label): + """Encode *label*.""" + + if label == '': + return b'' + try: + return encodings.idna.ToASCII(label) + except UnicodeError: + raise LabelTooLong + + def decode(self, label): + """Decode *label*.""" + if not self.strict_decode: + return super(IDNA2003Codec, self).decode(label) + if label == b'': + return u'' + try: + return _escapify(encodings.idna.ToUnicode(label), True) + except Exception as e: + raise IDNAException(idna_exception=e) + + +class IDNA2008Codec(IDNACodec): + """IDNA 2008 encoder/decoder. + + *uts_46* is a ``bool``. If True, apply Unicode IDNA + compatibility processing as described in Unicode Technical + Standard #46 (http://unicode.org/reports/tr46/). + If False, do not apply the mapping. The default is False. + + *transitional* is a ``bool``: If True, use the + "transitional" mode described in Unicode Technical Standard + #46. The default is False. + + *allow_pure_ascii* is a ``bool``. If True, then a label which + consists of only ASCII characters is allowed. This is less + strict than regular IDNA 2008, but is also necessary for mixed + names, e.g. a name with starting with "_sip._tcp." and ending + in an IDN suffix which would otherwise be disallowed. The + default is False. + + *strict_decode* is a ``bool``: If True, then IDNA2008 checking + is done when decoding. This can cause failures if the name + was encoded with IDNA2003. The default is False. + """ + + def __init__(self, uts_46=False, transitional=False, + allow_pure_ascii=False, strict_decode=False): + """Initialize the IDNA 2008 encoder/decoder.""" + super(IDNA2008Codec, self).__init__() + self.uts_46 = uts_46 + self.transitional = transitional + self.allow_pure_ascii = allow_pure_ascii + self.strict_decode = strict_decode + + def is_all_ascii(self, label): + for c in label: + if ord(c) > 0x7f: + return False + return True + + def encode(self, label): + if label == '': + return b'' + if self.allow_pure_ascii and self.is_all_ascii(label): + return label.encode('ascii') + if not have_idna_2008: + raise NoIDNA2008 + try: + if self.uts_46: + label = idna.uts46_remap(label, False, self.transitional) + return idna.alabel(label) + except idna.IDNAError as e: + raise IDNAException(idna_exception=e) + + def decode(self, label): + if not self.strict_decode: + return super(IDNA2008Codec, self).decode(label) + if label == b'': + return u'' + if not have_idna_2008: + raise NoIDNA2008 + try: + if self.uts_46: + label = idna.uts46_remap(label, False, False) + return _escapify(idna.ulabel(label), True) + except idna.IDNAError as e: + raise IDNAException(idna_exception=e) + +_escaped = bytearray(b'"().;\\@$') + +IDNA_2003_Practical = IDNA2003Codec(False) +IDNA_2003_Strict = IDNA2003Codec(True) +IDNA_2003 = IDNA_2003_Practical +IDNA_2008_Practical = IDNA2008Codec(True, False, True, False) +IDNA_2008_UTS_46 = IDNA2008Codec(True, False, False, False) +IDNA_2008_Strict = IDNA2008Codec(False, False, False, True) +IDNA_2008_Transitional = IDNA2008Codec(True, True, False, False) +IDNA_2008 = IDNA_2008_Practical + +def _escapify(label, unicode_mode=False): + """Escape the characters in label which need it. + @param unicode_mode: escapify only special and whitespace (<= 0x20) + characters + @returns: the escaped string + @rtype: string""" + if not unicode_mode: + text = '' + if isinstance(label, text_type): + label = label.encode() + for c in bytearray(label): + if c in _escaped: + text += '\\' + chr(c) + elif c > 0x20 and c < 0x7F: + text += chr(c) + else: + text += '\\%03d' % c + return text.encode() + + text = u'' + if isinstance(label, binary_type): + label = label.decode() + for c in label: + if c > u'\x20' and c < u'\x7f': + text += c + else: + if c >= u'\x7f': + text += c + else: + text += u'\\%03d' % ord(c) + return text + +def _validate_labels(labels): + """Check for empty labels in the middle of a label sequence, + labels that are too long, and for too many labels. + + Raises ``dns.name.NameTooLong`` if the name as a whole is too long. + + Raises ``dns.name.EmptyLabel`` if a label is empty (i.e. the root + label) and appears in a position other than the end of the label + sequence + + """ + + l = len(labels) + total = 0 + i = -1 + j = 0 + for label in labels: + ll = len(label) + total += ll + 1 + if ll > 63: + raise LabelTooLong + if i < 0 and label == b'': + i = j + j += 1 + if total > 255: + raise NameTooLong + if i >= 0 and i != l - 1: + raise EmptyLabel + + +def _maybe_convert_to_binary(label): + """If label is ``text``, convert it to ``binary``. If it is already + ``binary`` just return it. + + """ + + if isinstance(label, binary_type): + return label + if isinstance(label, text_type): + return label.encode() + raise ValueError + + +class Name(object): + + """A DNS name. + + The dns.name.Name class represents a DNS name as a tuple of + labels. Each label is a `binary` in DNS wire format. Instances + of the class are immutable. + """ + + __slots__ = ['labels'] + + def __init__(self, labels): + """*labels* is any iterable whose values are ``text`` or ``binary``. + """ + + labels = [_maybe_convert_to_binary(x) for x in labels] + super(Name, self).__setattr__('labels', tuple(labels)) + _validate_labels(self.labels) + + def __setattr__(self, name, value): + # Names are immutable + raise TypeError("object doesn't support attribute assignment") + + def __copy__(self): + return Name(self.labels) + + def __deepcopy__(self, memo): + return Name(copy.deepcopy(self.labels, memo)) + + def __getstate__(self): + # Names can be pickled + return {'labels': self.labels} + + def __setstate__(self, state): + super(Name, self).__setattr__('labels', state['labels']) + _validate_labels(self.labels) + + def is_absolute(self): + """Is the most significant label of this name the root label? + + Returns a ``bool``. + """ + + return len(self.labels) > 0 and self.labels[-1] == b'' + + def is_wild(self): + """Is this name wild? (I.e. Is the least significant label '*'?) + + Returns a ``bool``. + """ + + return len(self.labels) > 0 and self.labels[0] == b'*' + + def __hash__(self): + """Return a case-insensitive hash of the name. + + Returns an ``int``. + """ + + h = long(0) + for label in self.labels: + for c in bytearray(label.lower()): + h += (h << 3) + c + return int(h % maxint) + + def fullcompare(self, other): + """Compare two names, returning a 3-tuple + ``(relation, order, nlabels)``. + + *relation* describes the relation ship between the names, + and is one of: ``dns.name.NAMERELN_NONE``, + ``dns.name.NAMERELN_SUPERDOMAIN``, ``dns.name.NAMERELN_SUBDOMAIN``, + ``dns.name.NAMERELN_EQUAL``, or ``dns.name.NAMERELN_COMMONANCESTOR``. + + *order* is < 0 if *self* < *other*, > 0 if *self* > *other*, and == + 0 if *self* == *other*. A relative name is always less than an + absolute name. If both names have the same relativity, then + the DNSSEC order relation is used to order them. + + *nlabels* is the number of significant labels that the two names + have in common. + + Here are some examples. Names ending in "." are absolute names, + those not ending in "." are relative names. + + ============= ============= =========== ===== ======= + self other relation order nlabels + ============= ============= =========== ===== ======= + www.example. www.example. equal 0 3 + www.example. example. subdomain > 0 2 + example. www.example. superdomain < 0 2 + example1.com. example2.com. common anc. < 0 2 + example1 example2. none < 0 0 + example1. example2 none > 0 0 + ============= ============= =========== ===== ======= + """ + + sabs = self.is_absolute() + oabs = other.is_absolute() + if sabs != oabs: + if sabs: + return (NAMERELN_NONE, 1, 0) + else: + return (NAMERELN_NONE, -1, 0) + l1 = len(self.labels) + l2 = len(other.labels) + ldiff = l1 - l2 + if ldiff < 0: + l = l1 + else: + l = l2 + + order = 0 + nlabels = 0 + namereln = NAMERELN_NONE + while l > 0: + l -= 1 + l1 -= 1 + l2 -= 1 + label1 = self.labels[l1].lower() + label2 = other.labels[l2].lower() + if label1 < label2: + order = -1 + if nlabels > 0: + namereln = NAMERELN_COMMONANCESTOR + return (namereln, order, nlabels) + elif label1 > label2: + order = 1 + if nlabels > 0: + namereln = NAMERELN_COMMONANCESTOR + return (namereln, order, nlabels) + nlabels += 1 + order = ldiff + if ldiff < 0: + namereln = NAMERELN_SUPERDOMAIN + elif ldiff > 0: + namereln = NAMERELN_SUBDOMAIN + else: + namereln = NAMERELN_EQUAL + return (namereln, order, nlabels) + + def is_subdomain(self, other): + """Is self a subdomain of other? + + Note that the notion of subdomain includes equality, e.g. + "dnpython.org" is a subdomain of itself. + + Returns a ``bool``. + """ + + (nr, o, nl) = self.fullcompare(other) + if nr == NAMERELN_SUBDOMAIN or nr == NAMERELN_EQUAL: + return True + return False + + def is_superdomain(self, other): + """Is self a superdomain of other? + + Note that the notion of superdomain includes equality, e.g. + "dnpython.org" is a superdomain of itself. + + Returns a ``bool``. + """ + + (nr, o, nl) = self.fullcompare(other) + if nr == NAMERELN_SUPERDOMAIN or nr == NAMERELN_EQUAL: + return True + return False + + def canonicalize(self): + """Return a name which is equal to the current name, but is in + DNSSEC canonical form. + """ + + return Name([x.lower() for x in self.labels]) + + def __eq__(self, other): + if isinstance(other, Name): + return self.fullcompare(other)[1] == 0 + else: + return False + + def __ne__(self, other): + if isinstance(other, Name): + return self.fullcompare(other)[1] != 0 + else: + return True + + def __lt__(self, other): + if isinstance(other, Name): + return self.fullcompare(other)[1] < 0 + else: + return NotImplemented + + def __le__(self, other): + if isinstance(other, Name): + return self.fullcompare(other)[1] <= 0 + else: + return NotImplemented + + def __ge__(self, other): + if isinstance(other, Name): + return self.fullcompare(other)[1] >= 0 + else: + return NotImplemented + + def __gt__(self, other): + if isinstance(other, Name): + return self.fullcompare(other)[1] > 0 + else: + return NotImplemented + + def __repr__(self): + return '' + + def __str__(self): + return self.to_text(False) + + def to_text(self, omit_final_dot=False): + """Convert name to DNS text format. + + *omit_final_dot* is a ``bool``. If True, don't emit the final + dot (denoting the root label) for absolute names. The default + is False. + + Returns a ``text``. + """ + + if len(self.labels) == 0: + return maybe_decode(b'@') + if len(self.labels) == 1 and self.labels[0] == b'': + return maybe_decode(b'.') + if omit_final_dot and self.is_absolute(): + l = self.labels[:-1] + else: + l = self.labels + s = b'.'.join(map(_escapify, l)) + return maybe_decode(s) + + def to_unicode(self, omit_final_dot=False, idna_codec=None): + """Convert name to Unicode text format. + + IDN ACE labels are converted to Unicode. + + *omit_final_dot* is a ``bool``. If True, don't emit the final + dot (denoting the root label) for absolute names. The default + is False. + *idna_codec* specifies the IDNA encoder/decoder. If None, the + dns.name.IDNA_2003_Practical encoder/decoder is used. + The IDNA_2003_Practical decoder does + not impose any policy, it just decodes punycode, so if you + don't want checking for compliance, you can use this decoder + for IDNA2008 as well. + + Returns a ``text``. + """ + + if len(self.labels) == 0: + return u'@' + if len(self.labels) == 1 and self.labels[0] == b'': + return u'.' + if omit_final_dot and self.is_absolute(): + l = self.labels[:-1] + else: + l = self.labels + if idna_codec is None: + idna_codec = IDNA_2003_Practical + return u'.'.join([idna_codec.decode(x) for x in l]) + + def to_digestable(self, origin=None): + """Convert name to a format suitable for digesting in hashes. + + The name is canonicalized and converted to uncompressed wire + format. All names in wire format are absolute. If the name + is a relative name, then an origin must be supplied. + + *origin* is a ``dns.name.Name`` or ``None``. If the name is + relative and origin is not ``None``, then origin will be appended + to the name. + + Raises ``dns.name.NeedAbsoluteNameOrOrigin`` if the name is + relative and no origin was provided. + + Returns a ``binary``. + """ + + if not self.is_absolute(): + if origin is None or not origin.is_absolute(): + raise NeedAbsoluteNameOrOrigin + labels = list(self.labels) + labels.extend(list(origin.labels)) + else: + labels = self.labels + dlabels = [struct.pack('!B%ds' % len(x), len(x), x.lower()) + for x in labels] + return b''.join(dlabels) + + def to_wire(self, file=None, compress=None, origin=None): + """Convert name to wire format, possibly compressing it. + + *file* is the file where the name is emitted (typically a + BytesIO file). If ``None`` (the default), a ``binary`` + containing the wire name will be returned. + + *compress*, a ``dict``, is the compression table to use. If + ``None`` (the default), names will not be compressed. + + *origin* is a ``dns.name.Name`` or ``None``. If the name is + relative and origin is not ``None``, then *origin* will be appended + to it. + + Raises ``dns.name.NeedAbsoluteNameOrOrigin`` if the name is + relative and no origin was provided. + + Returns a ``binary`` or ``None``. + """ + + if file is None: + file = BytesIO() + want_return = True + else: + want_return = False + + if not self.is_absolute(): + if origin is None or not origin.is_absolute(): + raise NeedAbsoluteNameOrOrigin + labels = list(self.labels) + labels.extend(list(origin.labels)) + else: + labels = self.labels + i = 0 + for label in labels: + n = Name(labels[i:]) + i += 1 + if compress is not None: + pos = compress.get(n) + else: + pos = None + if pos is not None: + value = 0xc000 + pos + s = struct.pack('!H', value) + file.write(s) + break + else: + if compress is not None and len(n) > 1: + pos = file.tell() + if pos <= 0x3fff: + compress[n] = pos + l = len(label) + file.write(struct.pack('!B', l)) + if l > 0: + file.write(label) + if want_return: + return file.getvalue() + + def __len__(self): + """The length of the name (in labels). + + Returns an ``int``. + """ + + return len(self.labels) + + def __getitem__(self, index): + return self.labels[index] + + def __add__(self, other): + return self.concatenate(other) + + def __sub__(self, other): + return self.relativize(other) + + def split(self, depth): + """Split a name into a prefix and suffix names at the specified depth. + + *depth* is an ``int`` specifying the number of labels in the suffix + + Raises ``ValueError`` if *depth* was not >= 0 and <= the length of the + name. + + Returns the tuple ``(prefix, suffix)``. + """ + + l = len(self.labels) + if depth == 0: + return (self, dns.name.empty) + elif depth == l: + return (dns.name.empty, self) + elif depth < 0 or depth > l: + raise ValueError( + 'depth must be >= 0 and <= the length of the name') + return (Name(self[: -depth]), Name(self[-depth:])) + + def concatenate(self, other): + """Return a new name which is the concatenation of self and other. + + Raises ``dns.name.AbsoluteConcatenation`` if the name is + absolute and *other* is not the empty name. + + Returns a ``dns.name.Name``. + """ + + if self.is_absolute() and len(other) > 0: + raise AbsoluteConcatenation + labels = list(self.labels) + labels.extend(list(other.labels)) + return Name(labels) + + def relativize(self, origin): + """If the name is a subdomain of *origin*, return a new name which is + the name relative to origin. Otherwise return the name. + + For example, relativizing ``www.dnspython.org.`` to origin + ``dnspython.org.`` returns the name ``www``. Relativizing ``example.`` + to origin ``dnspython.org.`` returns ``example.``. + + Returns a ``dns.name.Name``. + """ + + if origin is not None and self.is_subdomain(origin): + return Name(self[: -len(origin)]) + else: + return self + + def derelativize(self, origin): + """If the name is a relative name, return a new name which is the + concatenation of the name and origin. Otherwise return the name. + + For example, derelativizing ``www`` to origin ``dnspython.org.`` + returns the name ``www.dnspython.org.``. Derelativizing ``example.`` + to origin ``dnspython.org.`` returns ``example.``. + + Returns a ``dns.name.Name``. + """ + + if not self.is_absolute(): + return self.concatenate(origin) + else: + return self + + def choose_relativity(self, origin=None, relativize=True): + """Return a name with the relativity desired by the caller. + + If *origin* is ``None``, then the name is returned. + Otherwise, if *relativize* is ``True`` the name is + relativized, and if *relativize* is ``False`` the name is + derelativized. + + Returns a ``dns.name.Name``. + """ + + if origin: + if relativize: + return self.relativize(origin) + else: + return self.derelativize(origin) + else: + return self + + def parent(self): + """Return the parent of the name. + + For example, the parent of ``www.dnspython.org.`` is ``dnspython.org``. + + Raises ``dns.name.NoParent`` if the name is either the root name or the + empty name, and thus has no parent. + + Returns a ``dns.name.Name``. + """ + + if self == root or self == empty: + raise NoParent + return Name(self.labels[1:]) + +#: The root name, '.' +root = Name([b'']) + +#: The empty name. +empty = Name([]) + +def from_unicode(text, origin=root, idna_codec=None): + """Convert unicode text into a Name object. + + Labels are encoded in IDN ACE form according to rules specified by + the IDNA codec. + + *text*, a ``text``, is the text to convert into a name. + + *origin*, a ``dns.name.Name``, specifies the origin to + append to non-absolute names. The default is the root name. + + *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA + encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder + is used. + + Returns a ``dns.name.Name``. + """ + + if not isinstance(text, text_type): + raise ValueError("input to from_unicode() must be a unicode string") + if not (origin is None or isinstance(origin, Name)): + raise ValueError("origin must be a Name or None") + labels = [] + label = u'' + escaping = False + edigits = 0 + total = 0 + if idna_codec is None: + idna_codec = IDNA_2003 + if text == u'@': + text = u'' + if text: + if text == u'.': + return Name([b'']) # no Unicode "u" on this constant! + for c in text: + if escaping: + if edigits == 0: + if c.isdigit(): + total = int(c) + edigits += 1 + else: + label += c + escaping = False + else: + if not c.isdigit(): + raise BadEscape + total *= 10 + total += int(c) + edigits += 1 + if edigits == 3: + escaping = False + label += unichr(total) + elif c in [u'.', u'\u3002', u'\uff0e', u'\uff61']: + if len(label) == 0: + raise EmptyLabel + labels.append(idna_codec.encode(label)) + label = u'' + elif c == u'\\': + escaping = True + edigits = 0 + total = 0 + else: + label += c + if escaping: + raise BadEscape + if len(label) > 0: + labels.append(idna_codec.encode(label)) + else: + labels.append(b'') + + if (len(labels) == 0 or labels[-1] != b'') and origin is not None: + labels.extend(list(origin.labels)) + return Name(labels) + + +def from_text(text, origin=root, idna_codec=None): + """Convert text into a Name object. + + *text*, a ``text``, is the text to convert into a name. + + *origin*, a ``dns.name.Name``, specifies the origin to + append to non-absolute names. The default is the root name. + + *idna_codec*, a ``dns.name.IDNACodec``, specifies the IDNA + encoder/decoder. If ``None``, the default IDNA 2003 encoder/decoder + is used. + + Returns a ``dns.name.Name``. + """ + + if isinstance(text, text_type): + return from_unicode(text, origin, idna_codec) + if not isinstance(text, binary_type): + raise ValueError("input to from_text() must be a string") + if not (origin is None or isinstance(origin, Name)): + raise ValueError("origin must be a Name or None") + labels = [] + label = b'' + escaping = False + edigits = 0 + total = 0 + if text == b'@': + text = b'' + if text: + if text == b'.': + return Name([b'']) + for c in bytearray(text): + byte_ = struct.pack('!B', c) + if escaping: + if edigits == 0: + if byte_.isdigit(): + total = int(byte_) + edigits += 1 + else: + label += byte_ + escaping = False + else: + if not byte_.isdigit(): + raise BadEscape + total *= 10 + total += int(byte_) + edigits += 1 + if edigits == 3: + escaping = False + label += struct.pack('!B', total) + elif byte_ == b'.': + if len(label) == 0: + raise EmptyLabel + labels.append(label) + label = b'' + elif byte_ == b'\\': + escaping = True + edigits = 0 + total = 0 + else: + label += byte_ + if escaping: + raise BadEscape + if len(label) > 0: + labels.append(label) + else: + labels.append(b'') + if (len(labels) == 0 or labels[-1] != b'') and origin is not None: + labels.extend(list(origin.labels)) + return Name(labels) + + +def from_wire(message, current): + """Convert possibly compressed wire format into a Name. + + *message* is a ``binary`` containing an entire DNS message in DNS + wire form. + + *current*, an ``int``, is the offset of the beginning of the name + from the start of the message + + Raises ``dns.name.BadPointer`` if a compression pointer did not + point backwards in the message. + + Raises ``dns.name.BadLabelType`` if an invalid label type was encountered. + + Returns a ``(dns.name.Name, int)`` tuple consisting of the name + that was read and the number of bytes of the wire format message + which were consumed reading it. + """ + + if not isinstance(message, binary_type): + raise ValueError("input to from_wire() must be a byte string") + message = dns.wiredata.maybe_wrap(message) + labels = [] + biggest_pointer = current + hops = 0 + count = message[current] + current += 1 + cused = 1 + while count != 0: + if count < 64: + labels.append(message[current: current + count].unwrap()) + current += count + if hops == 0: + cused += count + elif count >= 192: + current = (count & 0x3f) * 256 + message[current] + if hops == 0: + cused += 1 + if current >= biggest_pointer: + raise BadPointer + biggest_pointer = current + hops += 1 + else: + raise BadLabelType + count = message[current] + current += 1 + if hops == 0: + cused += 1 + labels.append('') + return (Name(labels), cused) diff --git a/env/lib/python3.7/site-packages/dns/namedict.py b/env/lib/python3.7/site-packages/dns/namedict.py new file mode 100644 index 0000000..37a1310 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/namedict.py @@ -0,0 +1,108 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# Copyright (C) 2016 Coresec Systems AB +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND CORESEC SYSTEMS AB DISCLAIMS ALL +# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL CORESEC +# SYSTEMS AB BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION +# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS name dictionary""" + +import collections +import dns.name +from ._compat import xrange + + +class NameDict(collections.MutableMapping): + """A dictionary whose keys are dns.name.Name objects. + + In addition to being like a regular Python dictionary, this + dictionary can also get the deepest match for a given key. + """ + + __slots__ = ["max_depth", "max_depth_items", "__store"] + + def __init__(self, *args, **kwargs): + super(NameDict, self).__init__() + self.__store = dict() + #: the maximum depth of the keys that have ever been added + self.max_depth = 0 + #: the number of items of maximum depth + self.max_depth_items = 0 + self.update(dict(*args, **kwargs)) + + def __update_max_depth(self, key): + if len(key) == self.max_depth: + self.max_depth_items = self.max_depth_items + 1 + elif len(key) > self.max_depth: + self.max_depth = len(key) + self.max_depth_items = 1 + + def __getitem__(self, key): + return self.__store[key] + + def __setitem__(self, key, value): + if not isinstance(key, dns.name.Name): + raise ValueError('NameDict key must be a name') + self.__store[key] = value + self.__update_max_depth(key) + + def __delitem__(self, key): + value = self.__store.pop(key) + if len(value) == self.max_depth: + self.max_depth_items = self.max_depth_items - 1 + if self.max_depth_items == 0: + self.max_depth = 0 + for k in self.__store: + self.__update_max_depth(k) + + def __iter__(self): + return iter(self.__store) + + def __len__(self): + return len(self.__store) + + def has_key(self, key): + return key in self.__store + + def get_deepest_match(self, name): + """Find the deepest match to *fname* in the dictionary. + + The deepest match is the longest name in the dictionary which is + a superdomain of *name*. Note that *superdomain* includes matching + *name* itself. + + *name*, a ``dns.name.Name``, the name to find. + + Returns a ``(key, value)`` where *key* is the deepest + ``dns.name.Name``, and *value* is the value associated with *key*. + """ + + depth = len(name) + if depth > self.max_depth: + depth = self.max_depth + for i in xrange(-depth, 0): + n = dns.name.Name(name[i:]) + if n in self: + return (n, self[n]) + v = self[dns.name.empty] + return (dns.name.empty, v) diff --git a/env/lib/python3.7/site-packages/dns/node.py b/env/lib/python3.7/site-packages/dns/node.py new file mode 100644 index 0000000..8a7f19f --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/node.py @@ -0,0 +1,182 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS nodes. A node is a set of rdatasets.""" + +from io import StringIO + +import dns.rdataset +import dns.rdatatype +import dns.renderer + + +class Node(object): + + """A Node is a set of rdatasets.""" + + __slots__ = ['rdatasets'] + + def __init__(self): + #: the set of rdatsets, represented as a list. + self.rdatasets = [] + + def to_text(self, name, **kw): + """Convert a node to text format. + + Each rdataset at the node is printed. Any keyword arguments + to this method are passed on to the rdataset's to_text() method. + + *name*, a ``dns.name.Name`` or ``text``, the owner name of the rdatasets. + + Returns a ``text``. + """ + + s = StringIO() + for rds in self.rdatasets: + if len(rds) > 0: + s.write(rds.to_text(name, **kw)) + s.write(u'\n') + return s.getvalue()[:-1] + + def __repr__(self): + return '' + + def __eq__(self, other): + # + # This is inefficient. Good thing we don't need to do it much. + # + for rd in self.rdatasets: + if rd not in other.rdatasets: + return False + for rd in other.rdatasets: + if rd not in self.rdatasets: + return False + return True + + def __ne__(self, other): + return not self.__eq__(other) + + def __len__(self): + return len(self.rdatasets) + + def __iter__(self): + return iter(self.rdatasets) + + def find_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE, + create=False): + """Find an rdataset matching the specified properties in the + current node. + + *rdclass*, an ``int``, the class of the rdataset. + + *rdtype*, an ``int``, the type of the rdataset. + + *covers*, an ``int``, the covered type. Usually this value is + dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or + dns.rdatatype.RRSIG, then the covers value will be the rdata + type the SIG/RRSIG covers. The library treats the SIG and RRSIG + types as if they were a family of + types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much + easier to work with than if RRSIGs covering different rdata + types were aggregated into a single RRSIG rdataset. + + *create*, a ``bool``. If True, create the rdataset if it is not found. + + Raises ``KeyError`` if an rdataset of the desired type and class does + not exist and *create* is not ``True``. + + Returns a ``dns.rdataset.Rdataset``. + """ + + for rds in self.rdatasets: + if rds.match(rdclass, rdtype, covers): + return rds + if not create: + raise KeyError + rds = dns.rdataset.Rdataset(rdclass, rdtype) + self.rdatasets.append(rds) + return rds + + def get_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE, + create=False): + """Get an rdataset matching the specified properties in the + current node. + + None is returned if an rdataset of the specified type and + class does not exist and *create* is not ``True``. + + *rdclass*, an ``int``, the class of the rdataset. + + *rdtype*, an ``int``, the type of the rdataset. + + *covers*, an ``int``, the covered type. Usually this value is + dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or + dns.rdatatype.RRSIG, then the covers value will be the rdata + type the SIG/RRSIG covers. The library treats the SIG and RRSIG + types as if they were a family of + types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much + easier to work with than if RRSIGs covering different rdata + types were aggregated into a single RRSIG rdataset. + + *create*, a ``bool``. If True, create the rdataset if it is not found. + + Returns a ``dns.rdataset.Rdataset`` or ``None``. + """ + + try: + rds = self.find_rdataset(rdclass, rdtype, covers, create) + except KeyError: + rds = None + return rds + + def delete_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE): + """Delete the rdataset matching the specified properties in the + current node. + + If a matching rdataset does not exist, it is not an error. + + *rdclass*, an ``int``, the class of the rdataset. + + *rdtype*, an ``int``, the type of the rdataset. + + *covers*, an ``int``, the covered type. + """ + + rds = self.get_rdataset(rdclass, rdtype, covers) + if rds is not None: + self.rdatasets.remove(rds) + + def replace_rdataset(self, replacement): + """Replace an rdataset. + + It is not an error if there is no rdataset matching *replacement*. + + Ownership of the *replacement* object is transferred to the node; + in other words, this method does not store a copy of *replacement* + at the node, it stores *replacement* itself. + + *replacement*, a ``dns.rdataset.Rdataset``. + + Raises ``ValueError`` if *replacement* is not a + ``dns.rdataset.Rdataset``. + """ + + if not isinstance(replacement, dns.rdataset.Rdataset): + raise ValueError('replacement is not an rdataset') + self.delete_rdataset(replacement.rdclass, replacement.rdtype, + replacement.covers) + self.rdatasets.append(replacement) diff --git a/env/lib/python3.7/site-packages/dns/opcode.py b/env/lib/python3.7/site-packages/dns/opcode.py new file mode 100644 index 0000000..c0735ba --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/opcode.py @@ -0,0 +1,119 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Opcodes.""" + +import dns.exception + +#: Query +QUERY = 0 +#: Inverse Query (historical) +IQUERY = 1 +#: Server Status (unspecified and unimplemented anywhere) +STATUS = 2 +#: Notify +NOTIFY = 4 +#: Dynamic Update +UPDATE = 5 + +_by_text = { + 'QUERY': QUERY, + 'IQUERY': IQUERY, + 'STATUS': STATUS, + 'NOTIFY': NOTIFY, + 'UPDATE': UPDATE +} + +# We construct the inverse mapping programmatically to ensure that we +# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that +# would cause the mapping not to be true inverse. + +_by_value = {y: x for x, y in _by_text.items()} + + +class UnknownOpcode(dns.exception.DNSException): + """An DNS opcode is unknown.""" + + +def from_text(text): + """Convert text into an opcode. + + *text*, a ``text``, the textual opcode + + Raises ``dns.opcode.UnknownOpcode`` if the opcode is unknown. + + Returns an ``int``. + """ + + if text.isdigit(): + value = int(text) + if value >= 0 and value <= 15: + return value + value = _by_text.get(text.upper()) + if value is None: + raise UnknownOpcode + return value + + +def from_flags(flags): + """Extract an opcode from DNS message flags. + + *flags*, an ``int``, the DNS flags. + + Returns an ``int``. + """ + + return (flags & 0x7800) >> 11 + + +def to_flags(value): + """Convert an opcode to a value suitable for ORing into DNS message + flags. + + *value*, an ``int``, the DNS opcode value. + + Returns an ``int``. + """ + + return (value << 11) & 0x7800 + + +def to_text(value): + """Convert an opcode to text. + + *value*, an ``int`` the opcode value, + + Raises ``dns.opcode.UnknownOpcode`` if the opcode is unknown. + + Returns a ``text``. + """ + + text = _by_value.get(value) + if text is None: + text = str(value) + return text + + +def is_update(flags): + """Is the opcode in flags UPDATE? + + *flags*, an ``int``, the DNS message flags. + + Returns a ``bool``. + """ + + return from_flags(flags) == UPDATE diff --git a/env/lib/python3.7/site-packages/dns/py.typed b/env/lib/python3.7/site-packages/dns/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/dns/query.py b/env/lib/python3.7/site-packages/dns/query.py new file mode 100644 index 0000000..c0c517c --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/query.py @@ -0,0 +1,683 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Talk to a DNS server.""" + +from __future__ import generators + +import errno +import select +import socket +import struct +import sys +import time + +import dns.exception +import dns.inet +import dns.name +import dns.message +import dns.rcode +import dns.rdataclass +import dns.rdatatype +from ._compat import long, string_types, PY3 + +if PY3: + select_error = OSError +else: + select_error = select.error + +# Function used to create a socket. Can be overridden if needed in special +# situations. +socket_factory = socket.socket + +class UnexpectedSource(dns.exception.DNSException): + """A DNS query response came from an unexpected address or port.""" + + +class BadResponse(dns.exception.FormError): + """A DNS query response does not respond to the question asked.""" + + +class TransferError(dns.exception.DNSException): + """A zone transfer response got a non-zero rcode.""" + + def __init__(self, rcode): + message = 'Zone transfer error: %s' % dns.rcode.to_text(rcode) + super(TransferError, self).__init__(message) + self.rcode = rcode + + +def _compute_expiration(timeout): + if timeout is None: + return None + else: + return time.time() + timeout + +# This module can use either poll() or select() as the "polling backend". +# +# A backend function takes an fd, bools for readability, writablity, and +# error detection, and a timeout. + +def _poll_for(fd, readable, writable, error, timeout): + """Poll polling backend.""" + + event_mask = 0 + if readable: + event_mask |= select.POLLIN + if writable: + event_mask |= select.POLLOUT + if error: + event_mask |= select.POLLERR + + pollable = select.poll() + pollable.register(fd, event_mask) + + if timeout: + event_list = pollable.poll(long(timeout * 1000)) + else: + event_list = pollable.poll() + + return bool(event_list) + + +def _select_for(fd, readable, writable, error, timeout): + """Select polling backend.""" + + rset, wset, xset = [], [], [] + + if readable: + rset = [fd] + if writable: + wset = [fd] + if error: + xset = [fd] + + if timeout is None: + (rcount, wcount, xcount) = select.select(rset, wset, xset) + else: + (rcount, wcount, xcount) = select.select(rset, wset, xset, timeout) + + return bool((rcount or wcount or xcount)) + + +def _wait_for(fd, readable, writable, error, expiration): + # Use the selected polling backend to wait for any of the specified + # events. An "expiration" absolute time is converted into a relative + # timeout. + + done = False + while not done: + if expiration is None: + timeout = None + else: + timeout = expiration - time.time() + if timeout <= 0.0: + raise dns.exception.Timeout + try: + if not _polling_backend(fd, readable, writable, error, timeout): + raise dns.exception.Timeout + except select_error as e: + if e.args[0] != errno.EINTR: + raise e + done = True + + +def _set_polling_backend(fn): + # Internal API. Do not use. + + global _polling_backend + + _polling_backend = fn + +if hasattr(select, 'poll'): + # Prefer poll() on platforms that support it because it has no + # limits on the maximum value of a file descriptor (plus it will + # be more efficient for high values). + _polling_backend = _poll_for +else: + _polling_backend = _select_for + + +def _wait_for_readable(s, expiration): + _wait_for(s, True, False, True, expiration) + + +def _wait_for_writable(s, expiration): + _wait_for(s, False, True, True, expiration) + + +def _addresses_equal(af, a1, a2): + # Convert the first value of the tuple, which is a textual format + # address into binary form, so that we are not confused by different + # textual representations of the same address + try: + n1 = dns.inet.inet_pton(af, a1[0]) + n2 = dns.inet.inet_pton(af, a2[0]) + except dns.exception.SyntaxError: + return False + return n1 == n2 and a1[1:] == a2[1:] + + +def _destination_and_source(af, where, port, source, source_port): + # Apply defaults and compute destination and source tuples + # suitable for use in connect(), sendto(), or bind(). + if af is None: + try: + af = dns.inet.af_for_address(where) + except Exception: + af = dns.inet.AF_INET + if af == dns.inet.AF_INET: + destination = (where, port) + if source is not None or source_port != 0: + if source is None: + source = '0.0.0.0' + source = (source, source_port) + elif af == dns.inet.AF_INET6: + destination = (where, port, 0, 0) + if source is not None or source_port != 0: + if source is None: + source = '::' + source = (source, source_port, 0, 0) + return (af, destination, source) + + +def send_udp(sock, what, destination, expiration=None): + """Send a DNS message to the specified UDP socket. + + *sock*, a ``socket``. + + *what*, a ``binary`` or ``dns.message.Message``, the message to send. + + *destination*, a destination tuple appropriate for the address family + of the socket, specifying where to send the query. + + *expiration*, a ``float`` or ``None``, the absolute time at which + a timeout exception should be raised. If ``None``, no timeout will + occur. + + Returns an ``(int, float)`` tuple of bytes sent and the sent time. + """ + + if isinstance(what, dns.message.Message): + what = what.to_wire() + _wait_for_writable(sock, expiration) + sent_time = time.time() + n = sock.sendto(what, destination) + return (n, sent_time) + + +def receive_udp(sock, destination, expiration=None, + ignore_unexpected=False, one_rr_per_rrset=False, + keyring=None, request_mac=b'', ignore_trailing=False): + """Read a DNS message from a UDP socket. + + *sock*, a ``socket``. + + *destination*, a destination tuple appropriate for the address family + of the socket, specifying where the associated query was sent. + + *expiration*, a ``float`` or ``None``, the absolute time at which + a timeout exception should be raised. If ``None``, no timeout will + occur. + + *ignore_unexpected*, a ``bool``. If ``True``, ignore responses from + unexpected sources. + + *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own + RRset. + + *keyring*, a ``dict``, the keyring to use for TSIG. + + *request_mac*, a ``binary``, the MAC of the request (for TSIG). + + *ignore_trailing*, a ``bool``. If ``True``, ignore trailing + junk at end of the received message. + + Raises if the message is malformed, if network errors occur, of if + there is a timeout. + + Returns a ``dns.message.Message`` object. + """ + + wire = b'' + while 1: + _wait_for_readable(sock, expiration) + (wire, from_address) = sock.recvfrom(65535) + if _addresses_equal(sock.family, from_address, destination) or \ + (dns.inet.is_multicast(destination[0]) and + from_address[1:] == destination[1:]): + break + if not ignore_unexpected: + raise UnexpectedSource('got a response from ' + '%s instead of %s' % (from_address, + destination)) + received_time = time.time() + r = dns.message.from_wire(wire, keyring=keyring, request_mac=request_mac, + one_rr_per_rrset=one_rr_per_rrset, + ignore_trailing=ignore_trailing) + return (r, received_time) + +def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0, + ignore_unexpected=False, one_rr_per_rrset=False, ignore_trailing=False): + """Return the response obtained after sending a query via UDP. + + *q*, a ``dns.message.Message``, the query to send + + *where*, a ``text`` containing an IPv4 or IPv6 address, where + to send the message. + + *timeout*, a ``float`` or ``None``, the number of seconds to wait before the + query times out. If ``None``, the default, wait forever. + + *port*, an ``int``, the port send the message to. The default is 53. + + *af*, an ``int``, the address family to use. The default is ``None``, + which causes the address family to use to be inferred from the form of + *where*. If the inference attempt fails, AF_INET is used. This + parameter is historical; you need never set it. + + *source*, a ``text`` containing an IPv4 or IPv6 address, specifying + the source address. The default is the wildcard address. + + *source_port*, an ``int``, the port from which to send the message. + The default is 0. + + *ignore_unexpected*, a ``bool``. If ``True``, ignore responses from + unexpected sources. + + *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own + RRset. + + *ignore_trailing*, a ``bool``. If ``True``, ignore trailing + junk at end of the received message. + + Returns a ``dns.message.Message``. + """ + + wire = q.to_wire() + (af, destination, source) = _destination_and_source(af, where, port, + source, source_port) + s = socket_factory(af, socket.SOCK_DGRAM, 0) + received_time = None + sent_time = None + try: + expiration = _compute_expiration(timeout) + s.setblocking(0) + if source is not None: + s.bind(source) + (_, sent_time) = send_udp(s, wire, destination, expiration) + (r, received_time) = receive_udp(s, destination, expiration, + ignore_unexpected, one_rr_per_rrset, + q.keyring, q.mac, ignore_trailing) + finally: + if sent_time is None or received_time is None: + response_time = 0 + else: + response_time = received_time - sent_time + s.close() + r.time = response_time + if not q.is_response(r): + raise BadResponse + return r + + +def _net_read(sock, count, expiration): + """Read the specified number of bytes from sock. Keep trying until we + either get the desired amount, or we hit EOF. + A Timeout exception will be raised if the operation is not completed + by the expiration time. + """ + s = b'' + while count > 0: + _wait_for_readable(sock, expiration) + n = sock.recv(count) + if n == b'': + raise EOFError + count = count - len(n) + s = s + n + return s + + +def _net_write(sock, data, expiration): + """Write the specified data to the socket. + A Timeout exception will be raised if the operation is not completed + by the expiration time. + """ + current = 0 + l = len(data) + while current < l: + _wait_for_writable(sock, expiration) + current += sock.send(data[current:]) + + +def send_tcp(sock, what, expiration=None): + """Send a DNS message to the specified TCP socket. + + *sock*, a ``socket``. + + *what*, a ``binary`` or ``dns.message.Message``, the message to send. + + *expiration*, a ``float`` or ``None``, the absolute time at which + a timeout exception should be raised. If ``None``, no timeout will + occur. + + Returns an ``(int, float)`` tuple of bytes sent and the sent time. + """ + + if isinstance(what, dns.message.Message): + what = what.to_wire() + l = len(what) + # copying the wire into tcpmsg is inefficient, but lets us + # avoid writev() or doing a short write that would get pushed + # onto the net + tcpmsg = struct.pack("!H", l) + what + _wait_for_writable(sock, expiration) + sent_time = time.time() + _net_write(sock, tcpmsg, expiration) + return (len(tcpmsg), sent_time) + +def receive_tcp(sock, expiration=None, one_rr_per_rrset=False, + keyring=None, request_mac=b'', ignore_trailing=False): + """Read a DNS message from a TCP socket. + + *sock*, a ``socket``. + + *expiration*, a ``float`` or ``None``, the absolute time at which + a timeout exception should be raised. If ``None``, no timeout will + occur. + + *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own + RRset. + + *keyring*, a ``dict``, the keyring to use for TSIG. + + *request_mac*, a ``binary``, the MAC of the request (for TSIG). + + *ignore_trailing*, a ``bool``. If ``True``, ignore trailing + junk at end of the received message. + + Raises if the message is malformed, if network errors occur, of if + there is a timeout. + + Returns a ``dns.message.Message`` object. + """ + + ldata = _net_read(sock, 2, expiration) + (l,) = struct.unpack("!H", ldata) + wire = _net_read(sock, l, expiration) + received_time = time.time() + r = dns.message.from_wire(wire, keyring=keyring, request_mac=request_mac, + one_rr_per_rrset=one_rr_per_rrset, + ignore_trailing=ignore_trailing) + return (r, received_time) + +def _connect(s, address): + try: + s.connect(address) + except socket.error: + (ty, v) = sys.exc_info()[:2] + + if hasattr(v, 'errno'): + v_err = v.errno + else: + v_err = v[0] + if v_err not in [errno.EINPROGRESS, errno.EWOULDBLOCK, errno.EALREADY]: + raise v + + +def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0, + one_rr_per_rrset=False, ignore_trailing=False): + """Return the response obtained after sending a query via TCP. + + *q*, a ``dns.message.Message``, the query to send + + *where*, a ``text`` containing an IPv4 or IPv6 address, where + to send the message. + + *timeout*, a ``float`` or ``None``, the number of seconds to wait before the + query times out. If ``None``, the default, wait forever. + + *port*, an ``int``, the port send the message to. The default is 53. + + *af*, an ``int``, the address family to use. The default is ``None``, + which causes the address family to use to be inferred from the form of + *where*. If the inference attempt fails, AF_INET is used. This + parameter is historical; you need never set it. + + *source*, a ``text`` containing an IPv4 or IPv6 address, specifying + the source address. The default is the wildcard address. + + *source_port*, an ``int``, the port from which to send the message. + The default is 0. + + *one_rr_per_rrset*, a ``bool``. If ``True``, put each RR into its own + RRset. + + *ignore_trailing*, a ``bool``. If ``True``, ignore trailing + junk at end of the received message. + + Returns a ``dns.message.Message``. + """ + + wire = q.to_wire() + (af, destination, source) = _destination_and_source(af, where, port, + source, source_port) + s = socket_factory(af, socket.SOCK_STREAM, 0) + begin_time = None + received_time = None + try: + expiration = _compute_expiration(timeout) + s.setblocking(0) + begin_time = time.time() + if source is not None: + s.bind(source) + _connect(s, destination) + send_tcp(s, wire, expiration) + (r, received_time) = receive_tcp(s, expiration, one_rr_per_rrset, + q.keyring, q.mac, ignore_trailing) + finally: + if begin_time is None or received_time is None: + response_time = 0 + else: + response_time = received_time - begin_time + s.close() + r.time = response_time + if not q.is_response(r): + raise BadResponse + return r + + +def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN, + timeout=None, port=53, keyring=None, keyname=None, relativize=True, + af=None, lifetime=None, source=None, source_port=0, serial=0, + use_udp=False, keyalgorithm=dns.tsig.default_algorithm): + """Return a generator for the responses to a zone transfer. + + *where*. If the inference attempt fails, AF_INET is used. This + parameter is historical; you need never set it. + + *zone*, a ``dns.name.Name`` or ``text``, the name of the zone to transfer. + + *rdtype*, an ``int`` or ``text``, the type of zone transfer. The + default is ``dns.rdatatype.AXFR``. ``dns.rdatatype.IXFR`` can be + used to do an incremental transfer instead. + + *rdclass*, an ``int`` or ``text``, the class of the zone transfer. + The default is ``dns.rdataclass.IN``. + + *timeout*, a ``float``, the number of seconds to wait for each + response message. If None, the default, wait forever. + + *port*, an ``int``, the port send the message to. The default is 53. + + *keyring*, a ``dict``, the keyring to use for TSIG. + + *keyname*, a ``dns.name.Name`` or ``text``, the name of the TSIG + key to use. + + *relativize*, a ``bool``. If ``True``, all names in the zone will be + relativized to the zone origin. It is essential that the + relativize setting matches the one specified to + ``dns.zone.from_xfr()`` if using this generator to make a zone. + + *af*, an ``int``, the address family to use. The default is ``None``, + which causes the address family to use to be inferred from the form of + *where*. If the inference attempt fails, AF_INET is used. This + parameter is historical; you need never set it. + + *lifetime*, a ``float``, the total number of seconds to spend + doing the transfer. If ``None``, the default, then there is no + limit on the time the transfer may take. + + *source*, a ``text`` containing an IPv4 or IPv6 address, specifying + the source address. The default is the wildcard address. + + *source_port*, an ``int``, the port from which to send the message. + The default is 0. + + *serial*, an ``int``, the SOA serial number to use as the base for + an IXFR diff sequence (only meaningful if *rdtype* is + ``dns.rdatatype.IXFR``). + + *use_udp*, a ``bool``. If ``True``, use UDP (only meaningful for IXFR). + + *keyalgorithm*, a ``dns.name.Name`` or ``text``, the TSIG algorithm to use. + + Raises on errors, and so does the generator. + + Returns a generator of ``dns.message.Message`` objects. + """ + + if isinstance(zone, string_types): + zone = dns.name.from_text(zone) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + q = dns.message.make_query(zone, rdtype, rdclass) + if rdtype == dns.rdatatype.IXFR: + rrset = dns.rrset.from_text(zone, 0, 'IN', 'SOA', + '. . %u 0 0 0 0' % serial) + q.authority.append(rrset) + if keyring is not None: + q.use_tsig(keyring, keyname, algorithm=keyalgorithm) + wire = q.to_wire() + (af, destination, source) = _destination_and_source(af, where, port, + source, source_port) + if use_udp: + if rdtype != dns.rdatatype.IXFR: + raise ValueError('cannot do a UDP AXFR') + s = socket_factory(af, socket.SOCK_DGRAM, 0) + else: + s = socket_factory(af, socket.SOCK_STREAM, 0) + s.setblocking(0) + if source is not None: + s.bind(source) + expiration = _compute_expiration(lifetime) + _connect(s, destination) + l = len(wire) + if use_udp: + _wait_for_writable(s, expiration) + s.send(wire) + else: + tcpmsg = struct.pack("!H", l) + wire + _net_write(s, tcpmsg, expiration) + done = False + delete_mode = True + expecting_SOA = False + soa_rrset = None + if relativize: + origin = zone + oname = dns.name.empty + else: + origin = None + oname = zone + tsig_ctx = None + first = True + while not done: + mexpiration = _compute_expiration(timeout) + if mexpiration is None or mexpiration > expiration: + mexpiration = expiration + if use_udp: + _wait_for_readable(s, expiration) + (wire, from_address) = s.recvfrom(65535) + else: + ldata = _net_read(s, 2, mexpiration) + (l,) = struct.unpack("!H", ldata) + wire = _net_read(s, l, mexpiration) + is_ixfr = (rdtype == dns.rdatatype.IXFR) + r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac, + xfr=True, origin=origin, tsig_ctx=tsig_ctx, + multi=True, first=first, + one_rr_per_rrset=is_ixfr) + rcode = r.rcode() + if rcode != dns.rcode.NOERROR: + raise TransferError(rcode) + tsig_ctx = r.tsig_ctx + first = False + answer_index = 0 + if soa_rrset is None: + if not r.answer or r.answer[0].name != oname: + raise dns.exception.FormError( + "No answer or RRset not for qname") + rrset = r.answer[0] + if rrset.rdtype != dns.rdatatype.SOA: + raise dns.exception.FormError("first RRset is not an SOA") + answer_index = 1 + soa_rrset = rrset.copy() + if rdtype == dns.rdatatype.IXFR: + if soa_rrset[0].serial <= serial: + # + # We're already up-to-date. + # + done = True + else: + expecting_SOA = True + # + # Process SOAs in the answer section (other than the initial + # SOA in the first message). + # + for rrset in r.answer[answer_index:]: + if done: + raise dns.exception.FormError("answers after final SOA") + if rrset.rdtype == dns.rdatatype.SOA and rrset.name == oname: + if expecting_SOA: + if rrset[0].serial != serial: + raise dns.exception.FormError( + "IXFR base serial mismatch") + expecting_SOA = False + elif rdtype == dns.rdatatype.IXFR: + delete_mode = not delete_mode + # + # If this SOA RRset is equal to the first we saw then we're + # finished. If this is an IXFR we also check that we're seeing + # the record in the expected part of the response. + # + if rrset == soa_rrset and \ + (rdtype == dns.rdatatype.AXFR or + (rdtype == dns.rdatatype.IXFR and delete_mode)): + done = True + elif expecting_SOA: + # + # We made an IXFR request and are expecting another + # SOA RR, but saw something else, so this must be an + # AXFR response. + # + rdtype = dns.rdatatype.AXFR + expecting_SOA = False + if done and q.keyring and not r.had_tsig: + raise dns.exception.FormError("missing TSIG") + yield r + s.close() diff --git a/env/lib/python3.7/site-packages/dns/rcode.py b/env/lib/python3.7/site-packages/dns/rcode.py new file mode 100644 index 0000000..5191e1b --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rcode.py @@ -0,0 +1,144 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Result Codes.""" + +import dns.exception +from ._compat import long + +#: No error +NOERROR = 0 +#: Form error +FORMERR = 1 +#: Server failure +SERVFAIL = 2 +#: Name does not exist ("Name Error" in RFC 1025 terminology). +NXDOMAIN = 3 +#: Not implemented +NOTIMP = 4 +#: Refused +REFUSED = 5 +#: Name exists. +YXDOMAIN = 6 +#: RRset exists. +YXRRSET = 7 +#: RRset does not exist. +NXRRSET = 8 +#: Not authoritative. +NOTAUTH = 9 +#: Name not in zone. +NOTZONE = 10 +#: Bad EDNS version. +BADVERS = 16 + +_by_text = { + 'NOERROR': NOERROR, + 'FORMERR': FORMERR, + 'SERVFAIL': SERVFAIL, + 'NXDOMAIN': NXDOMAIN, + 'NOTIMP': NOTIMP, + 'REFUSED': REFUSED, + 'YXDOMAIN': YXDOMAIN, + 'YXRRSET': YXRRSET, + 'NXRRSET': NXRRSET, + 'NOTAUTH': NOTAUTH, + 'NOTZONE': NOTZONE, + 'BADVERS': BADVERS +} + +# We construct the inverse mapping programmatically to ensure that we +# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that +# would cause the mapping not to be a true inverse. + +_by_value = {y: x for x, y in _by_text.items()} + + +class UnknownRcode(dns.exception.DNSException): + """A DNS rcode is unknown.""" + + +def from_text(text): + """Convert text into an rcode. + + *text*, a ``text``, the textual rcode or an integer in textual form. + + Raises ``dns.rcode.UnknownRcode`` if the rcode mnemonic is unknown. + + Returns an ``int``. + """ + + if text.isdigit(): + v = int(text) + if v >= 0 and v <= 4095: + return v + v = _by_text.get(text.upper()) + if v is None: + raise UnknownRcode + return v + + +def from_flags(flags, ednsflags): + """Return the rcode value encoded by flags and ednsflags. + + *flags*, an ``int``, the DNS flags field. + + *ednsflags*, an ``int``, the EDNS flags field. + + Raises ``ValueError`` if rcode is < 0 or > 4095 + + Returns an ``int``. + """ + + value = (flags & 0x000f) | ((ednsflags >> 20) & 0xff0) + if value < 0 or value > 4095: + raise ValueError('rcode must be >= 0 and <= 4095') + return value + + +def to_flags(value): + """Return a (flags, ednsflags) tuple which encodes the rcode. + + *value*, an ``int``, the rcode. + + Raises ``ValueError`` if rcode is < 0 or > 4095. + + Returns an ``(int, int)`` tuple. + """ + + if value < 0 or value > 4095: + raise ValueError('rcode must be >= 0 and <= 4095') + v = value & 0xf + ev = long(value & 0xff0) << 20 + return (v, ev) + + +def to_text(value): + """Convert rcode into text. + + *value*, and ``int``, the rcode. + + Raises ``ValueError`` if rcode is < 0 or > 4095. + + Returns a ``text``. + """ + + if value < 0 or value > 4095: + raise ValueError('rcode must be >= 0 and <= 4095') + text = _by_value.get(value) + if text is None: + text = str(value) + return text diff --git a/env/lib/python3.7/site-packages/dns/rdata.py b/env/lib/python3.7/site-packages/dns/rdata.py new file mode 100644 index 0000000..ea1971d --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdata.py @@ -0,0 +1,456 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS rdata.""" + +from io import BytesIO +import base64 +import binascii + +import dns.exception +import dns.name +import dns.rdataclass +import dns.rdatatype +import dns.tokenizer +import dns.wiredata +from ._compat import xrange, string_types, text_type + +try: + import threading as _threading +except ImportError: + import dummy_threading as _threading + +_hex_chunksize = 32 + + +def _hexify(data, chunksize=_hex_chunksize): + """Convert a binary string into its hex encoding, broken up into chunks + of chunksize characters separated by a space. + """ + + line = binascii.hexlify(data) + return b' '.join([line[i:i + chunksize] + for i + in range(0, len(line), chunksize)]).decode() + +_base64_chunksize = 32 + + +def _base64ify(data, chunksize=_base64_chunksize): + """Convert a binary string into its base64 encoding, broken up into chunks + of chunksize characters separated by a space. + """ + + line = base64.b64encode(data) + return b' '.join([line[i:i + chunksize] + for i + in range(0, len(line), chunksize)]).decode() + +__escaped = bytearray(b'"\\') + +def _escapify(qstring): + """Escape the characters in a quoted string which need it.""" + + if isinstance(qstring, text_type): + qstring = qstring.encode() + if not isinstance(qstring, bytearray): + qstring = bytearray(qstring) + + text = '' + for c in qstring: + if c in __escaped: + text += '\\' + chr(c) + elif c >= 0x20 and c < 0x7F: + text += chr(c) + else: + text += '\\%03d' % c + return text + + +def _truncate_bitmap(what): + """Determine the index of greatest byte that isn't all zeros, and + return the bitmap that contains all the bytes less than that index. + """ + + for i in xrange(len(what) - 1, -1, -1): + if what[i] != 0: + return what[0: i + 1] + return what[0:1] + + +class Rdata(object): + """Base class for all DNS rdata types.""" + + __slots__ = ['rdclass', 'rdtype'] + + def __init__(self, rdclass, rdtype): + """Initialize an rdata. + + *rdclass*, an ``int`` is the rdataclass of the Rdata. + *rdtype*, an ``int`` is the rdatatype of the Rdata. + """ + + self.rdclass = rdclass + self.rdtype = rdtype + + def covers(self): + """Return the type a Rdata covers. + + DNS SIG/RRSIG rdatas apply to a specific type; this type is + returned by the covers() function. If the rdata type is not + SIG or RRSIG, dns.rdatatype.NONE is returned. This is useful when + creating rdatasets, allowing the rdataset to contain only RRSIGs + of a particular type, e.g. RRSIG(NS). + + Returns an ``int``. + """ + + return dns.rdatatype.NONE + + def extended_rdatatype(self): + """Return a 32-bit type value, the least significant 16 bits of + which are the ordinary DNS type, and the upper 16 bits of which are + the "covered" type, if any. + + Returns an ``int``. + """ + + return self.covers() << 16 | self.rdtype + + def to_text(self, origin=None, relativize=True, **kw): + """Convert an rdata to text format. + + Returns a ``text``. + """ + + raise NotImplementedError + + def to_wire(self, file, compress=None, origin=None): + """Convert an rdata to wire format. + + Returns a ``binary``. + """ + + raise NotImplementedError + + def to_digestable(self, origin=None): + """Convert rdata to a format suitable for digesting in hashes. This + is also the DNSSEC canonical form. + + Returns a ``binary``. + """ + + f = BytesIO() + self.to_wire(f, None, origin) + return f.getvalue() + + def validate(self): + """Check that the current contents of the rdata's fields are + valid. + + If you change an rdata by assigning to its fields, + it is a good idea to call validate() when you are done making + changes. + + Raises various exceptions if there are problems. + + Returns ``None``. + """ + + dns.rdata.from_text(self.rdclass, self.rdtype, self.to_text()) + + def __repr__(self): + covers = self.covers() + if covers == dns.rdatatype.NONE: + ctext = '' + else: + ctext = '(' + dns.rdatatype.to_text(covers) + ')' + return '' + + def __str__(self): + return self.to_text() + + def _cmp(self, other): + """Compare an rdata with another rdata of the same rdtype and + rdclass. + + Return < 0 if self < other in the DNSSEC ordering, 0 if self + == other, and > 0 if self > other. + + """ + our = self.to_digestable(dns.name.root) + their = other.to_digestable(dns.name.root) + if our == their: + return 0 + elif our > their: + return 1 + else: + return -1 + + def __eq__(self, other): + if not isinstance(other, Rdata): + return False + if self.rdclass != other.rdclass or self.rdtype != other.rdtype: + return False + return self._cmp(other) == 0 + + def __ne__(self, other): + if not isinstance(other, Rdata): + return True + if self.rdclass != other.rdclass or self.rdtype != other.rdtype: + return True + return self._cmp(other) != 0 + + def __lt__(self, other): + if not isinstance(other, Rdata) or \ + self.rdclass != other.rdclass or self.rdtype != other.rdtype: + + return NotImplemented + return self._cmp(other) < 0 + + def __le__(self, other): + if not isinstance(other, Rdata) or \ + self.rdclass != other.rdclass or self.rdtype != other.rdtype: + return NotImplemented + return self._cmp(other) <= 0 + + def __ge__(self, other): + if not isinstance(other, Rdata) or \ + self.rdclass != other.rdclass or self.rdtype != other.rdtype: + return NotImplemented + return self._cmp(other) >= 0 + + def __gt__(self, other): + if not isinstance(other, Rdata) or \ + self.rdclass != other.rdclass or self.rdtype != other.rdtype: + return NotImplemented + return self._cmp(other) > 0 + + def __hash__(self): + return hash(self.to_digestable(dns.name.root)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + raise NotImplementedError + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + raise NotImplementedError + + def choose_relativity(self, origin=None, relativize=True): + """Convert any domain names in the rdata to the specified + relativization. + """ + +class GenericRdata(Rdata): + + """Generic Rdata Class + + This class is used for rdata types for which we have no better + implementation. It implements the DNS "unknown RRs" scheme. + """ + + __slots__ = ['data'] + + def __init__(self, rdclass, rdtype, data): + super(GenericRdata, self).__init__(rdclass, rdtype) + self.data = data + + def to_text(self, origin=None, relativize=True, **kw): + return r'\# %d ' % len(self.data) + _hexify(self.data) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + token = tok.get() + if not token.is_identifier() or token.value != r'\#': + raise dns.exception.SyntaxError( + r'generic rdata does not start with \#') + length = tok.get_int() + chunks = [] + while 1: + token = tok.get() + if token.is_eol_or_eof(): + break + chunks.append(token.value.encode()) + hex = b''.join(chunks) + data = binascii.unhexlify(hex) + if len(data) != length: + raise dns.exception.SyntaxError( + 'generic rdata hex data has wrong length') + return cls(rdclass, rdtype, data) + + def to_wire(self, file, compress=None, origin=None): + file.write(self.data) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + return cls(rdclass, rdtype, wire[current: current + rdlen]) + +_rdata_modules = {} +_module_prefix = 'dns.rdtypes' +_import_lock = _threading.Lock() + +def get_rdata_class(rdclass, rdtype): + + def import_module(name): + with _import_lock: + mod = __import__(name) + components = name.split('.') + for comp in components[1:]: + mod = getattr(mod, comp) + return mod + + mod = _rdata_modules.get((rdclass, rdtype)) + rdclass_text = dns.rdataclass.to_text(rdclass) + rdtype_text = dns.rdatatype.to_text(rdtype) + rdtype_text = rdtype_text.replace('-', '_') + if not mod: + mod = _rdata_modules.get((dns.rdatatype.ANY, rdtype)) + if not mod: + try: + mod = import_module('.'.join([_module_prefix, + rdclass_text, rdtype_text])) + _rdata_modules[(rdclass, rdtype)] = mod + except ImportError: + try: + mod = import_module('.'.join([_module_prefix, + 'ANY', rdtype_text])) + _rdata_modules[(dns.rdataclass.ANY, rdtype)] = mod + except ImportError: + mod = None + if mod: + cls = getattr(mod, rdtype_text) + else: + cls = GenericRdata + return cls + + +def from_text(rdclass, rdtype, tok, origin=None, relativize=True): + """Build an rdata object from text format. + + This function attempts to dynamically load a class which + implements the specified rdata class and type. If there is no + class-and-type-specific implementation, the GenericRdata class + is used. + + Once a class is chosen, its from_text() class method is called + with the parameters to this function. + + If *tok* is a ``text``, then a tokenizer is created and the string + is used as its input. + + *rdclass*, an ``int``, the rdataclass. + + *rdtype*, an ``int``, the rdatatype. + + *tok*, a ``dns.tokenizer.Tokenizer`` or a ``text``. + + *origin*, a ``dns.name.Name`` (or ``None``), the + origin to use for relative names. + + *relativize*, a ``bool``. If true, name will be relativized to + the specified origin. + + Returns an instance of the chosen Rdata subclass. + """ + + if isinstance(tok, string_types): + tok = dns.tokenizer.Tokenizer(tok) + cls = get_rdata_class(rdclass, rdtype) + if cls != GenericRdata: + # peek at first token + token = tok.get() + tok.unget(token) + if token.is_identifier() and \ + token.value == r'\#': + # + # Known type using the generic syntax. Extract the + # wire form from the generic syntax, and then run + # from_wire on it. + # + rdata = GenericRdata.from_text(rdclass, rdtype, tok, origin, + relativize) + return from_wire(rdclass, rdtype, rdata.data, 0, len(rdata.data), + origin) + return cls.from_text(rdclass, rdtype, tok, origin, relativize) + + +def from_wire(rdclass, rdtype, wire, current, rdlen, origin=None): + """Build an rdata object from wire format + + This function attempts to dynamically load a class which + implements the specified rdata class and type. If there is no + class-and-type-specific implementation, the GenericRdata class + is used. + + Once a class is chosen, its from_wire() class method is called + with the parameters to this function. + + *rdclass*, an ``int``, the rdataclass. + + *rdtype*, an ``int``, the rdatatype. + + *wire*, a ``binary``, the wire-format message. + + *current*, an ``int``, the offset in wire of the beginning of + the rdata. + + *rdlen*, an ``int``, the length of the wire-format rdata + + *origin*, a ``dns.name.Name`` (or ``None``). If not ``None``, + then names will be relativized to this origin. + + Returns an instance of the chosen Rdata subclass. + """ + + wire = dns.wiredata.maybe_wrap(wire) + cls = get_rdata_class(rdclass, rdtype) + return cls.from_wire(rdclass, rdtype, wire, current, rdlen, origin) + + +class RdatatypeExists(dns.exception.DNSException): + """DNS rdatatype already exists.""" + supp_kwargs = {'rdclass', 'rdtype'} + fmt = "The rdata type with class {rdclass} and rdtype {rdtype} " + \ + "already exists." + + +def register_type(implementation, rdtype, rdtype_text, is_singleton=False, + rdclass=dns.rdataclass.IN): + """Dynamically register a module to handle an rdatatype. + + *implementation*, a module implementing the type in the usual dnspython + way. + + *rdtype*, an ``int``, the rdatatype to register. + + *rdtype_text*, a ``text``, the textual form of the rdatatype. + + *is_singleton*, a ``bool``, indicating if the type is a singleton (i.e. + RRsets of the type can have only one member.) + + *rdclass*, the rdataclass of the type, or ``dns.rdataclass.ANY`` if + it applies to all classes. + """ + + existing_cls = get_rdata_class(rdclass, rdtype) + if existing_cls != GenericRdata: + raise RdatatypeExists(rdclass=rdclass, rdtype=rdtype) + _rdata_modules[(rdclass, rdtype)] = implementation + dns.rdatatype.register_type(rdtype, rdtype_text, is_singleton) diff --git a/env/lib/python3.7/site-packages/dns/rdataclass.py b/env/lib/python3.7/site-packages/dns/rdataclass.py new file mode 100644 index 0000000..b88aa85 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdataclass.py @@ -0,0 +1,122 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Rdata Classes.""" + +import re + +import dns.exception + +RESERVED0 = 0 +IN = 1 +CH = 3 +HS = 4 +NONE = 254 +ANY = 255 + +_by_text = { + 'RESERVED0': RESERVED0, + 'IN': IN, + 'CH': CH, + 'HS': HS, + 'NONE': NONE, + 'ANY': ANY +} + +# We construct the inverse mapping programmatically to ensure that we +# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that +# would cause the mapping not to be true inverse. + +_by_value = {y: x for x, y in _by_text.items()} + +# Now that we've built the inverse map, we can add class aliases to +# the _by_text mapping. + +_by_text.update({ + 'INTERNET': IN, + 'CHAOS': CH, + 'HESIOD': HS +}) + +_metaclasses = { + NONE: True, + ANY: True +} + +_unknown_class_pattern = re.compile('CLASS([0-9]+)$', re.I) + + +class UnknownRdataclass(dns.exception.DNSException): + """A DNS class is unknown.""" + + +def from_text(text): + """Convert text into a DNS rdata class value. + + The input text can be a defined DNS RR class mnemonic or + instance of the DNS generic class syntax. + + For example, "IN" and "CLASS1" will both result in a value of 1. + + Raises ``dns.rdatatype.UnknownRdataclass`` if the class is unknown. + + Raises ``ValueError`` if the rdata class value is not >= 0 and <= 65535. + + Returns an ``int``. + """ + + value = _by_text.get(text.upper()) + if value is None: + match = _unknown_class_pattern.match(text) + if match is None: + raise UnknownRdataclass + value = int(match.group(1)) + if value < 0 or value > 65535: + raise ValueError("class must be between >= 0 and <= 65535") + return value + + +def to_text(value): + """Convert a DNS rdata type value to text. + + If the value has a known mnemonic, it will be used, otherwise the + DNS generic class syntax will be used. + + Raises ``ValueError`` if the rdata class value is not >= 0 and <= 65535. + + Returns a ``str``. + """ + + if value < 0 or value > 65535: + raise ValueError("class must be between >= 0 and <= 65535") + text = _by_value.get(value) + if text is None: + text = 'CLASS' + repr(value) + return text + + +def is_metaclass(rdclass): + """True if the specified class is a metaclass. + + The currently defined metaclasses are ANY and NONE. + + *rdclass* is an ``int``. + """ + + if rdclass in _metaclasses: + return True + return False diff --git a/env/lib/python3.7/site-packages/dns/rdataset.py b/env/lib/python3.7/site-packages/dns/rdataset.py new file mode 100644 index 0000000..f1afe24 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdataset.py @@ -0,0 +1,347 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS rdatasets (an rdataset is a set of rdatas of a given type and class)""" + +import random +from io import StringIO +import struct + +import dns.exception +import dns.rdatatype +import dns.rdataclass +import dns.rdata +import dns.set +from ._compat import string_types + +# define SimpleSet here for backwards compatibility +SimpleSet = dns.set.Set + + +class DifferingCovers(dns.exception.DNSException): + """An attempt was made to add a DNS SIG/RRSIG whose covered type + is not the same as that of the other rdatas in the rdataset.""" + + +class IncompatibleTypes(dns.exception.DNSException): + """An attempt was made to add DNS RR data of an incompatible type.""" + + +class Rdataset(dns.set.Set): + + """A DNS rdataset.""" + + __slots__ = ['rdclass', 'rdtype', 'covers', 'ttl'] + + def __init__(self, rdclass, rdtype, covers=dns.rdatatype.NONE, ttl=0): + """Create a new rdataset of the specified class and type. + + *rdclass*, an ``int``, the rdataclass. + + *rdtype*, an ``int``, the rdatatype. + + *covers*, an ``int``, the covered rdatatype. + + *ttl*, an ``int``, the TTL. + """ + + super(Rdataset, self).__init__() + self.rdclass = rdclass + self.rdtype = rdtype + self.covers = covers + self.ttl = ttl + + def _clone(self): + obj = super(Rdataset, self)._clone() + obj.rdclass = self.rdclass + obj.rdtype = self.rdtype + obj.covers = self.covers + obj.ttl = self.ttl + return obj + + def update_ttl(self, ttl): + """Perform TTL minimization. + + Set the TTL of the rdataset to be the lesser of the set's current + TTL or the specified TTL. If the set contains no rdatas, set the TTL + to the specified TTL. + + *ttl*, an ``int``. + """ + + if len(self) == 0: + self.ttl = ttl + elif ttl < self.ttl: + self.ttl = ttl + + def add(self, rd, ttl=None): + """Add the specified rdata to the rdataset. + + If the optional *ttl* parameter is supplied, then + ``self.update_ttl(ttl)`` will be called prior to adding the rdata. + + *rd*, a ``dns.rdata.Rdata``, the rdata + + *ttl*, an ``int``, the TTL. + + Raises ``dns.rdataset.IncompatibleTypes`` if the type and class + do not match the type and class of the rdataset. + + Raises ``dns.rdataset.DifferingCovers`` if the type is a signature + type and the covered type does not match that of the rdataset. + """ + + # + # If we're adding a signature, do some special handling to + # check that the signature covers the same type as the + # other rdatas in this rdataset. If this is the first rdata + # in the set, initialize the covers field. + # + if self.rdclass != rd.rdclass or self.rdtype != rd.rdtype: + raise IncompatibleTypes + if ttl is not None: + self.update_ttl(ttl) + if self.rdtype == dns.rdatatype.RRSIG or \ + self.rdtype == dns.rdatatype.SIG: + covers = rd.covers() + if len(self) == 0 and self.covers == dns.rdatatype.NONE: + self.covers = covers + elif self.covers != covers: + raise DifferingCovers + if dns.rdatatype.is_singleton(rd.rdtype) and len(self) > 0: + self.clear() + super(Rdataset, self).add(rd) + + def union_update(self, other): + self.update_ttl(other.ttl) + super(Rdataset, self).union_update(other) + + def intersection_update(self, other): + self.update_ttl(other.ttl) + super(Rdataset, self).intersection_update(other) + + def update(self, other): + """Add all rdatas in other to self. + + *other*, a ``dns.rdataset.Rdataset``, the rdataset from which + to update. + """ + + self.update_ttl(other.ttl) + super(Rdataset, self).update(other) + + def __repr__(self): + if self.covers == 0: + ctext = '' + else: + ctext = '(' + dns.rdatatype.to_text(self.covers) + ')' + return '' + + def __str__(self): + return self.to_text() + + def __eq__(self, other): + if not isinstance(other, Rdataset): + return False + if self.rdclass != other.rdclass or \ + self.rdtype != other.rdtype or \ + self.covers != other.covers: + return False + return super(Rdataset, self).__eq__(other) + + def __ne__(self, other): + return not self.__eq__(other) + + def to_text(self, name=None, origin=None, relativize=True, + override_rdclass=None, **kw): + """Convert the rdataset into DNS master file format. + + See ``dns.name.Name.choose_relativity`` for more information + on how *origin* and *relativize* determine the way names + are emitted. + + Any additional keyword arguments are passed on to the rdata + ``to_text()`` method. + + *name*, a ``dns.name.Name``. If name is not ``None``, emit RRs with + *name* as the owner name. + + *origin*, a ``dns.name.Name`` or ``None``, the origin for relative + names. + + *relativize*, a ``bool``. If ``True``, names will be relativized + to *origin*. + """ + + if name is not None: + name = name.choose_relativity(origin, relativize) + ntext = str(name) + pad = ' ' + else: + ntext = '' + pad = '' + s = StringIO() + if override_rdclass is not None: + rdclass = override_rdclass + else: + rdclass = self.rdclass + if len(self) == 0: + # + # Empty rdatasets are used for the question section, and in + # some dynamic updates, so we don't need to print out the TTL + # (which is meaningless anyway). + # + s.write(u'{}{}{} {}\n'.format(ntext, pad, + dns.rdataclass.to_text(rdclass), + dns.rdatatype.to_text(self.rdtype))) + else: + for rd in self: + s.write(u'%s%s%d %s %s %s\n' % + (ntext, pad, self.ttl, dns.rdataclass.to_text(rdclass), + dns.rdatatype.to_text(self.rdtype), + rd.to_text(origin=origin, relativize=relativize, + **kw))) + # + # We strip off the final \n for the caller's convenience in printing + # + return s.getvalue()[:-1] + + def to_wire(self, name, file, compress=None, origin=None, + override_rdclass=None, want_shuffle=True): + """Convert the rdataset to wire format. + + *name*, a ``dns.name.Name`` is the owner name to use. + + *file* is the file where the name is emitted (typically a + BytesIO file). + + *compress*, a ``dict``, is the compression table to use. If + ``None`` (the default), names will not be compressed. + + *origin* is a ``dns.name.Name`` or ``None``. If the name is + relative and origin is not ``None``, then *origin* will be appended + to it. + + *override_rdclass*, an ``int``, is used as the class instead of the + class of the rdataset. This is useful when rendering rdatasets + associated with dynamic updates. + + *want_shuffle*, a ``bool``. If ``True``, then the order of the + Rdatas within the Rdataset will be shuffled before rendering. + + Returns an ``int``, the number of records emitted. + """ + + if override_rdclass is not None: + rdclass = override_rdclass + want_shuffle = False + else: + rdclass = self.rdclass + file.seek(0, 2) + if len(self) == 0: + name.to_wire(file, compress, origin) + stuff = struct.pack("!HHIH", self.rdtype, rdclass, 0, 0) + file.write(stuff) + return 1 + else: + if want_shuffle: + l = list(self) + random.shuffle(l) + else: + l = self + for rd in l: + name.to_wire(file, compress, origin) + stuff = struct.pack("!HHIH", self.rdtype, rdclass, + self.ttl, 0) + file.write(stuff) + start = file.tell() + rd.to_wire(file, compress, origin) + end = file.tell() + assert end - start < 65536 + file.seek(start - 2) + stuff = struct.pack("!H", end - start) + file.write(stuff) + file.seek(0, 2) + return len(self) + + def match(self, rdclass, rdtype, covers): + """Returns ``True`` if this rdataset matches the specified class, + type, and covers. + """ + if self.rdclass == rdclass and \ + self.rdtype == rdtype and \ + self.covers == covers: + return True + return False + + +def from_text_list(rdclass, rdtype, ttl, text_rdatas): + """Create an rdataset with the specified class, type, and TTL, and with + the specified list of rdatas in text format. + + Returns a ``dns.rdataset.Rdataset`` object. + """ + + if isinstance(rdclass, string_types): + rdclass = dns.rdataclass.from_text(rdclass) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + r = Rdataset(rdclass, rdtype) + r.update_ttl(ttl) + for t in text_rdatas: + rd = dns.rdata.from_text(r.rdclass, r.rdtype, t) + r.add(rd) + return r + + +def from_text(rdclass, rdtype, ttl, *text_rdatas): + """Create an rdataset with the specified class, type, and TTL, and with + the specified rdatas in text format. + + Returns a ``dns.rdataset.Rdataset`` object. + """ + + return from_text_list(rdclass, rdtype, ttl, text_rdatas) + + +def from_rdata_list(ttl, rdatas): + """Create an rdataset with the specified TTL, and with + the specified list of rdata objects. + + Returns a ``dns.rdataset.Rdataset`` object. + """ + + if len(rdatas) == 0: + raise ValueError("rdata list must not be empty") + r = None + for rd in rdatas: + if r is None: + r = Rdataset(rd.rdclass, rd.rdtype) + r.update_ttl(ttl) + r.add(rd) + return r + + +def from_rdata(ttl, *rdatas): + """Create an rdataset with the specified TTL, and with + the specified rdata objects. + + Returns a ``dns.rdataset.Rdataset`` object. + """ + + return from_rdata_list(ttl, rdatas) diff --git a/env/lib/python3.7/site-packages/dns/rdatatype.py b/env/lib/python3.7/site-packages/dns/rdatatype.py new file mode 100644 index 0000000..b247bc9 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdatatype.py @@ -0,0 +1,287 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Rdata Types.""" + +import re + +import dns.exception + +NONE = 0 +A = 1 +NS = 2 +MD = 3 +MF = 4 +CNAME = 5 +SOA = 6 +MB = 7 +MG = 8 +MR = 9 +NULL = 10 +WKS = 11 +PTR = 12 +HINFO = 13 +MINFO = 14 +MX = 15 +TXT = 16 +RP = 17 +AFSDB = 18 +X25 = 19 +ISDN = 20 +RT = 21 +NSAP = 22 +NSAP_PTR = 23 +SIG = 24 +KEY = 25 +PX = 26 +GPOS = 27 +AAAA = 28 +LOC = 29 +NXT = 30 +SRV = 33 +NAPTR = 35 +KX = 36 +CERT = 37 +A6 = 38 +DNAME = 39 +OPT = 41 +APL = 42 +DS = 43 +SSHFP = 44 +IPSECKEY = 45 +RRSIG = 46 +NSEC = 47 +DNSKEY = 48 +DHCID = 49 +NSEC3 = 50 +NSEC3PARAM = 51 +TLSA = 52 +HIP = 55 +CDS = 59 +CDNSKEY = 60 +OPENPGPKEY = 61 +CSYNC = 62 +SPF = 99 +UNSPEC = 103 +EUI48 = 108 +EUI64 = 109 +TKEY = 249 +TSIG = 250 +IXFR = 251 +AXFR = 252 +MAILB = 253 +MAILA = 254 +ANY = 255 +URI = 256 +CAA = 257 +AVC = 258 +TA = 32768 +DLV = 32769 + +_by_text = { + 'NONE': NONE, + 'A': A, + 'NS': NS, + 'MD': MD, + 'MF': MF, + 'CNAME': CNAME, + 'SOA': SOA, + 'MB': MB, + 'MG': MG, + 'MR': MR, + 'NULL': NULL, + 'WKS': WKS, + 'PTR': PTR, + 'HINFO': HINFO, + 'MINFO': MINFO, + 'MX': MX, + 'TXT': TXT, + 'RP': RP, + 'AFSDB': AFSDB, + 'X25': X25, + 'ISDN': ISDN, + 'RT': RT, + 'NSAP': NSAP, + 'NSAP-PTR': NSAP_PTR, + 'SIG': SIG, + 'KEY': KEY, + 'PX': PX, + 'GPOS': GPOS, + 'AAAA': AAAA, + 'LOC': LOC, + 'NXT': NXT, + 'SRV': SRV, + 'NAPTR': NAPTR, + 'KX': KX, + 'CERT': CERT, + 'A6': A6, + 'DNAME': DNAME, + 'OPT': OPT, + 'APL': APL, + 'DS': DS, + 'SSHFP': SSHFP, + 'IPSECKEY': IPSECKEY, + 'RRSIG': RRSIG, + 'NSEC': NSEC, + 'DNSKEY': DNSKEY, + 'DHCID': DHCID, + 'NSEC3': NSEC3, + 'NSEC3PARAM': NSEC3PARAM, + 'TLSA': TLSA, + 'HIP': HIP, + 'CDS': CDS, + 'CDNSKEY': CDNSKEY, + 'OPENPGPKEY': OPENPGPKEY, + 'CSYNC': CSYNC, + 'SPF': SPF, + 'UNSPEC': UNSPEC, + 'EUI48': EUI48, + 'EUI64': EUI64, + 'TKEY': TKEY, + 'TSIG': TSIG, + 'IXFR': IXFR, + 'AXFR': AXFR, + 'MAILB': MAILB, + 'MAILA': MAILA, + 'ANY': ANY, + 'URI': URI, + 'CAA': CAA, + 'AVC': AVC, + 'TA': TA, + 'DLV': DLV, +} + +# We construct the inverse mapping programmatically to ensure that we +# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that +# would cause the mapping not to be true inverse. + +_by_value = {y: x for x, y in _by_text.items()} + +_metatypes = { + OPT: True +} + +_singletons = { + SOA: True, + NXT: True, + DNAME: True, + NSEC: True, + CNAME: True, +} + +_unknown_type_pattern = re.compile('TYPE([0-9]+)$', re.I) + + +class UnknownRdatatype(dns.exception.DNSException): + """DNS resource record type is unknown.""" + + +def from_text(text): + """Convert text into a DNS rdata type value. + + The input text can be a defined DNS RR type mnemonic or + instance of the DNS generic type syntax. + + For example, "NS" and "TYPE2" will both result in a value of 2. + + Raises ``dns.rdatatype.UnknownRdatatype`` if the type is unknown. + + Raises ``ValueError`` if the rdata type value is not >= 0 and <= 65535. + + Returns an ``int``. + """ + + value = _by_text.get(text.upper()) + if value is None: + match = _unknown_type_pattern.match(text) + if match is None: + raise UnknownRdatatype + value = int(match.group(1)) + if value < 0 or value > 65535: + raise ValueError("type must be between >= 0 and <= 65535") + return value + + +def to_text(value): + """Convert a DNS rdata type value to text. + + If the value has a known mnemonic, it will be used, otherwise the + DNS generic type syntax will be used. + + Raises ``ValueError`` if the rdata type value is not >= 0 and <= 65535. + + Returns a ``str``. + """ + + if value < 0 or value > 65535: + raise ValueError("type must be between >= 0 and <= 65535") + text = _by_value.get(value) + if text is None: + text = 'TYPE' + repr(value) + return text + + +def is_metatype(rdtype): + """True if the specified type is a metatype. + + *rdtype* is an ``int``. + + The currently defined metatypes are TKEY, TSIG, IXFR, AXFR, MAILA, + MAILB, ANY, and OPT. + + Returns a ``bool``. + """ + + if rdtype >= TKEY and rdtype <= ANY or rdtype in _metatypes: + return True + return False + + +def is_singleton(rdtype): + """Is the specified type a singleton type? + + Singleton types can only have a single rdata in an rdataset, or a single + RR in an RRset. + + The currently defined singleton types are CNAME, DNAME, NSEC, NXT, and + SOA. + + *rdtype* is an ``int``. + + Returns a ``bool``. + """ + + if rdtype in _singletons: + return True + return False + + +def register_type(rdtype, rdtype_text, is_singleton=False): # pylint: disable=redefined-outer-name + """Dynamically register an rdatatype. + + *rdtype*, an ``int``, the rdatatype to register. + + *rdtype_text*, a ``text``, the textual form of the rdatatype. + + *is_singleton*, a ``bool``, indicating if the type is a singleton (i.e. + RRsets of the type can have only one member.) + """ + + _by_text[rdtype_text] = rdtype + _by_value[rdtype] = rdtype_text + if is_singleton: + _singletons[rdtype] = True diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/AFSDB.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/AFSDB.py new file mode 100644 index 0000000..c6a700c --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/AFSDB.py @@ -0,0 +1,55 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.mxbase + + +class AFSDB(dns.rdtypes.mxbase.UncompressedDowncasingMX): + + """AFSDB record + + @ivar subtype: the subtype value + @type subtype: int + @ivar hostname: the hostname name + @type hostname: dns.name.Name object""" + + # Use the property mechanism to make "subtype" an alias for the + # "preference" attribute, and "hostname" an alias for the "exchange" + # attribute. + # + # This lets us inherit the UncompressedMX implementation but lets + # the caller use appropriate attribute names for the rdata type. + # + # We probably lose some performance vs. a cut-and-paste + # implementation, but this way we don't copy code, and that's + # good. + + def get_subtype(self): + return self.preference + + def set_subtype(self, subtype): + self.preference = subtype + + subtype = property(get_subtype, set_subtype) + + def get_hostname(self): + return self.exchange + + def set_hostname(self, hostname): + self.exchange = hostname + + hostname = property(get_hostname, set_hostname) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/AVC.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/AVC.py new file mode 100644 index 0000000..7f340b3 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/AVC.py @@ -0,0 +1,25 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2016 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.txtbase + + +class AVC(dns.rdtypes.txtbase.TXTBase): + + """AVC record + + @see: U{http://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template}""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CAA.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CAA.py new file mode 100644 index 0000000..0acf201 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CAA.py @@ -0,0 +1,75 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.tokenizer + + +class CAA(dns.rdata.Rdata): + + """CAA (Certification Authority Authorization) record + + @ivar flags: the flags + @type flags: int + @ivar tag: the tag + @type tag: string + @ivar value: the value + @type value: string + @see: RFC 6844""" + + __slots__ = ['flags', 'tag', 'value'] + + def __init__(self, rdclass, rdtype, flags, tag, value): + super(CAA, self).__init__(rdclass, rdtype) + self.flags = flags + self.tag = tag + self.value = value + + def to_text(self, origin=None, relativize=True, **kw): + return '%u %s "%s"' % (self.flags, + dns.rdata._escapify(self.tag), + dns.rdata._escapify(self.value)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + flags = tok.get_uint8() + tag = tok.get_string().encode() + if len(tag) > 255: + raise dns.exception.SyntaxError("tag too long") + if not tag.isalnum(): + raise dns.exception.SyntaxError("tag is not alphanumeric") + value = tok.get_string().encode() + return cls(rdclass, rdtype, flags, tag, value) + + def to_wire(self, file, compress=None, origin=None): + file.write(struct.pack('!B', self.flags)) + l = len(self.tag) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.tag) + file.write(self.value) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (flags, l) = struct.unpack('!BB', wire[current: current + 2]) + current += 2 + tag = wire[current: current + l] + value = wire[current + l:current + rdlen - 2] + return cls(rdclass, rdtype, flags, tag, value) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CDNSKEY.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CDNSKEY.py new file mode 100644 index 0000000..653ae1b --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CDNSKEY.py @@ -0,0 +1,27 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.dnskeybase +from dns.rdtypes.dnskeybase import flags_to_text_set, flags_from_text_set + + +__all__ = ['flags_to_text_set', 'flags_from_text_set'] + + +class CDNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase): + + """CDNSKEY record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CDS.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CDS.py new file mode 100644 index 0000000..a63041d --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CDS.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.dsbase + + +class CDS(dns.rdtypes.dsbase.DSBase): + + """CDS record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CERT.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CERT.py new file mode 100644 index 0000000..eea27b5 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CERT.py @@ -0,0 +1,123 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct +import base64 + +import dns.exception +import dns.dnssec +import dns.rdata +import dns.tokenizer + +_ctype_by_value = { + 1: 'PKIX', + 2: 'SPKI', + 3: 'PGP', + 253: 'URI', + 254: 'OID', +} + +_ctype_by_name = { + 'PKIX': 1, + 'SPKI': 2, + 'PGP': 3, + 'URI': 253, + 'OID': 254, +} + + +def _ctype_from_text(what): + v = _ctype_by_name.get(what) + if v is not None: + return v + return int(what) + + +def _ctype_to_text(what): + v = _ctype_by_value.get(what) + if v is not None: + return v + return str(what) + + +class CERT(dns.rdata.Rdata): + + """CERT record + + @ivar certificate_type: certificate type + @type certificate_type: int + @ivar key_tag: key tag + @type key_tag: int + @ivar algorithm: algorithm + @type algorithm: int + @ivar certificate: the certificate or CRL + @type certificate: string + @see: RFC 2538""" + + __slots__ = ['certificate_type', 'key_tag', 'algorithm', 'certificate'] + + def __init__(self, rdclass, rdtype, certificate_type, key_tag, algorithm, + certificate): + super(CERT, self).__init__(rdclass, rdtype) + self.certificate_type = certificate_type + self.key_tag = key_tag + self.algorithm = algorithm + self.certificate = certificate + + def to_text(self, origin=None, relativize=True, **kw): + certificate_type = _ctype_to_text(self.certificate_type) + return "%s %d %s %s" % (certificate_type, self.key_tag, + dns.dnssec.algorithm_to_text(self.algorithm), + dns.rdata._base64ify(self.certificate)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + certificate_type = _ctype_from_text(tok.get_string()) + key_tag = tok.get_uint16() + algorithm = dns.dnssec.algorithm_from_text(tok.get_string()) + if algorithm < 0 or algorithm > 255: + raise dns.exception.SyntaxError("bad algorithm type") + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + certificate = base64.b64decode(b64) + return cls(rdclass, rdtype, certificate_type, key_tag, + algorithm, certificate) + + def to_wire(self, file, compress=None, origin=None): + prefix = struct.pack("!HHB", self.certificate_type, self.key_tag, + self.algorithm) + file.write(prefix) + file.write(self.certificate) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + prefix = wire[current: current + 5].unwrap() + current += 5 + rdlen -= 5 + if rdlen < 0: + raise dns.exception.FormError + (certificate_type, key_tag, algorithm) = struct.unpack("!HHB", prefix) + certificate = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, certificate_type, key_tag, algorithm, + certificate) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CNAME.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CNAME.py new file mode 100644 index 0000000..11d42aa --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CNAME.py @@ -0,0 +1,27 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.nsbase + + +class CNAME(dns.rdtypes.nsbase.NSBase): + + """CNAME record + + Note: although CNAME is officially a singleton type, dnspython allows + non-singleton CNAME rdatasets because such sets have been commonly + used by BIND and other nameservers for load balancing.""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CSYNC.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CSYNC.py new file mode 100644 index 0000000..06292fb --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/CSYNC.py @@ -0,0 +1,126 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2004-2007, 2009-2011, 2016 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.rdatatype +import dns.name +from dns._compat import xrange + +class CSYNC(dns.rdata.Rdata): + + """CSYNC record + + @ivar serial: the SOA serial number + @type serial: int + @ivar flags: the CSYNC flags + @type flags: int + @ivar windows: the windowed bitmap list + @type windows: list of (window number, string) tuples""" + + __slots__ = ['serial', 'flags', 'windows'] + + def __init__(self, rdclass, rdtype, serial, flags, windows): + super(CSYNC, self).__init__(rdclass, rdtype) + self.serial = serial + self.flags = flags + self.windows = windows + + def to_text(self, origin=None, relativize=True, **kw): + text = '' + for (window, bitmap) in self.windows: + bits = [] + for i in xrange(0, len(bitmap)): + byte = bitmap[i] + for j in xrange(0, 8): + if byte & (0x80 >> j): + bits.append(dns.rdatatype.to_text(window * 256 + + i * 8 + j)) + text += (' ' + ' '.join(bits)) + return '%d %d%s' % (self.serial, self.flags, text) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + serial = tok.get_uint32() + flags = tok.get_uint16() + rdtypes = [] + while 1: + token = tok.get().unescape() + if token.is_eol_or_eof(): + break + nrdtype = dns.rdatatype.from_text(token.value) + if nrdtype == 0: + raise dns.exception.SyntaxError("CSYNC with bit 0") + if nrdtype > 65535: + raise dns.exception.SyntaxError("CSYNC with bit > 65535") + rdtypes.append(nrdtype) + rdtypes.sort() + window = 0 + octets = 0 + prior_rdtype = 0 + bitmap = bytearray(b'\0' * 32) + windows = [] + for nrdtype in rdtypes: + if nrdtype == prior_rdtype: + continue + prior_rdtype = nrdtype + new_window = nrdtype // 256 + if new_window != window: + windows.append((window, bitmap[0:octets])) + bitmap = bytearray(b'\0' * 32) + window = new_window + offset = nrdtype % 256 + byte = offset // 8 + bit = offset % 8 + octets = byte + 1 + bitmap[byte] = bitmap[byte] | (0x80 >> bit) + + windows.append((window, bitmap[0:octets])) + return cls(rdclass, rdtype, serial, flags, windows) + + def to_wire(self, file, compress=None, origin=None): + file.write(struct.pack('!IH', self.serial, self.flags)) + for (window, bitmap) in self.windows: + file.write(struct.pack('!BB', window, len(bitmap))) + file.write(bitmap) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + if rdlen < 6: + raise dns.exception.FormError("CSYNC too short") + (serial, flags) = struct.unpack("!IH", wire[current: current + 6]) + current += 6 + rdlen -= 6 + windows = [] + while rdlen > 0: + if rdlen < 3: + raise dns.exception.FormError("CSYNC too short") + window = wire[current] + octets = wire[current + 1] + if octets == 0 or octets > 32: + raise dns.exception.FormError("bad CSYNC octets") + current += 2 + rdlen -= 2 + if rdlen < octets: + raise dns.exception.FormError("bad CSYNC bitmap length") + bitmap = bytearray(wire[current: current + octets].unwrap()) + current += octets + rdlen -= octets + windows.append((window, bitmap)) + return cls(rdclass, rdtype, serial, flags, windows) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DLV.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DLV.py new file mode 100644 index 0000000..1635212 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DLV.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.dsbase + + +class DLV(dns.rdtypes.dsbase.DSBase): + + """DLV record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DNAME.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DNAME.py new file mode 100644 index 0000000..2499283 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DNAME.py @@ -0,0 +1,26 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.nsbase + + +class DNAME(dns.rdtypes.nsbase.UncompressedNS): + + """DNAME record""" + + def to_digestable(self, origin=None): + return self.target.to_digestable(origin) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DNSKEY.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DNSKEY.py new file mode 100644 index 0000000..e36f7bc --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DNSKEY.py @@ -0,0 +1,27 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.dnskeybase +from dns.rdtypes.dnskeybase import flags_to_text_set, flags_from_text_set + + +__all__ = ['flags_to_text_set', 'flags_from_text_set'] + + +class DNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase): + + """DNSKEY record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DS.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DS.py new file mode 100644 index 0000000..7d457b2 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/DS.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.dsbase + + +class DS(dns.rdtypes.dsbase.DSBase): + + """DS record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/EUI48.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/EUI48.py new file mode 100644 index 0000000..aa260e2 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/EUI48.py @@ -0,0 +1,29 @@ +# Copyright (C) 2015 Red Hat, Inc. +# Author: Petr Spacek +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.euibase + + +class EUI48(dns.rdtypes.euibase.EUIBase): + + """EUI48 record + + @ivar fingerprint: 48-bit Extended Unique Identifier (EUI-48) + @type fingerprint: string + @see: rfc7043.txt""" + + byte_len = 6 # 0123456789ab (in hex) + text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/EUI64.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/EUI64.py new file mode 100644 index 0000000..5eba350 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/EUI64.py @@ -0,0 +1,29 @@ +# Copyright (C) 2015 Red Hat, Inc. +# Author: Petr Spacek +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.euibase + + +class EUI64(dns.rdtypes.euibase.EUIBase): + + """EUI64 record + + @ivar fingerprint: 64-bit Extended Unique Identifier (EUI-64) + @type fingerprint: string + @see: rfc7043.txt""" + + byte_len = 8 # 0123456789abcdef (in hex) + text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab-cd-ef diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/GPOS.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/GPOS.py new file mode 100644 index 0000000..422822f --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/GPOS.py @@ -0,0 +1,162 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.tokenizer +from dns._compat import long, text_type + + +def _validate_float_string(what): + if what[0] == b'-'[0] or what[0] == b'+'[0]: + what = what[1:] + if what.isdigit(): + return + (left, right) = what.split(b'.') + if left == b'' and right == b'': + raise dns.exception.FormError + if not left == b'' and not left.decode().isdigit(): + raise dns.exception.FormError + if not right == b'' and not right.decode().isdigit(): + raise dns.exception.FormError + + +def _sanitize(value): + if isinstance(value, text_type): + return value.encode() + return value + + +class GPOS(dns.rdata.Rdata): + + """GPOS record + + @ivar latitude: latitude + @type latitude: string + @ivar longitude: longitude + @type longitude: string + @ivar altitude: altitude + @type altitude: string + @see: RFC 1712""" + + __slots__ = ['latitude', 'longitude', 'altitude'] + + def __init__(self, rdclass, rdtype, latitude, longitude, altitude): + super(GPOS, self).__init__(rdclass, rdtype) + if isinstance(latitude, float) or \ + isinstance(latitude, int) or \ + isinstance(latitude, long): + latitude = str(latitude) + if isinstance(longitude, float) or \ + isinstance(longitude, int) or \ + isinstance(longitude, long): + longitude = str(longitude) + if isinstance(altitude, float) or \ + isinstance(altitude, int) or \ + isinstance(altitude, long): + altitude = str(altitude) + latitude = _sanitize(latitude) + longitude = _sanitize(longitude) + altitude = _sanitize(altitude) + _validate_float_string(latitude) + _validate_float_string(longitude) + _validate_float_string(altitude) + self.latitude = latitude + self.longitude = longitude + self.altitude = altitude + + def to_text(self, origin=None, relativize=True, **kw): + return '{} {} {}'.format(self.latitude.decode(), + self.longitude.decode(), + self.altitude.decode()) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + latitude = tok.get_string() + longitude = tok.get_string() + altitude = tok.get_string() + tok.get_eol() + return cls(rdclass, rdtype, latitude, longitude, altitude) + + def to_wire(self, file, compress=None, origin=None): + l = len(self.latitude) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.latitude) + l = len(self.longitude) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.longitude) + l = len(self.altitude) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.altitude) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + l = wire[current] + current += 1 + rdlen -= 1 + if l > rdlen: + raise dns.exception.FormError + latitude = wire[current: current + l].unwrap() + current += l + rdlen -= l + l = wire[current] + current += 1 + rdlen -= 1 + if l > rdlen: + raise dns.exception.FormError + longitude = wire[current: current + l].unwrap() + current += l + rdlen -= l + l = wire[current] + current += 1 + rdlen -= 1 + if l != rdlen: + raise dns.exception.FormError + altitude = wire[current: current + l].unwrap() + return cls(rdclass, rdtype, latitude, longitude, altitude) + + def _get_float_latitude(self): + return float(self.latitude) + + def _set_float_latitude(self, value): + self.latitude = str(value) + + float_latitude = property(_get_float_latitude, _set_float_latitude, + doc="latitude as a floating point value") + + def _get_float_longitude(self): + return float(self.longitude) + + def _set_float_longitude(self, value): + self.longitude = str(value) + + float_longitude = property(_get_float_longitude, _set_float_longitude, + doc="longitude as a floating point value") + + def _get_float_altitude(self): + return float(self.altitude) + + def _set_float_altitude(self, value): + self.altitude = str(value) + + float_altitude = property(_get_float_altitude, _set_float_altitude, + doc="altitude as a floating point value") diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/HINFO.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/HINFO.py new file mode 100644 index 0000000..e4e0b34 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/HINFO.py @@ -0,0 +1,86 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.tokenizer +from dns._compat import text_type + + +class HINFO(dns.rdata.Rdata): + + """HINFO record + + @ivar cpu: the CPU type + @type cpu: string + @ivar os: the OS type + @type os: string + @see: RFC 1035""" + + __slots__ = ['cpu', 'os'] + + def __init__(self, rdclass, rdtype, cpu, os): + super(HINFO, self).__init__(rdclass, rdtype) + if isinstance(cpu, text_type): + self.cpu = cpu.encode() + else: + self.cpu = cpu + if isinstance(os, text_type): + self.os = os.encode() + else: + self.os = os + + def to_text(self, origin=None, relativize=True, **kw): + return '"{}" "{}"'.format(dns.rdata._escapify(self.cpu), + dns.rdata._escapify(self.os)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + cpu = tok.get_string() + os = tok.get_string() + tok.get_eol() + return cls(rdclass, rdtype, cpu, os) + + def to_wire(self, file, compress=None, origin=None): + l = len(self.cpu) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.cpu) + l = len(self.os) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.os) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + l = wire[current] + current += 1 + rdlen -= 1 + if l > rdlen: + raise dns.exception.FormError + cpu = wire[current:current + l].unwrap() + current += l + rdlen -= l + l = wire[current] + current += 1 + rdlen -= 1 + if l != rdlen: + raise dns.exception.FormError + os = wire[current: current + l].unwrap() + return cls(rdclass, rdtype, cpu, os) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/HIP.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/HIP.py new file mode 100644 index 0000000..7c876b2 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/HIP.py @@ -0,0 +1,115 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2010, 2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct +import base64 +import binascii + +import dns.exception +import dns.rdata +import dns.rdatatype + + +class HIP(dns.rdata.Rdata): + + """HIP record + + @ivar hit: the host identity tag + @type hit: string + @ivar algorithm: the public key cryptographic algorithm + @type algorithm: int + @ivar key: the public key + @type key: string + @ivar servers: the rendezvous servers + @type servers: list of dns.name.Name objects + @see: RFC 5205""" + + __slots__ = ['hit', 'algorithm', 'key', 'servers'] + + def __init__(self, rdclass, rdtype, hit, algorithm, key, servers): + super(HIP, self).__init__(rdclass, rdtype) + self.hit = hit + self.algorithm = algorithm + self.key = key + self.servers = servers + + def to_text(self, origin=None, relativize=True, **kw): + hit = binascii.hexlify(self.hit).decode() + key = base64.b64encode(self.key).replace(b'\n', b'').decode() + text = u'' + servers = [] + for server in self.servers: + servers.append(server.choose_relativity(origin, relativize)) + if len(servers) > 0: + text += (u' ' + u' '.join((x.to_unicode() for x in servers))) + return u'%u %s %s%s' % (self.algorithm, hit, key, text) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + algorithm = tok.get_uint8() + hit = binascii.unhexlify(tok.get_string().encode()) + if len(hit) > 255: + raise dns.exception.SyntaxError("HIT too long") + key = base64.b64decode(tok.get_string().encode()) + servers = [] + while 1: + token = tok.get() + if token.is_eol_or_eof(): + break + server = dns.name.from_text(token.value, origin) + server.choose_relativity(origin, relativize) + servers.append(server) + return cls(rdclass, rdtype, hit, algorithm, key, servers) + + def to_wire(self, file, compress=None, origin=None): + lh = len(self.hit) + lk = len(self.key) + file.write(struct.pack("!BBH", lh, self.algorithm, lk)) + file.write(self.hit) + file.write(self.key) + for server in self.servers: + server.to_wire(file, None, origin) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (lh, algorithm, lk) = struct.unpack('!BBH', + wire[current: current + 4]) + current += 4 + rdlen -= 4 + hit = wire[current: current + lh].unwrap() + current += lh + rdlen -= lh + key = wire[current: current + lk].unwrap() + current += lk + rdlen -= lk + servers = [] + while rdlen > 0: + (server, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + current += cused + rdlen -= cused + if origin is not None: + server = server.relativize(origin) + servers.append(server) + return cls(rdclass, rdtype, hit, algorithm, key, servers) + + def choose_relativity(self, origin=None, relativize=True): + servers = [] + for server in self.servers: + server = server.choose_relativity(origin, relativize) + servers.append(server) + self.servers = servers diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/ISDN.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/ISDN.py new file mode 100644 index 0000000..f5f5f8b --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/ISDN.py @@ -0,0 +1,99 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.tokenizer +from dns._compat import text_type + + +class ISDN(dns.rdata.Rdata): + + """ISDN record + + @ivar address: the ISDN address + @type address: string + @ivar subaddress: the ISDN subaddress (or '' if not present) + @type subaddress: string + @see: RFC 1183""" + + __slots__ = ['address', 'subaddress'] + + def __init__(self, rdclass, rdtype, address, subaddress): + super(ISDN, self).__init__(rdclass, rdtype) + if isinstance(address, text_type): + self.address = address.encode() + else: + self.address = address + if isinstance(address, text_type): + self.subaddress = subaddress.encode() + else: + self.subaddress = subaddress + + def to_text(self, origin=None, relativize=True, **kw): + if self.subaddress: + return '"{}" "{}"'.format(dns.rdata._escapify(self.address), + dns.rdata._escapify(self.subaddress)) + else: + return '"%s"' % dns.rdata._escapify(self.address) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + address = tok.get_string() + t = tok.get() + if not t.is_eol_or_eof(): + tok.unget(t) + subaddress = tok.get_string() + else: + tok.unget(t) + subaddress = '' + tok.get_eol() + return cls(rdclass, rdtype, address, subaddress) + + def to_wire(self, file, compress=None, origin=None): + l = len(self.address) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.address) + l = len(self.subaddress) + if l > 0: + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.subaddress) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + l = wire[current] + current += 1 + rdlen -= 1 + if l > rdlen: + raise dns.exception.FormError + address = wire[current: current + l].unwrap() + current += l + rdlen -= l + if rdlen > 0: + l = wire[current] + current += 1 + rdlen -= 1 + if l != rdlen: + raise dns.exception.FormError + subaddress = wire[current: current + l].unwrap() + else: + subaddress = '' + return cls(rdclass, rdtype, address, subaddress) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/LOC.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/LOC.py new file mode 100644 index 0000000..da9bb03 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/LOC.py @@ -0,0 +1,327 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import division + +import struct + +import dns.exception +import dns.rdata +from dns._compat import long, xrange, round_py2_compat + + +_pows = tuple(long(10**i) for i in range(0, 11)) + +# default values are in centimeters +_default_size = 100.0 +_default_hprec = 1000000.0 +_default_vprec = 1000.0 + + +def _exponent_of(what, desc): + if what == 0: + return 0 + exp = None + for i in xrange(len(_pows)): + if what // _pows[i] == long(0): + exp = i - 1 + break + if exp is None or exp < 0: + raise dns.exception.SyntaxError("%s value out of bounds" % desc) + return exp + + +def _float_to_tuple(what): + if what < 0: + sign = -1 + what *= -1 + else: + sign = 1 + what = round_py2_compat(what * 3600000) + degrees = int(what // 3600000) + what -= degrees * 3600000 + minutes = int(what // 60000) + what -= minutes * 60000 + seconds = int(what // 1000) + what -= int(seconds * 1000) + what = int(what) + return (degrees, minutes, seconds, what, sign) + + +def _tuple_to_float(what): + value = float(what[0]) + value += float(what[1]) / 60.0 + value += float(what[2]) / 3600.0 + value += float(what[3]) / 3600000.0 + return float(what[4]) * value + + +def _encode_size(what, desc): + what = long(what) + exponent = _exponent_of(what, desc) & 0xF + base = what // pow(10, exponent) & 0xF + return base * 16 + exponent + + +def _decode_size(what, desc): + exponent = what & 0x0F + if exponent > 9: + raise dns.exception.SyntaxError("bad %s exponent" % desc) + base = (what & 0xF0) >> 4 + if base > 9: + raise dns.exception.SyntaxError("bad %s base" % desc) + return long(base) * pow(10, exponent) + + +class LOC(dns.rdata.Rdata): + + """LOC record + + @ivar latitude: latitude + @type latitude: (int, int, int, int, sign) tuple specifying the degrees, minutes, + seconds, milliseconds, and sign of the coordinate. + @ivar longitude: longitude + @type longitude: (int, int, int, int, sign) tuple specifying the degrees, + minutes, seconds, milliseconds, and sign of the coordinate. + @ivar altitude: altitude + @type altitude: float + @ivar size: size of the sphere + @type size: float + @ivar horizontal_precision: horizontal precision + @type horizontal_precision: float + @ivar vertical_precision: vertical precision + @type vertical_precision: float + @see: RFC 1876""" + + __slots__ = ['latitude', 'longitude', 'altitude', 'size', + 'horizontal_precision', 'vertical_precision'] + + def __init__(self, rdclass, rdtype, latitude, longitude, altitude, + size=_default_size, hprec=_default_hprec, + vprec=_default_vprec): + """Initialize a LOC record instance. + + The parameters I{latitude} and I{longitude} may be either a 4-tuple + of integers specifying (degrees, minutes, seconds, milliseconds), + or they may be floating point values specifying the number of + degrees. The other parameters are floats. Size, horizontal precision, + and vertical precision are specified in centimeters.""" + + super(LOC, self).__init__(rdclass, rdtype) + if isinstance(latitude, int) or isinstance(latitude, long): + latitude = float(latitude) + if isinstance(latitude, float): + latitude = _float_to_tuple(latitude) + self.latitude = latitude + if isinstance(longitude, int) or isinstance(longitude, long): + longitude = float(longitude) + if isinstance(longitude, float): + longitude = _float_to_tuple(longitude) + self.longitude = longitude + self.altitude = float(altitude) + self.size = float(size) + self.horizontal_precision = float(hprec) + self.vertical_precision = float(vprec) + + def to_text(self, origin=None, relativize=True, **kw): + if self.latitude[4] > 0: + lat_hemisphere = 'N' + else: + lat_hemisphere = 'S' + if self.longitude[4] > 0: + long_hemisphere = 'E' + else: + long_hemisphere = 'W' + text = "%d %d %d.%03d %s %d %d %d.%03d %s %0.2fm" % ( + self.latitude[0], self.latitude[1], + self.latitude[2], self.latitude[3], lat_hemisphere, + self.longitude[0], self.longitude[1], self.longitude[2], + self.longitude[3], long_hemisphere, + self.altitude / 100.0 + ) + + # do not print default values + if self.size != _default_size or \ + self.horizontal_precision != _default_hprec or \ + self.vertical_precision != _default_vprec: + text += " {:0.2f}m {:0.2f}m {:0.2f}m".format( + self.size / 100.0, self.horizontal_precision / 100.0, + self.vertical_precision / 100.0 + ) + return text + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + latitude = [0, 0, 0, 0, 1] + longitude = [0, 0, 0, 0, 1] + size = _default_size + hprec = _default_hprec + vprec = _default_vprec + + latitude[0] = tok.get_int() + t = tok.get_string() + if t.isdigit(): + latitude[1] = int(t) + t = tok.get_string() + if '.' in t: + (seconds, milliseconds) = t.split('.') + if not seconds.isdigit(): + raise dns.exception.SyntaxError( + 'bad latitude seconds value') + latitude[2] = int(seconds) + if latitude[2] >= 60: + raise dns.exception.SyntaxError('latitude seconds >= 60') + l = len(milliseconds) + if l == 0 or l > 3 or not milliseconds.isdigit(): + raise dns.exception.SyntaxError( + 'bad latitude milliseconds value') + if l == 1: + m = 100 + elif l == 2: + m = 10 + else: + m = 1 + latitude[3] = m * int(milliseconds) + t = tok.get_string() + elif t.isdigit(): + latitude[2] = int(t) + t = tok.get_string() + if t == 'S': + latitude[4] = -1 + elif t != 'N': + raise dns.exception.SyntaxError('bad latitude hemisphere value') + + longitude[0] = tok.get_int() + t = tok.get_string() + if t.isdigit(): + longitude[1] = int(t) + t = tok.get_string() + if '.' in t: + (seconds, milliseconds) = t.split('.') + if not seconds.isdigit(): + raise dns.exception.SyntaxError( + 'bad longitude seconds value') + longitude[2] = int(seconds) + if longitude[2] >= 60: + raise dns.exception.SyntaxError('longitude seconds >= 60') + l = len(milliseconds) + if l == 0 or l > 3 or not milliseconds.isdigit(): + raise dns.exception.SyntaxError( + 'bad longitude milliseconds value') + if l == 1: + m = 100 + elif l == 2: + m = 10 + else: + m = 1 + longitude[3] = m * int(milliseconds) + t = tok.get_string() + elif t.isdigit(): + longitude[2] = int(t) + t = tok.get_string() + if t == 'W': + longitude[4] = -1 + elif t != 'E': + raise dns.exception.SyntaxError('bad longitude hemisphere value') + + t = tok.get_string() + if t[-1] == 'm': + t = t[0: -1] + altitude = float(t) * 100.0 # m -> cm + + token = tok.get().unescape() + if not token.is_eol_or_eof(): + value = token.value + if value[-1] == 'm': + value = value[0: -1] + size = float(value) * 100.0 # m -> cm + token = tok.get().unescape() + if not token.is_eol_or_eof(): + value = token.value + if value[-1] == 'm': + value = value[0: -1] + hprec = float(value) * 100.0 # m -> cm + token = tok.get().unescape() + if not token.is_eol_or_eof(): + value = token.value + if value[-1] == 'm': + value = value[0: -1] + vprec = float(value) * 100.0 # m -> cm + tok.get_eol() + + return cls(rdclass, rdtype, latitude, longitude, altitude, + size, hprec, vprec) + + def to_wire(self, file, compress=None, origin=None): + milliseconds = (self.latitude[0] * 3600000 + + self.latitude[1] * 60000 + + self.latitude[2] * 1000 + + self.latitude[3]) * self.latitude[4] + latitude = long(0x80000000) + milliseconds + milliseconds = (self.longitude[0] * 3600000 + + self.longitude[1] * 60000 + + self.longitude[2] * 1000 + + self.longitude[3]) * self.longitude[4] + longitude = long(0x80000000) + milliseconds + altitude = long(self.altitude) + long(10000000) + size = _encode_size(self.size, "size") + hprec = _encode_size(self.horizontal_precision, "horizontal precision") + vprec = _encode_size(self.vertical_precision, "vertical precision") + wire = struct.pack("!BBBBIII", 0, size, hprec, vprec, latitude, + longitude, altitude) + file.write(wire) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (version, size, hprec, vprec, latitude, longitude, altitude) = \ + struct.unpack("!BBBBIII", wire[current: current + rdlen]) + if latitude > long(0x80000000): + latitude = float(latitude - long(0x80000000)) / 3600000 + else: + latitude = -1 * float(long(0x80000000) - latitude) / 3600000 + if latitude < -90.0 or latitude > 90.0: + raise dns.exception.FormError("bad latitude") + if longitude > long(0x80000000): + longitude = float(longitude - long(0x80000000)) / 3600000 + else: + longitude = -1 * float(long(0x80000000) - longitude) / 3600000 + if longitude < -180.0 or longitude > 180.0: + raise dns.exception.FormError("bad longitude") + altitude = float(altitude) - 10000000.0 + size = _decode_size(size, "size") + hprec = _decode_size(hprec, "horizontal precision") + vprec = _decode_size(vprec, "vertical precision") + return cls(rdclass, rdtype, latitude, longitude, altitude, + size, hprec, vprec) + + def _get_float_latitude(self): + return _tuple_to_float(self.latitude) + + def _set_float_latitude(self, value): + self.latitude = _float_to_tuple(value) + + float_latitude = property(_get_float_latitude, _set_float_latitude, + doc="latitude as a floating point value") + + def _get_float_longitude(self): + return _tuple_to_float(self.longitude) + + def _set_float_longitude(self, value): + self.longitude = _float_to_tuple(value) + + float_longitude = property(_get_float_longitude, _set_float_longitude, + doc="longitude as a floating point value") diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/MX.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/MX.py new file mode 100644 index 0000000..0a06494 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/MX.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.mxbase + + +class MX(dns.rdtypes.mxbase.MXBase): + + """MX record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NS.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NS.py new file mode 100644 index 0000000..f9fcf63 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NS.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.nsbase + + +class NS(dns.rdtypes.nsbase.NSBase): + + """NS record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC.py new file mode 100644 index 0000000..4e3da72 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC.py @@ -0,0 +1,128 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.rdatatype +import dns.name +from dns._compat import xrange + + +class NSEC(dns.rdata.Rdata): + + """NSEC record + + @ivar next: the next name + @type next: dns.name.Name object + @ivar windows: the windowed bitmap list + @type windows: list of (window number, string) tuples""" + + __slots__ = ['next', 'windows'] + + def __init__(self, rdclass, rdtype, next, windows): + super(NSEC, self).__init__(rdclass, rdtype) + self.next = next + self.windows = windows + + def to_text(self, origin=None, relativize=True, **kw): + next = self.next.choose_relativity(origin, relativize) + text = '' + for (window, bitmap) in self.windows: + bits = [] + for i in xrange(0, len(bitmap)): + byte = bitmap[i] + for j in xrange(0, 8): + if byte & (0x80 >> j): + bits.append(dns.rdatatype.to_text(window * 256 + + i * 8 + j)) + text += (' ' + ' '.join(bits)) + return '{}{}'.format(next, text) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + next = tok.get_name() + next = next.choose_relativity(origin, relativize) + rdtypes = [] + while 1: + token = tok.get().unescape() + if token.is_eol_or_eof(): + break + nrdtype = dns.rdatatype.from_text(token.value) + if nrdtype == 0: + raise dns.exception.SyntaxError("NSEC with bit 0") + if nrdtype > 65535: + raise dns.exception.SyntaxError("NSEC with bit > 65535") + rdtypes.append(nrdtype) + rdtypes.sort() + window = 0 + octets = 0 + prior_rdtype = 0 + bitmap = bytearray(b'\0' * 32) + windows = [] + for nrdtype in rdtypes: + if nrdtype == prior_rdtype: + continue + prior_rdtype = nrdtype + new_window = nrdtype // 256 + if new_window != window: + windows.append((window, bitmap[0:octets])) + bitmap = bytearray(b'\0' * 32) + window = new_window + offset = nrdtype % 256 + byte = offset // 8 + bit = offset % 8 + octets = byte + 1 + bitmap[byte] = bitmap[byte] | (0x80 >> bit) + + windows.append((window, bitmap[0:octets])) + return cls(rdclass, rdtype, next, windows) + + def to_wire(self, file, compress=None, origin=None): + self.next.to_wire(file, None, origin) + for (window, bitmap) in self.windows: + file.write(struct.pack('!BB', window, len(bitmap))) + file.write(bitmap) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (next, cused) = dns.name.from_wire(wire[: current + rdlen], current) + current += cused + rdlen -= cused + windows = [] + while rdlen > 0: + if rdlen < 3: + raise dns.exception.FormError("NSEC too short") + window = wire[current] + octets = wire[current + 1] + if octets == 0 or octets > 32: + raise dns.exception.FormError("bad NSEC octets") + current += 2 + rdlen -= 2 + if rdlen < octets: + raise dns.exception.FormError("bad NSEC bitmap length") + bitmap = bytearray(wire[current: current + octets].unwrap()) + current += octets + rdlen -= octets + windows.append((window, bitmap)) + if origin is not None: + next = next.relativize(origin) + return cls(rdclass, rdtype, next, windows) + + def choose_relativity(self, origin=None, relativize=True): + self.next = self.next.choose_relativity(origin, relativize) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC3.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC3.py new file mode 100644 index 0000000..1c281c4 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC3.py @@ -0,0 +1,196 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2004-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import base64 +import binascii +import string +import struct + +import dns.exception +import dns.rdata +import dns.rdatatype +from dns._compat import xrange, text_type, PY3 + +# pylint: disable=deprecated-string-function +if PY3: + b32_hex_to_normal = bytes.maketrans(b'0123456789ABCDEFGHIJKLMNOPQRSTUV', + b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567') + b32_normal_to_hex = bytes.maketrans(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', + b'0123456789ABCDEFGHIJKLMNOPQRSTUV') +else: + b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567') + b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', + '0123456789ABCDEFGHIJKLMNOPQRSTUV') +# pylint: enable=deprecated-string-function + + +# hash algorithm constants +SHA1 = 1 + +# flag constants +OPTOUT = 1 + + +class NSEC3(dns.rdata.Rdata): + + """NSEC3 record + + @ivar algorithm: the hash algorithm number + @type algorithm: int + @ivar flags: the flags + @type flags: int + @ivar iterations: the number of iterations + @type iterations: int + @ivar salt: the salt + @type salt: string + @ivar next: the next name hash + @type next: string + @ivar windows: the windowed bitmap list + @type windows: list of (window number, string) tuples""" + + __slots__ = ['algorithm', 'flags', 'iterations', 'salt', 'next', 'windows'] + + def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt, + next, windows): + super(NSEC3, self).__init__(rdclass, rdtype) + self.algorithm = algorithm + self.flags = flags + self.iterations = iterations + if isinstance(salt, text_type): + self.salt = salt.encode() + else: + self.salt = salt + self.next = next + self.windows = windows + + def to_text(self, origin=None, relativize=True, **kw): + next = base64.b32encode(self.next).translate( + b32_normal_to_hex).lower().decode() + if self.salt == b'': + salt = '-' + else: + salt = binascii.hexlify(self.salt).decode() + text = u'' + for (window, bitmap) in self.windows: + bits = [] + for i in xrange(0, len(bitmap)): + byte = bitmap[i] + for j in xrange(0, 8): + if byte & (0x80 >> j): + bits.append(dns.rdatatype.to_text(window * 256 + + i * 8 + j)) + text += (u' ' + u' '.join(bits)) + return u'%u %u %u %s %s%s' % (self.algorithm, self.flags, + self.iterations, salt, next, text) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + algorithm = tok.get_uint8() + flags = tok.get_uint8() + iterations = tok.get_uint16() + salt = tok.get_string() + if salt == u'-': + salt = b'' + else: + salt = binascii.unhexlify(salt.encode('ascii')) + next = tok.get_string().encode( + 'ascii').upper().translate(b32_hex_to_normal) + next = base64.b32decode(next) + rdtypes = [] + while 1: + token = tok.get().unescape() + if token.is_eol_or_eof(): + break + nrdtype = dns.rdatatype.from_text(token.value) + if nrdtype == 0: + raise dns.exception.SyntaxError("NSEC3 with bit 0") + if nrdtype > 65535: + raise dns.exception.SyntaxError("NSEC3 with bit > 65535") + rdtypes.append(nrdtype) + rdtypes.sort() + window = 0 + octets = 0 + prior_rdtype = 0 + bitmap = bytearray(b'\0' * 32) + windows = [] + for nrdtype in rdtypes: + if nrdtype == prior_rdtype: + continue + prior_rdtype = nrdtype + new_window = nrdtype // 256 + if new_window != window: + if octets != 0: + windows.append((window, bitmap[0:octets])) + bitmap = bytearray(b'\0' * 32) + window = new_window + offset = nrdtype % 256 + byte = offset // 8 + bit = offset % 8 + octets = byte + 1 + bitmap[byte] = bitmap[byte] | (0x80 >> bit) + if octets != 0: + windows.append((window, bitmap[0:octets])) + return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, + windows) + + def to_wire(self, file, compress=None, origin=None): + l = len(self.salt) + file.write(struct.pack("!BBHB", self.algorithm, self.flags, + self.iterations, l)) + file.write(self.salt) + l = len(self.next) + file.write(struct.pack("!B", l)) + file.write(self.next) + for (window, bitmap) in self.windows: + file.write(struct.pack("!BB", window, len(bitmap))) + file.write(bitmap) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (algorithm, flags, iterations, slen) = \ + struct.unpack('!BBHB', wire[current: current + 5]) + + current += 5 + rdlen -= 5 + salt = wire[current: current + slen].unwrap() + current += slen + rdlen -= slen + nlen = wire[current] + current += 1 + rdlen -= 1 + next = wire[current: current + nlen].unwrap() + current += nlen + rdlen -= nlen + windows = [] + while rdlen > 0: + if rdlen < 3: + raise dns.exception.FormError("NSEC3 too short") + window = wire[current] + octets = wire[current + 1] + if octets == 0 or octets > 32: + raise dns.exception.FormError("bad NSEC3 octets") + current += 2 + rdlen -= 2 + if rdlen < octets: + raise dns.exception.FormError("bad NSEC3 bitmap length") + bitmap = bytearray(wire[current: current + octets].unwrap()) + current += octets + rdlen -= octets + windows.append((window, bitmap)) + return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, + windows) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC3PARAM.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC3PARAM.py new file mode 100644 index 0000000..87c36e5 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/NSEC3PARAM.py @@ -0,0 +1,90 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct +import binascii + +import dns.exception +import dns.rdata +from dns._compat import text_type + + +class NSEC3PARAM(dns.rdata.Rdata): + + """NSEC3PARAM record + + @ivar algorithm: the hash algorithm number + @type algorithm: int + @ivar flags: the flags + @type flags: int + @ivar iterations: the number of iterations + @type iterations: int + @ivar salt: the salt + @type salt: string""" + + __slots__ = ['algorithm', 'flags', 'iterations', 'salt'] + + def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt): + super(NSEC3PARAM, self).__init__(rdclass, rdtype) + self.algorithm = algorithm + self.flags = flags + self.iterations = iterations + if isinstance(salt, text_type): + self.salt = salt.encode() + else: + self.salt = salt + + def to_text(self, origin=None, relativize=True, **kw): + if self.salt == b'': + salt = '-' + else: + salt = binascii.hexlify(self.salt).decode() + return '%u %u %u %s' % (self.algorithm, self.flags, self.iterations, + salt) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + algorithm = tok.get_uint8() + flags = tok.get_uint8() + iterations = tok.get_uint16() + salt = tok.get_string() + if salt == '-': + salt = '' + else: + salt = binascii.unhexlify(salt.encode()) + tok.get_eol() + return cls(rdclass, rdtype, algorithm, flags, iterations, salt) + + def to_wire(self, file, compress=None, origin=None): + l = len(self.salt) + file.write(struct.pack("!BBHB", self.algorithm, self.flags, + self.iterations, l)) + file.write(self.salt) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (algorithm, flags, iterations, slen) = \ + struct.unpack('!BBHB', + wire[current: current + 5]) + current += 5 + rdlen -= 5 + salt = wire[current: current + slen].unwrap() + current += slen + rdlen -= slen + if rdlen != 0: + raise dns.exception.FormError + return cls(rdclass, rdtype, algorithm, flags, iterations, salt) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/OPENPGPKEY.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/OPENPGPKEY.py new file mode 100644 index 0000000..a066cf9 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/OPENPGPKEY.py @@ -0,0 +1,60 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2016 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import base64 + +import dns.exception +import dns.rdata +import dns.tokenizer + +class OPENPGPKEY(dns.rdata.Rdata): + + """OPENPGPKEY record + + @ivar key: the key + @type key: bytes + @see: RFC 7929 + """ + + def __init__(self, rdclass, rdtype, key): + super(OPENPGPKEY, self).__init__(rdclass, rdtype) + self.key = key + + def to_text(self, origin=None, relativize=True, **kw): + return dns.rdata._base64ify(self.key) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + key = base64.b64decode(b64) + return cls(rdclass, rdtype, key) + + def to_wire(self, file, compress=None, origin=None): + file.write(self.key) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + key = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, key) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/PTR.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/PTR.py new file mode 100644 index 0000000..20cd507 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/PTR.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.nsbase + + +class PTR(dns.rdtypes.nsbase.NSBase): + + """PTR record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RP.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RP.py new file mode 100644 index 0000000..8f07be9 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RP.py @@ -0,0 +1,82 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.exception +import dns.rdata +import dns.name + + +class RP(dns.rdata.Rdata): + + """RP record + + @ivar mbox: The responsible person's mailbox + @type mbox: dns.name.Name object + @ivar txt: The owner name of a node with TXT records, or the root name + if no TXT records are associated with this RP. + @type txt: dns.name.Name object + @see: RFC 1183""" + + __slots__ = ['mbox', 'txt'] + + def __init__(self, rdclass, rdtype, mbox, txt): + super(RP, self).__init__(rdclass, rdtype) + self.mbox = mbox + self.txt = txt + + def to_text(self, origin=None, relativize=True, **kw): + mbox = self.mbox.choose_relativity(origin, relativize) + txt = self.txt.choose_relativity(origin, relativize) + return "{} {}".format(str(mbox), str(txt)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + mbox = tok.get_name() + txt = tok.get_name() + mbox = mbox.choose_relativity(origin, relativize) + txt = txt.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, mbox, txt) + + def to_wire(self, file, compress=None, origin=None): + self.mbox.to_wire(file, None, origin) + self.txt.to_wire(file, None, origin) + + def to_digestable(self, origin=None): + return self.mbox.to_digestable(origin) + \ + self.txt.to_digestable(origin) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (mbox, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + current += cused + rdlen -= cused + if rdlen <= 0: + raise dns.exception.FormError + (txt, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if origin is not None: + mbox = mbox.relativize(origin) + txt = txt.relativize(origin) + return cls(rdclass, rdtype, mbox, txt) + + def choose_relativity(self, origin=None, relativize=True): + self.mbox = self.mbox.choose_relativity(origin, relativize) + self.txt = self.txt.choose_relativity(origin, relativize) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RRSIG.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RRSIG.py new file mode 100644 index 0000000..d3756ec --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RRSIG.py @@ -0,0 +1,158 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import base64 +import calendar +import struct +import time + +import dns.dnssec +import dns.exception +import dns.rdata +import dns.rdatatype + + +class BadSigTime(dns.exception.DNSException): + + """Time in DNS SIG or RRSIG resource record cannot be parsed.""" + + +def sigtime_to_posixtime(what): + if len(what) != 14: + raise BadSigTime + year = int(what[0:4]) + month = int(what[4:6]) + day = int(what[6:8]) + hour = int(what[8:10]) + minute = int(what[10:12]) + second = int(what[12:14]) + return calendar.timegm((year, month, day, hour, minute, second, + 0, 0, 0)) + + +def posixtime_to_sigtime(what): + return time.strftime('%Y%m%d%H%M%S', time.gmtime(what)) + + +class RRSIG(dns.rdata.Rdata): + + """RRSIG record + + @ivar type_covered: the rdata type this signature covers + @type type_covered: int + @ivar algorithm: the algorithm used for the sig + @type algorithm: int + @ivar labels: number of labels + @type labels: int + @ivar original_ttl: the original TTL + @type original_ttl: long + @ivar expiration: signature expiration time + @type expiration: long + @ivar inception: signature inception time + @type inception: long + @ivar key_tag: the key tag + @type key_tag: int + @ivar signer: the signer + @type signer: dns.name.Name object + @ivar signature: the signature + @type signature: string""" + + __slots__ = ['type_covered', 'algorithm', 'labels', 'original_ttl', + 'expiration', 'inception', 'key_tag', 'signer', + 'signature'] + + def __init__(self, rdclass, rdtype, type_covered, algorithm, labels, + original_ttl, expiration, inception, key_tag, signer, + signature): + super(RRSIG, self).__init__(rdclass, rdtype) + self.type_covered = type_covered + self.algorithm = algorithm + self.labels = labels + self.original_ttl = original_ttl + self.expiration = expiration + self.inception = inception + self.key_tag = key_tag + self.signer = signer + self.signature = signature + + def covers(self): + return self.type_covered + + def to_text(self, origin=None, relativize=True, **kw): + return '%s %d %d %d %s %s %d %s %s' % ( + dns.rdatatype.to_text(self.type_covered), + self.algorithm, + self.labels, + self.original_ttl, + posixtime_to_sigtime(self.expiration), + posixtime_to_sigtime(self.inception), + self.key_tag, + self.signer.choose_relativity(origin, relativize), + dns.rdata._base64ify(self.signature) + ) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + type_covered = dns.rdatatype.from_text(tok.get_string()) + algorithm = dns.dnssec.algorithm_from_text(tok.get_string()) + labels = tok.get_int() + original_ttl = tok.get_ttl() + expiration = sigtime_to_posixtime(tok.get_string()) + inception = sigtime_to_posixtime(tok.get_string()) + key_tag = tok.get_int() + signer = tok.get_name() + signer = signer.choose_relativity(origin, relativize) + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + signature = base64.b64decode(b64) + return cls(rdclass, rdtype, type_covered, algorithm, labels, + original_ttl, expiration, inception, key_tag, signer, + signature) + + def to_wire(self, file, compress=None, origin=None): + header = struct.pack('!HBBIIIH', self.type_covered, + self.algorithm, self.labels, + self.original_ttl, self.expiration, + self.inception, self.key_tag) + file.write(header) + self.signer.to_wire(file, None, origin) + file.write(self.signature) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + header = struct.unpack('!HBBIIIH', wire[current: current + 18]) + current += 18 + rdlen -= 18 + (signer, cused) = dns.name.from_wire(wire[: current + rdlen], current) + current += cused + rdlen -= cused + if origin is not None: + signer = signer.relativize(origin) + signature = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, header[0], header[1], header[2], + header[3], header[4], header[5], header[6], signer, + signature) + + def choose_relativity(self, origin=None, relativize=True): + self.signer = self.signer.choose_relativity(origin, relativize) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RT.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RT.py new file mode 100644 index 0000000..d0feb79 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/RT.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.mxbase + + +class RT(dns.rdtypes.mxbase.UncompressedDowncasingMX): + + """RT record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SOA.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SOA.py new file mode 100644 index 0000000..aec81ca --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SOA.py @@ -0,0 +1,116 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.name + + +class SOA(dns.rdata.Rdata): + + """SOA record + + @ivar mname: the SOA MNAME (master name) field + @type mname: dns.name.Name object + @ivar rname: the SOA RNAME (responsible name) field + @type rname: dns.name.Name object + @ivar serial: The zone's serial number + @type serial: int + @ivar refresh: The zone's refresh value (in seconds) + @type refresh: int + @ivar retry: The zone's retry value (in seconds) + @type retry: int + @ivar expire: The zone's expiration value (in seconds) + @type expire: int + @ivar minimum: The zone's negative caching time (in seconds, called + "minimum" for historical reasons) + @type minimum: int + @see: RFC 1035""" + + __slots__ = ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire', + 'minimum'] + + def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry, + expire, minimum): + super(SOA, self).__init__(rdclass, rdtype) + self.mname = mname + self.rname = rname + self.serial = serial + self.refresh = refresh + self.retry = retry + self.expire = expire + self.minimum = minimum + + def to_text(self, origin=None, relativize=True, **kw): + mname = self.mname.choose_relativity(origin, relativize) + rname = self.rname.choose_relativity(origin, relativize) + return '%s %s %d %d %d %d %d' % ( + mname, rname, self.serial, self.refresh, self.retry, + self.expire, self.minimum) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + mname = tok.get_name() + rname = tok.get_name() + mname = mname.choose_relativity(origin, relativize) + rname = rname.choose_relativity(origin, relativize) + serial = tok.get_uint32() + refresh = tok.get_ttl() + retry = tok.get_ttl() + expire = tok.get_ttl() + minimum = tok.get_ttl() + tok.get_eol() + return cls(rdclass, rdtype, mname, rname, serial, refresh, retry, + expire, minimum) + + def to_wire(self, file, compress=None, origin=None): + self.mname.to_wire(file, compress, origin) + self.rname.to_wire(file, compress, origin) + five_ints = struct.pack('!IIIII', self.serial, self.refresh, + self.retry, self.expire, self.minimum) + file.write(five_ints) + + def to_digestable(self, origin=None): + return self.mname.to_digestable(origin) + \ + self.rname.to_digestable(origin) + \ + struct.pack('!IIIII', self.serial, self.refresh, + self.retry, self.expire, self.minimum) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (mname, cused) = dns.name.from_wire(wire[: current + rdlen], current) + current += cused + rdlen -= cused + (rname, cused) = dns.name.from_wire(wire[: current + rdlen], current) + current += cused + rdlen -= cused + if rdlen != 20: + raise dns.exception.FormError + five_ints = struct.unpack('!IIIII', + wire[current: current + rdlen]) + if origin is not None: + mname = mname.relativize(origin) + rname = rname.relativize(origin) + return cls(rdclass, rdtype, mname, rname, + five_ints[0], five_ints[1], five_ints[2], five_ints[3], + five_ints[4]) + + def choose_relativity(self, origin=None, relativize=True): + self.mname = self.mname.choose_relativity(origin, relativize) + self.rname = self.rname.choose_relativity(origin, relativize) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SPF.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SPF.py new file mode 100644 index 0000000..41dee62 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SPF.py @@ -0,0 +1,25 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.txtbase + + +class SPF(dns.rdtypes.txtbase.TXTBase): + + """SPF record + + @see: RFC 4408""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SSHFP.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SSHFP.py new file mode 100644 index 0000000..c18311e --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/SSHFP.py @@ -0,0 +1,79 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2005-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct +import binascii + +import dns.rdata +import dns.rdatatype + + +class SSHFP(dns.rdata.Rdata): + + """SSHFP record + + @ivar algorithm: the algorithm + @type algorithm: int + @ivar fp_type: the digest type + @type fp_type: int + @ivar fingerprint: the fingerprint + @type fingerprint: string + @see: draft-ietf-secsh-dns-05.txt""" + + __slots__ = ['algorithm', 'fp_type', 'fingerprint'] + + def __init__(self, rdclass, rdtype, algorithm, fp_type, + fingerprint): + super(SSHFP, self).__init__(rdclass, rdtype) + self.algorithm = algorithm + self.fp_type = fp_type + self.fingerprint = fingerprint + + def to_text(self, origin=None, relativize=True, **kw): + return '%d %d %s' % (self.algorithm, + self.fp_type, + dns.rdata._hexify(self.fingerprint, + chunksize=128)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + algorithm = tok.get_uint8() + fp_type = tok.get_uint8() + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value.encode()) + fingerprint = b''.join(chunks) + fingerprint = binascii.unhexlify(fingerprint) + return cls(rdclass, rdtype, algorithm, fp_type, fingerprint) + + def to_wire(self, file, compress=None, origin=None): + header = struct.pack("!BB", self.algorithm, self.fp_type) + file.write(header) + file.write(self.fingerprint) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + header = struct.unpack("!BB", wire[current: current + 2]) + current += 2 + rdlen -= 2 + fingerprint = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, header[0], header[1], fingerprint) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/TLSA.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/TLSA.py new file mode 100644 index 0000000..a135c2b --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/TLSA.py @@ -0,0 +1,84 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2005-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct +import binascii + +import dns.rdata +import dns.rdatatype + + +class TLSA(dns.rdata.Rdata): + + """TLSA record + + @ivar usage: The certificate usage + @type usage: int + @ivar selector: The selector field + @type selector: int + @ivar mtype: The 'matching type' field + @type mtype: int + @ivar cert: The 'Certificate Association Data' field + @type cert: string + @see: RFC 6698""" + + __slots__ = ['usage', 'selector', 'mtype', 'cert'] + + def __init__(self, rdclass, rdtype, usage, selector, + mtype, cert): + super(TLSA, self).__init__(rdclass, rdtype) + self.usage = usage + self.selector = selector + self.mtype = mtype + self.cert = cert + + def to_text(self, origin=None, relativize=True, **kw): + return '%d %d %d %s' % (self.usage, + self.selector, + self.mtype, + dns.rdata._hexify(self.cert, + chunksize=128)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + usage = tok.get_uint8() + selector = tok.get_uint8() + mtype = tok.get_uint8() + cert_chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + cert_chunks.append(t.value.encode()) + cert = b''.join(cert_chunks) + cert = binascii.unhexlify(cert) + return cls(rdclass, rdtype, usage, selector, mtype, cert) + + def to_wire(self, file, compress=None, origin=None): + header = struct.pack("!BBB", self.usage, self.selector, self.mtype) + file.write(header) + file.write(self.cert) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + header = struct.unpack("!BBB", wire[current: current + 3]) + current += 3 + rdlen -= 3 + cert = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, header[0], header[1], header[2], cert) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/TXT.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/TXT.py new file mode 100644 index 0000000..c5ae919 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/TXT.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.txtbase + + +class TXT(dns.rdtypes.txtbase.TXTBase): + + """TXT record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/URI.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/URI.py new file mode 100644 index 0000000..f5b65ed --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/URI.py @@ -0,0 +1,82 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# Copyright (C) 2015 Red Hat, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.name +from dns._compat import text_type + + +class URI(dns.rdata.Rdata): + + """URI record + + @ivar priority: the priority + @type priority: int + @ivar weight: the weight + @type weight: int + @ivar target: the target host + @type target: dns.name.Name object + @see: draft-faltstrom-uri-13""" + + __slots__ = ['priority', 'weight', 'target'] + + def __init__(self, rdclass, rdtype, priority, weight, target): + super(URI, self).__init__(rdclass, rdtype) + self.priority = priority + self.weight = weight + if len(target) < 1: + raise dns.exception.SyntaxError("URI target cannot be empty") + if isinstance(target, text_type): + self.target = target.encode() + else: + self.target = target + + def to_text(self, origin=None, relativize=True, **kw): + return '%d %d "%s"' % (self.priority, self.weight, + self.target.decode()) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + priority = tok.get_uint16() + weight = tok.get_uint16() + target = tok.get().unescape() + if not (target.is_quoted_string() or target.is_identifier()): + raise dns.exception.SyntaxError("URI target must be a string") + tok.get_eol() + return cls(rdclass, rdtype, priority, weight, target.value) + + def to_wire(self, file, compress=None, origin=None): + two_ints = struct.pack("!HH", self.priority, self.weight) + file.write(two_ints) + file.write(self.target) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + if rdlen < 5: + raise dns.exception.FormError('URI RR is shorter than 5 octets') + + (priority, weight) = struct.unpack('!HH', wire[current: current + 4]) + current += 4 + rdlen -= 4 + target = wire[current: current + rdlen] + current += rdlen + + return cls(rdclass, rdtype, priority, weight, target) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/X25.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/X25.py new file mode 100644 index 0000000..e530a2c --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/X25.py @@ -0,0 +1,66 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.tokenizer +from dns._compat import text_type + + +class X25(dns.rdata.Rdata): + + """X25 record + + @ivar address: the PSDN address + @type address: string + @see: RFC 1183""" + + __slots__ = ['address'] + + def __init__(self, rdclass, rdtype, address): + super(X25, self).__init__(rdclass, rdtype) + if isinstance(address, text_type): + self.address = address.encode() + else: + self.address = address + + def to_text(self, origin=None, relativize=True, **kw): + return '"%s"' % dns.rdata._escapify(self.address) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + address = tok.get_string() + tok.get_eol() + return cls(rdclass, rdtype, address) + + def to_wire(self, file, compress=None, origin=None): + l = len(self.address) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(self.address) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + l = wire[current] + current += 1 + rdlen -= 1 + if l != rdlen: + raise dns.exception.FormError + address = wire[current: current + l].unwrap() + return cls(rdclass, rdtype, address) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__init__.py b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__init__.py new file mode 100644 index 0000000..ca41ef8 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__init__.py @@ -0,0 +1,57 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Class ANY (generic) rdata type classes.""" + +__all__ = [ + 'AFSDB', + 'AVC', + 'CAA', + 'CDNSKEY', + 'CDS', + 'CERT', + 'CNAME', + 'CSYNC', + 'DLV', + 'DNAME', + 'DNSKEY', + 'DS', + 'EUI48', + 'EUI64', + 'GPOS', + 'HINFO', + 'HIP', + 'ISDN', + 'LOC', + 'MX', + 'NS', + 'NSEC', + 'NSEC3', + 'NSEC3PARAM', + 'OPENPGPKEY', + 'PTR', + 'RP', + 'RRSIG', + 'RT', + 'SOA', + 'SPF', + 'SSHFP', + 'TLSA', + 'TXT', + 'URI', + 'X25', +] diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/AFSDB.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/AFSDB.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55d7004f71464fd7a0f52eaa38a79d131d3558c5 GIT binary patch literal 1124 zcma)5&u`N(6n1_!ZrUPI35jFG0jUye#E;9W33a1_6TM7G5FuG-g>I?Bw!i)wxoHndFY+LYqeC zfppboQEYQDaf_8`ChmEVY{Y&Ml8t}jMrqO7yUJ9N2J3orGjq|^+T8djE>G1M$?+V( z%@(l;i%Eu$J2`SQ0z|2%4Ir~kd1*`rYdBr;S@+d!u zQdI;=a_}O086SRGDi7l2+hUcaIPxS%Ey_EdfAXr^80Xuvw-g1d?_h+HbpWDWKHRTp zv0=pki9K4CC>F#{+YttDUMDN@8ArOriYV>+>?+qiptiE7ZsI-z$E~<6_I?*c#YMOZ z(j{C^75H|%J}PNm;(06J@J47u-(M-JZ7zrXgS54c(^aP_dLTEE2{_hp~0W zHwljWjD6h%NzK@d@hoIa!Z#$c3sBNrX1S2XR#No!5C#Z+1T2*n;2TJM#7AK20RXkl z0X3-M=!g|J>i9z}*}8DX>x)I81pLNS`F8E}JGJ-mhcwLAP^L-=KFhwPVW6UP`Tk>d WR4a6qNmT>%Xs_<|5R<@csPP{Sdr0m523F*SR2Hs2W}1kIO0x@V&@WZm*aQDv2Zds z!xHbn!58Uhk2$<(6cDWN{?!pAF@cGTf%Lt&YMN(?sYPG?7 zMu=|v`gLNh>Jl=W&7zb^7L|HTm@(;C7D8G>xHO?+niawdZ3wI(>?sM8vQRmscxVMM zX2oLA@v4AQ39Xb?ElP`$PxG2@QTjM#`Ksbm%FBe(Po#ZN+`vzl*g_GNsxXztvOEuu z(&OypVcaNCb2}+zt%YcA=SqN(!CfsTQgiLXmi_twH3_^X?rg?;&>pSYBl~Pe%m_G& jG_k+R#{N3(4{wKks5i6!vX(4>wN-Gs{Lb0#-%I!x7&m+D literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CAA.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CAA.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a5bc05076753fb24c9d5bb51068761b72be8342 GIT binary patch literal 2125 zcmZ8iOK%%D5GMDnm6V5*=1~ObCWzapXks7@+B9g3*hbnz0UeSY(nWy9Vo510uXa_E zvSVR&sa@pIA5rPpKhy)SJ^3&6(#~*Y*);_Yhr{74`SF|4PPZEpX!Aclefv9Tf8*q| zIiNg;E}w#6gwcY;%}8U*%@)g`^qdpeP5K$i(}t0; z$ruDDF=YfI(b&cq%o*CT^MMQ~bD4J>#4fwaS}Z)KvB!P3!P=~IOpjJ_v%f$@4|cgw`5@0yl~-l7Jyq{2k*mW~ZD#DfNbsx@ zEDR%P&-49MM1vw7%4d;!#~Za-Qiqe({8^Nj>YTqyhmAKV=X{M>Dv_5fs|miJ7E|81 z8};0V)zbMbl7sKdA9ka!o<4b^U2`&RLuBn5@60o}5`rV5Y(tk1Kq#VUO^&RERnyv9 zT9njwO%l6yKsvPx(q#lNqy3(zT{)d_AuQOagCxnzTqTLXU;?8G7X-LDk{1K*3zikB zl-d&vQMu?xbt_4XN0R(W{&}{g#*?i{K6#jzQl&-l@Nxd-=$pNv++wAi9KySlsBJaT z--s>Cjmlud-TOKV}P@&}SE& z--4*^1zD202P0jQg$25=?Akw~jP5z&3+0U5g~zNV{gu}K!e0{kd}XtZ?QCCA6C_0K z)qWiuxtOs1lYikGvkuTIQdJcdRXLp9#91z*vQkl6Ox~sCbj(Gb^@6xH z)tuhZgk2JuBTu-K3Y@pILWzP6&kr3bcCw zC5USeAe&}NJCiiqYi@Z14q@1(FKtVSrK>6pT21b`4cnYSUT_^`)p#Pflm;qIi;Ku0 z+YWNUzk{F>nMmk$8UiXC(AS(pj|?*mTN^s+YtAXM0CqvqFt@)+ezR_qrS;aD`||+t z_?iGNX0;BQ)p^UzVFr8LoA3v5%j}wmE6(|Ks}2q402TZ0&dv!IoSr2@n0e)Pex9B;3 zpa;}~*Q?&g!q~xLSf*p1BsxrzamA(u>YXI{WeOB-R{SJkRR(4#d$OpMgwlynifbTr z+f>3ahcd^+9W-yE=;2y-RVOoE6tHPsGkR3udk8EYrYPSAMQ(ryLdOcNju*NX?Sx@q zQM29)42E$Rs@9`*)|o7fTWD(vnOTMu<0X_SAudC}*nNpL&O|voK%<$;6@1%V`+NMn Mslx#z8T{=304JySiU0rr literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CDNSKEY.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/CDNSKEY.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ffc4e74bcc834e3eee87c2023fe130319921c61d GIT binary patch literal 507 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 Cv;naI literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DLV.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DLV.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..241cfd83f02bec039787980461f5717d2e2ba281 GIT binary patch literal 384 zcmYLEyGq1R5WSDM3Bd(fuonv<#pZ%mipaVw*hrcM!HaN-nV^YzTywKUgst>HtS$VZ zv{wFtm6L2%2j*~Q=FDq89=il>{eE=!$qD)Df~{FdX6WV+0SM5HNP0zp0e>UFW16y* zr`9W%J3yDjv%XPBf~do-Q6w{Tvxg94KM=`)N)8M=c*_^pH!m*2K@~@31%YR^j#5RK z$4a%XQh5ohtmC^%J+H!SsMtzD87cKaDjO&F@N*{WTnnA(X;PRv%(Cfma+01tJs1In z(M|nW79A56)QygfxD0Lu?)G(4F`TmB9oi9x^|3dS6O{Xd+y`?Xniy{{jI@WO91Ypg ZVmZfZ-}ryihB-L1b literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DNAME.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DNAME.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e8c1b1f42ef9c826d90d8aa12ba33330f94bcd8 GIT binary patch literal 552 zcmY*VO-sW-5Zz7EG?dmu#e<&2gU~}8(34Q4^#f1lA|4FFl4jPLm?m*IJ+$aa|A%_? zFXigVzu?K4m_i+xx3ly09&^&^v>4j++y3pY#n=~pR)&8zLf3l;zjWvFg|*iY8O(SFN*strN~uKEOM#cv3KKE z+6MVT(P_3xN~Mo4H~%XCnNd}vbc9HQnG~XI2{FrHo>1Ht;&C1%b)_i;WT6n%+DhIU zI7p+2W{dcU*fA`l%Jgi%ixLO5#6hYjftGmNRQt_3>DzU7<2ntqS+1nk61=Nw!5R%6 SMG;r&4F6;vcZrag9rG7D34y}^ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DNSKEY.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DNSKEY.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b12dad1e2a8eaeb7409b47461ea580dbbe4e0dab GIT binary patch literal 504 zcmYjOJx{|h5OwS{Nh>N9kdWAzkTSH9U;+Uu6^H?mrBf}WQ>fk2HebZ4M39)^e=zfx zvNG`(m^ddb<)k~mv+w!d*@JewMbKV94)5M9A2Cg(D5#=;u zoEbzgVNNMGZ-{6J>zxQo8uP~7n%i%TJHi+e*ZxL6@m*SOPr_iTAWtBd&p9ZWm%H`W zBuk>d&5UAw#xRUEb8QBKKDz2)kd+org~6Gi*oBqWl|Q__9=){d^&peuBon@CmJUE1 zL=vEE0Yr&dh8k}HJS~H8bz%dEWDM|0vL@bNg`aaTk5Vt4rQKPq@*oVmN3-Mk$zrNJ z5v#PwACp)kFB5r@O66VpBd>1XON&gu;J#L@2XbhYyG_1_jNXdTL%fj1L!cxM606PZ rB`U&>0Nh^H^47oNR^4WR#OmIS>Kf^PEuFJ^+KU~n!qO^?4s+NqlDU2J literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DS.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/DS.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7982cb2438eb4dac91f57564cb412539c5999dec GIT binary patch literal 381 zcmYLEJxjzu5Z#ZM#KQwQuonv<#brUO1CjFx*riG3A}lepXkxz1=86-n^nY0U2mCQ< zt^5mCPI5UNn8%x$_hx5T)9Hj@yu6>@esV&-`eGLrk|m}&K>z|YCz4(hV8Gu9a7{Co z@yvSVat~-kJnI{EBuskT1x2#NG=~Tp{XirGDmgH8@Qwx1^L`K=H#(^r2tBKFl`7*x zE7eVuDk@m#JwH(DX&vX|#8C>WM5zzbIJkF!pM_|PTGVMhPfOFrc|Jc&&$Gqjy%A8F zdec5sWzR$d?WWd7T!l9xi2QofFkEufU)d9v4Yg;>8LItJ?Sr|CjmE=EBb~7+?XhbI Z(F&)7@&BYPb8%=x6bQF{p1tLYVrz6q@git_2h$ao9z&gp=WF|T1HqK%@C_$ov z|3S@PN=uc$aMg`Bi4Y^r+vge2^V_-D*{L&%r`Lnu5Ht4f58I$K>r&c%0$>p2Oaxa9 zLWo`%L>P?2aWsyfBT<3ihBe|9-DACh$8Cf}x|Eg^Ak704Ap|0VP{bHRw96pgW28_a zh3c|$d3)XNJU*8nZg4O)P_J`}u6oD}A1XaUQy8V)32%3redYM&+@S^peyi2}4EZ&n zc50~5@I%sRwmXfrf?E{$S;0C|8m+q)@r0Y<;Mb4#QOnKUs!Enuk%xewNA40Sbv8jM zmvt#8Q<&wRf0gonmgSpHO-h&!q!dYi;ZWwNMdEPoJbPotue*eQr>UD1X`zay($-~p z-u$VK#>an0HU({qh5Iwro}~u7ahsm^?$UBEtzu#PVs|O6cbQbLEqbk1BP-`>P s!kOx47HQ$yirS_sYTI&+1TUyx&VHC%vo9pQOitH7diKq~=ATWX|5qK5=Kufz literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/EUI64.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/EUI64.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ef8e0a9a68f28a0483f81f6e4124f5ea678885ad GIT binary patch literal 567 zcmY*VO>Y`85cPflD_Ra!a_G_Op$Z4sDnUevqKZU{qFlIC9AZ_n7G@x(i`m$wf=W3h z|0C!AC9XN~7kcV=0Yw>Uo}XttZ^m=gXw(_mj_0;do@UhYpG=)*xo%3#|HB^pYFCA(?-~+857RYY_ zwNqn-h98kmtJ`UA72K-8_X^gL(qx;pi09mlN2lL9CvCTMn}kN*L>>ZyK24WMsk0eM zxvon&o5Lda{G*f)i!9$|YEr^{B&A4(D~B>iEfR-I=hu_*Qkl(eIypH{Uji{sUqCkm&#b literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/GPOS.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/GPOS.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e07451fde8383d1e0129756a254b14be85f812e GIT binary patch literal 4181 zcmbVP&2QYs6`$evu6AWbl5HtTll4d1Y+GB73)HC-q;`xZKnkcuYy=GvlpuCSG9_xc zouRCFOZ8B>2nw`01n8+iD;;z1AJB9Dgt@jCpL6S}zc*a2S5mDa;V$1BzIku>=6%iM zyWMV^;oATEcR%^yJY)Z&hvxDyxPx2&3P3Qya~9W_$Bun=C)l&t$^D%m4tBygV{zVY0QOx#6NNN`My(e z5rF%n%BgYbY`I(B?|Dtvs^W+Kk(JhJI%j$H=an;^`@ET>H}u1GMe07iM&Jho=<#a; z*S`i}{lJ8o7TIQ28eflcAXf~vX~|Cqa#Uu;(6rtw)XvY8DwGL?927$KUE}RNOiS2C zZa_|Dn-9w`nOekx|9NYz+!?KnveC6{sLM3ZuieakwDptiO}&PNM~};g#gIm8N{~7A z+THb!*WUl-FYaF-JvJATM`@mkw3Nw4UZiEBOO*{bU&O-t0_n?Fc!x*a!`)Fs{syQ4;MM5T!L%T(8e5kT3?WSt5 zMDwjgr^Bqw#`1MM>HvW8Hq=ln7!ByLx%|mM{{sWbVlEgWlE*!zraAOsML zQS6ILq9xi-cpS)3To!Yp^MoI8#Of8%74x9CK)))^i3Lk=-Juj&zQ&J z^DxnC#v{*+zarREaJ~}lb`RH`>`|(Ed0J-Wu8_By4WxYLqrD%51BKi5kg)btwErm`V)=h5ibl zL=08zz&S*wR?d;bS?N}8=^Z%wh8_9SQGi%`vkWWufbYAQ^DNg#c0^qDh`4?YE)QHD z=6uUl*%5KoBjS1jE+1Te8BNxVCQ{La-Xc0QY7yOH@N-tV6-(Nc2RK*xfE`;E5cyqX z`|e08wTi8oC`mE|b&@DlTV{Nld&bR%rE-Yi!h<%xZKf$oNA(hcmjO^hJT3DL6Dl#t zQ>{%_#(22e$go$f!6#29`JG3mW@XD^#=oT z7G2~xa^TN#>mGpMhbRJDoYEiIonVjfk&8%o*2mFr_j~r=_f4>YnwOUK4(74I%yvC> z83Yp)D0|t^w3VcYdW4E#obA1n^&%{bgwBo!keO5qDq!P|)qOHKjk*@NNb!5beFLC! z>ActvCKxegpAiR#{D{HBjH0m$s<4U<{JN?+aeGrXr85p`EQ`F~GVUPP>Izm>R{@M$ z7TfB3^hl-bgtt!aqqU)m9lMi{!L051>@?mO&)eNhSq9_)x~K$B_j8B`s>NF6%?)?`Da^{o z&ZT$zk#Tc5w1zSBceR#^4#fH>^!HR&N)sS6b_X~KN9kaDCP@4`NW6_KmnIq%J0m5v zw$?U0KWSVFlD$mH6c*BSj?j_PK`L}k;Ade&?1PY4an0eLn)%;&K;nC7H&9#zzr|o| zU+_2CzK<~Rw>|ZG3Da(o;lYPrc+s{ehb}@5rKJjMnJTn0XRlSBu@=hFH(1M6|2$)@ z_9WD!s#UdZs5|S5Hr@9W?O$~WbOB7TJKR(0s6VHu<#`tIu}4-j;b2!OIV@ve3G%N^ zfgcm+@xpe}OLYp+5(Sv`bpSR^fw~uI5`r-GCbPd~KAR@if7GhbMVJb$O?yhMCQT*@ ztzHGqYS-sBuuiJBlu(w}EmL#8{Sh*nR%Lv=Qdi2;OasdR9>P-}6*JH+!-fcV^GrilV|ho%OY3R09&(75N#XkiGYOrL=(i}9?RQw+Xwp$gRhq>7 h4++^9%~YIcWhZ*OcEvkH(p15qq%FV;ZZsbS{{`&Y!~*~T literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/HINFO.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/HINFO.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68b5f752368ee9909256b4bfcfa4853d8600d83c GIT binary patch literal 2087 zcmah~OOM+&5GE<=VXeJ+B0+j6+!P4nL$XbSpluKod3E~&oFYkqRwy6{B6lONEU6@& z&AQq{yIbTR^jiDaKhYn;Yft$LJ#~iiZniljG&me`W~h059N!-dVgh6T&nrLu4ctGt zIT{?8yD;@bAc6>5lB8Q{!rb0lt=z4w^rt}*Q1T@ap5TW>aLFd&Bs%bto}f?2$bSVl zk@1Myo{=w1YW5nLe z48<7{i?u^~K$A$E6@4*)^B$a^6YJuXJC9!yPLefn!_VDrMgW-*j zZr-vUe9E#~=e`S^5L_`09!xz3Vu+zFIbaLc(v~e5CB|z#!w;Cc+IkCrNm`NyRnU64 zf{Z)a!t$LO~#SIvz#V*Rw_{h2OAInif@I($vO`l3&`SxEg(k|zNE*zzobhBSz+UO@A5DEmxoA3fep55HO-9mz%%PBk(n&% zrBdfvQ*7;>h?XmSKsKmVv0YR)R zE|8ThN6&FYFfr*5U}{VPRGTcxK2+MRA*^&sDAXU3(FSdJz`F{wB;J-L?O>OL$jiEf z!h3nC)f(KT`arB_>K%0sx95=@*ZEDqdt0iWI?r!`o<`3Iizxo)r#kPCHF6ghD4_2c zi}Sw(#(<|2c%u8f<$~@IeZjEbXiFD>=7ld<%a?3PAs#qEP2`+ZY*!Id}oFAuC#osD5Z_^ zdfF(dwM&Y-hn{%X&?kq3W)8m))Qq$y&R#91MzcQ=09Kq51C&g`ynRj z69UQd1^txl`)%0zJ6v5gkeUf54)ov`UL?P>OJv~zG$P!0Hf`u^-gcL#%vVQ?GHSj9dT6}~dis4JN6r>SN2RvZ=(Dm!{KN z%u3|@Y5MalD_4>*O+}rqhDVIAGUYgPTg|UP4`h6ZIjIt0)_++Fvfq z5{!;pz=)~=Dq$yZt@k}(^jRQL#974pYcXfEAH*@EP7YbbaFYQvq3g%#cIk&dR5hB0fiLji8KHFTC&l2PJdk AEdT%j literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/HIP.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/HIP.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9398b3ce2e4b5d63291e597b9a440e957fed2715 GIT binary patch literal 3265 zcmZuzO_STk5uE`*eDGtn+Q=&@QCx79l?p56T}P2@Wg{z&Y$vjlV!3RURbfem;$mjG z;9>!40Is-O;3cb+FZltvg*@hevWn7 z*X$oZdo_2q#@^Ucv7_GPuA(-GP>(@Q+b8~O?Ez{e5$MlV5@AjQPFkuP%856d2 zM&8IjxBG$MU$d_B9Nt(jCi(KBH_=rbKuAX3;hFbs@*y127&?9DTXw*OE4*iZzacJ( zrf5CmeOG$oEzuU8XZ)P^eX%Vz#0BUB=r4;+anb0T;)>W3KZ3sXEpu4Ejdfhr_WjSl z9DKwXLmw&`=Sno2A+C>;lYt5klX5RC4`q0m7iE|TnUzU-8kU1$ZB(9)@r;a$QYG0^ zYo-p;VXl($@VIs`p6sVd93IKjFjlAIG9RkJ_z;?v-I~XhZZAx-a&0}B{<^!hY3At< z7E(xcB2`h(Q!*3s>?EHQ;Znage`T2__}cs+6j`y84UXkb4M=~ypdO{)PUij7T zKM8N$c>k8R5d$5pmaT0pMSDwsv1by?81$*)GgJ{lIg2+H`hJj^p1?ba@f z-QV^8ybBENj8B!1m;VB-Ftp-Z+%>C6#|k&AmzaDhM>eM8tYcgSYmG{jT?Q}%d!=2zZ4sQh`e4(Nh&_T=_MR<Da8lo|88y>OB`;?vY1;5NbWHVRz@YF&05%vRTn}Qznz5_j2^E(KpnWCE) zJdCNQixOcHioV!}sMzC;8L#-9E!Z~oxM%L!|YN{%bh!E9uLyu?#{~eta*JBUN7*!UUWCKzn^4- zB2E(R9m;8%9Gse@Ygd5cLTYz^P{R|tan=&Jn!404y$LS!J20+>!jK|=Mz8D|o zc_AYu(?OY>paN(+m6>)%d6F5_bpu6N)GjDLOfubkX?iBLb@a4G93fLX^Z`rvH9uba ze(f#4@&d}`BvpVyQsyVt) zISXsns#^0+!i^zuFuz!}4EDZw2s{uLD-T5WtKi%P7VO^h|6zT^hzDVr=V6*>!|ql; z7|Jr5pyb_Fgd`nIvSs@EO?p(p={#T%^XKl#rgR*TzUaXVYuY zq8L2hnz@xb_bY6`mA$Y*;6FXYmXEYqy));Xd-v`G?G*YoR5zYts{^f&ph;Y6XFQ0H z>aY+v4WyqYN_M@PCeA^UO6|w_@mR^CFrm~|dWd%P#*lpoFFmw^Dg@(A{H~awwZG>A zyeySZhs z?^IrGQ+aDP!J17A-h-u0KsI1cd-@H$+F;thOM66>+(uyWrg|Q+=aDt*%r>CgSkB!r z{;}yD1?pc_XO4t`wVkRx_o@yh>q)iZRTHdgRc*s7XPKbq29Z>uyS}=GPP>zgazg!6 z96VGPN<~}n68IFn8q5aq7t}AwV1@X;Lk8N5CkiKsvfoew1+b<7Rp~m{zoF5qJTTep zH{wYl#p^uyEzBRH6+eeymWz}U`Y)|X2Z_FfMtUFpE1WP1r`OR%%%f&FaT5cC-k!b- zOfz8m$4IS%P1T$-Ft$+;9TUhl0!e3%8sRu$*rqtIvAc?hCCo#eiX&YZr eXFPttoO(oy(f*w}5_f4kENGDi5GbAa+5ZRjjsmj) literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/ISDN.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/ISDN.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36848aa98c205702955237000c2bcaf3fdd82509 GIT binary patch literal 2315 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 n5Ung1SQesSRo}p}@uxc_XT@R) zC1p2}GB07B^?Xmt$90sA6H7`cV<|sKZQ`YU^4v!QlOF+;UGs@?qQHqr_YFSM}6rZC5@ a>4z(v4#xkJHq6GIoqe|X%K7Z?8U71HZCeKb literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/NS.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/NS.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..06c52c7c8393b56c8d7d305f69b0697d094d4e55 GIT binary patch literal 381 zcmYLEu}Z{15Z&y?OFTS~1ADO$Qd}0aIuJRpvD+qWf{tNLHBk1OW&*Ig!pa0SfGm0MkxJ zGnTopOzwdbk-+^%9T7>7yKs=KFzq3NMn4cq!I2CoI#@?V^t>;k<60+W4I*$mUnvt8 zTB&ZTR8hhv@A-jJPn$R&C!SJJCQ5yf+QYpA{49A>RJ=;7MQUsl=lS9+J?f`Nm;Biiz4w8@`5dRfV}6=v=A>m%^S~oAbh9VGubRilvSsyPF?%d`Mx@S&}u~t zY4)d^AO3lRv42wIGC8Q+M=pN@A(-GpmeeIrEYr4^rL!zuQ(8ms$WMIEe#wL_oTp4U znKcLo;klhefx#J#HMJ97W5(X*TsrhHTpOi<#Mc9@MKaj$p6^ z@3h^@EhpnlN}5*%X_}96m8O!GlC&m9IAu2MSH2XzVYe(RPYOEtGedY4rm5*n)4#DV zf3~ZR#=GNu{8BzDRd+ai>306g;Elumau;?RpQ?jmM77;|p>p@M(X!h-RG zPQ@h0nJ)qoPe?GdzvS_m^YQHCS-W9OT&?#GilWR?nGL%tf1ImRb1~AwjLIHnqsr@! z$Jt0!HjG+@Qgl_9Zm9BAkt*^QXHeuA)-U8ySGAjxcC5TY=KD}bmkXa|m34ShZ|azN zUhQR-SG#WIpe!q%qjIXUiVq~+KrLES+kyBAa!D1&SGdF1kT-dNvdJSJ^DTbXH21kY zT+duIMqfjw+kYFmybDWcd(IYY=4lUCYRoqCaDDzXL65aya~r(@F2z|e`SN>AxdU(R z>tFz*<3dBh4=wpVwBbAw)`EY+>B0^j*!A^y)048Cz_&rq_gznd?-dy`k4du+89jExmq&iBNCcV-Fa$-ekw0;e`KlWzERx zwWn9k9XMCiF|KvCYB=sBR|mvC@yq#FUom!e{hQji;@9rndF4(S!|?wv$#sm7s}L9D zyK)Vpy;24HnM#QeCEa3Wqge%$QC9Z4<1A_AWttVkw2&zJa*HNz)3~rNi=)~_-N)VG zB&)(~+RMf&FGf}4;ps?qr|(EvNO_%xJ7pnN6_W3DrR<)zuT^$$SjvzVBp#@2RUFE1 zQS;j*h{X~R7onl7Ty$om#2+mQ?7K9>D|#wZWzrnW9Oqkh#Wb7fFNsFkNqPx`qTeqw zC4WE@Z5Z@<_iv-)4dn7&2xbLvd52q&0ptoK)taW}pvOVW0Vt@K>H)w(8miH6#{yVZ z3|OuV)w_Hy2{!cM1}?us<&ygZfU~eUo4&eaz8{16oSCcn+*Z!qg-bfh({Sm9O-@OA za1ycC4mgS)2CH*sfA7JAwqKJ0@yJOoGh>m;J&`%U@8MmV^uR6SZtqZT;s9;0CKjik z53?%h6-Q&4m1TV&WNaCec#bmeK=%=HNuO5toX)EgQkaA=hZrHgq_mg7A$-VuJigYanw?9{-Te_4(J5q-jyORM3BSAxzr z_ZAFv(j?9DbPY2%1bIceSyRRFtAM&E*kLID1yaI`15)#sFvnYEU>?>mzp!D7+EHRv z6mfX~oX8(Sc@b03>RwmG2J^MEU(nNWwsobg**(Tnvab%>p#do348VDbP;>dj>q+=7 z-jEuSx6rP<$>>CO#|EDUbM2PgMaS2eOdOhB`Mrsh*+?a>6xgVC3WHC#Hz_kwziGxx zZqxjj#B;8454t{b`62|fzGFaA1E>ZTy)iX(ns6ejZ6HVA0FiMhG8iQ)=@7=D$cHaM zL=h9>q#6#0lPrS-!)|TcxcM_Q^V~6s0)LNOl9?Gl+cF6LuU8x>`(T+78eC`%?>u8N9>_A6gi}N zhSmd3z_2zj5Cld}&dni{Tyn`F$d3u;8pD9j$;lVztDd2xRg9QYS65e8*YtE(eO0qo ztGNun@gJXh@RRQ|_AeUDekPb#(UL!baK^PB^YdQwH8s|KUG;`c$k0g(&Z~x zuU&usg%@92d;N_!Z@%^R&)#|W=f7CLb^E>d@7(?1mrCi|r|$jgzMn7lz3(#Pd*5Z_ zNW*U0XvaUh;F1r)gp3Xu2dv?6bvi0K6kgi2ee+Y+(bOT7allKw%4-ib-wsQBnb-N; zL+w!W%Y215_&nqec8ZrTcNiVBwHskFCO(bLXoS}DW6Qe=+%OnR5hqEM;ZUMDLF-tGlSlG%cjf1R;+cA1tr zt(IEQYW7bZZb3cQH4fTzqZ){zVlC z&kpxR9UFNAEm;6z`hsSwKUb^j#2wUg&DpE2-)++y(XWO^FZ3>2@+C;hCOGk~KGh~h zYJyr*HnFE{j1%vcxVEi}^IRWWaU(5H9FjqY<}GfF?Y-YZ;=aLt{qX~RTpE`*+1T0p zFs*Pit;+JDcBo@+eM~pvKE}qCy;o_DTS|U;T$L4W%jzqDa&aJ?NiD5+=OztV;-w`f zU2ZM0RVJ&eY^qH)jqM!VV>=u7n6v>f<;lEsrrIido{jCDoA-dZ*vkUiBH9vs#gul( zULh}V*Z+-IWnXI-GA0Pxj_BTxJ|@C2{#x@68c&YA;y>}8OrA`d%bC3qB;oa|nX_@_ za^Vf+2*7S&c+v~fFq_9zD;|h`&}*fG)>gQeS-rt-C^DM^u?qjm${SG}B<(25N>J%V zoqgp^LML-ZFN`xg7!JdjX9jLPa|934KqZF~tWv7T%;Bx zb`^aT9fX;_y_>r&-FIdx8+IOncrg|FnTbBhvTUPkMRWhm!lg}Cz|@1Z3>1YufL zt81=i>kZA+s4Zz_^i{|_Z3Xn8mU~{Y=k_dXtYR@m+3RS@UvT2mm@qhzUGydN8pdVx zI(kPs%JrUw>p5^eV`9QR;Bw>$m{nT&n4ED^O3RSDsWWkI(bt5?`~NiK00R+g#9cttMr$|@Vr$$7c_7~@sB z@(NpHG`hidzQS&2&-m=ypCK8+Eg-anKy{=m7Y@q^o7%cKhYJ&Qdzq!&S4Gc3BTvb@ zNWPRryyv2CzG3WO<&5}c@A|cCSFWk51t$LQPoTnM;&CDtk?(;tSAAzQOj{%5-xqv$ z#$LLf^LZW;KZ0iFjN(~bHE3*&5KTgO#H$d+EX8LYsp1D}4MI1M(aeDDtUQXtq#X=H zzZNB}aL{WF1iFrR8rq_%mUP6RpNFIMQP3Nqj0^YL;gG6$a ztk{Eg8m5U~9f}BhE~YM#Mao&e8;85CS?CWsog_@fRa$7^_Rfa!8FDFq9#uKk8jjUGXmX6(yV5Ij1BI?O-kki{mqGQ!PM0I)-Do z_#A^2S-y+X5m`x_=mZCxvKH!rF7kf2B+V%T7u5o0NmB(5t)YNCS))Tw1y!L3(9qc4 zRp>bg*7L|=79eT%1VdVQu6?LY0Xv0lo46g0Y(sg)TtBd$SX+C0?LdEG?Z5!rbj4HH zue!O++C_O9W;Psk)CPbLgZB2>D?TYKN;#C9ov0UP<@TUI6k(Dm=g734pofN6d2Z+M!yZ2~UWz**Z&{3A8GCK3Sd1JI1!!u}lf+*oDc8?r&Lp8OMi2~hrJ zp^qDfzR8_pACB6G1&C&_?iN}|A)jcdGu0``#>xH&-m$|*vBQR1U7wUBpf`u>ozDTc zIh^KTT0sJ+D>$vpyyZwCoFb|iq2jCv1}_~9ykrZoapaM-u@P`Dht)jBkEmieSUnNv zncPDOv6*f)%iWly`fiY?h?@Sl3Ud^^@-A4R_Q6vYlI#62voP~*H9Whdz^37rTPxZ zRJE8-9~X{(g=SiWBSEU_O!ZkK2xBvgQWDC{ez1*HfLd0(NPB#O=FB^9zjn#DZ{5Co z>w~*=^{7OB>wW6f{!U))q)yDrH}V60nE)jr2rMqJ$RA6FS$w3F)h7x*Q!LXkjsF7r C?qt3I literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..153a6316e340cf61acaf6059b49e85e70b3a66b5 GIT binary patch literal 2382 zcmZuz-ESN<5V!Yx_bzFgh88Lz4kSP))J9OLl!8!`QmBMDp|(O|RcW7Y%>zc^SH z2Riql${#>5!e~L_rlm18V=J~z>zLLm+>sZ1l>9`P&73pB9BvQ&VQ^~4A)}8;*L?+^ zNUuwEsQ3$&sN*ruP_-<$B^LP<1ShynY%vP%Ep*A;ffG9~NuM&0`Da1wvTYWz))|dG z?z1bb%{I>HDUAcR!#3F^(1)OZk8QEbMjyQ-4vAZEl&d=GJ$`Wi)~|by_I^oi3ddRv zJA!AGU{Tb8axZ_LicVS#Dv_&$(cO+Z;GKh19;|hpax!|xMPrV4T2I~WQw#Cdgh#uwero4Wm>3aU+kS*(o9Gt@^YZV)jhRq z&ZDEXOYNX-=9?EH1Y3MB8>*p*B8t}J)S6i}t*yC5Np068v1}GcGJtc)ZLi z#swa%>%(bz(bv9US&>SqJ;Cs4-tf{G10R#bm?g(5Z-Z4fmXLhv10VvAW*r`%E$5C+|x&g?mvIt)-A0>(o?c<9wm-?@rNI=%m3 zF?mgIoU}fjbQXWI>zh04;8|X#GRt%AAMh7N-apnJ1KtCG7lH1&0x|=@3jr|5OC1Sb z041O2CtO>HN5-4j0*gjmMq6K12}bxW7)X<0Xhc10i*C}B?Q_>(m}U5&SkM%o?>CoVjzr2IlOUHz&YCf_wyy`E^i- zrygKq_rw+Ou7M|UIN&OoK-k@hqhvu7j)^jRlv|V4-R8E|whSf28zrm+zj)K!>nuMFY5y`x1Ksve;Q1~X@uIZAx>(SS$D|PZ7l1ku{1nt z!P=;?sUu_KGW*bm__l}6(ESr|GaNDus#}Ib&Jv|pCMUrcgmgXe2{hW9l!y+tMxNJ}D_XrxC|uIDdQTP=zSO;L8&hzZj(C#jC`m>Yn-th@C&?d^ zv{=meNy4fO)R0MKQ7H)t8`&tXgU~ILTt^%-Cleo``g0V!IJdD#y%{eGShUI{T`Df2 z5hfJ#DL_vqG=i36wXJp(1r}|$BhR8{z8e|zO|-@v0Qt=o;^GTf3;%?GPOwy^aSOW% o5;Rrj>w!Syg!>2^<8OVGre`u+@LdDI_ZXulwLy@YP;J})17&eJJpcdz literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/OPENPGPKEY.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/OPENPGPKEY.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd1196da798deaac8aeb3453bb1a53ed2a9fa5fc GIT binary patch literal 1711 zcmZ`(OK;mo5Z)yzz9i-08hxNCpdMOOKoS8-;MPV_Bn{jg0;on3Gzd|ErMWAcGDR}G zE88;YOYI^*qtdZ|X|FvM=&iS&I^#2NZ@b-)z&QQ&^B@282>Bfs ztKk6i7^eIR2qTQ)!~Sj7VO_Hy zydw^YLb!2Fhu`mP4|ksJJl}qE^1~(H6Fe;i3&S3a$Jt>bdIx;A)l>T%nPywfDzn<^ z?amaJ&8FmhtM}r&r@b#XA8eYfbQJ^saoQNq9UzJ*T9Y$tZq>B578WJ7U6a^m1bm~z zzN1@mT5%yPIIR6R&WcRMv9`el5IU0QBkc*6=82Tr6%0KREjZk#I*4PlAIHCuzn=`$ zq#9INbuTNVO7i^PgY4mW^I%U7SRt#K+Aj;_28|6lcrtu5xJ<|WY9`S0PhmM54G~+zzu+3u?`nIGEA3AUF4LsqQ8$w@FY~w*@Ee(B z#(1H!Q3loTfQ}CMamp)|m4$Ai&82`2Cc;O^Wsar}0gjgdx#>(aO4QE>3|GJ6vn>F+R3+P*jKHvHW>+zN% literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/PTR.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/PTR.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d26ab8388f0bd247f9b4931c8b3dc6f942509fd8 GIT binary patch literal 384 zcmYLEy-LJD5Z=wkBm@uSz+Nnb6qg096p`~9yC9y8i?GDZqKWx4n=2w%>3dlF20lw# zD__CN*<4Ns=Hr{0Z~hjOiBHg8-Vbg+86jUL*qDuEj;{9+fB?;jpce!zU~dGNqM4Pk z%zkBJ3+R#r_BZNClo;F?MKVX%I|vH)GY?)w7SV*QlgwAPVf>ld_Bp zC1vkRSyZsf4d0gXX%**V#g!7OM9L4+xHx%$pA+5|HLufpmX^AW^L%!g9%aXm_nJeg z>#lvMO2c>qZC5MJ&!ZcTyTiI`ES$1y4mHHHhB$D<6y@P44@-R)YlXL$TDW6UIAhj{ ZmJ6&7jsG{TnTIob?{xjk+4OG>`vq{2Tk`+_ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/RP.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/RP.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d49f954ef3df71d44c1f2d9fda22c58c31f6faf7 GIT binary patch literal 2348 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 P_^HdFHP&l(%QpW5YE?Y3 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/RT.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/RT.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2400538b2434384c87c37e0d52c9109f489f0720 GIT binary patch literal 399 zcmYLEO-sW-5Z&y?HWmv~5Il+pp@$}*r-Dco!IM4I2)YPM%q%rA*{sGg$6>Jm}46};_1gwN`>x=*e_C|n7 zE2c4v?N`Rvz`7tq`y2bnG^}|A3&jM(Y$8dV2f`^>oB_oNR?(UNygu`Hav5ehOow*m z2%&;h3Q_fhNHbU@wcZfoVG$(lOIHZULLoj#-o?EQ{fxaL)t-*@C{m^fl4P_W9mM1N zx$!_5T^4tls+E^RQEF+t#Jl36*ui)x-V>L^W%MG^8^zOH7NT2H zA1>s2i753gns93j5m%39GOITftFww9bc&VKi>lQ5qe8wyd%x}t+O<^qq_`75#JP{E zQvO26-B4UE=Z~b?IPQ9CUY9|XEdm8EPgyGmNLGXm(ZD2rO=}db^W9}@p*l< zIy|QhBX81W7M;~3pDuERE7>s33{C31DqpW}z4WZYd0yu8<@}7sQtm4wxQPjG6xsXbMCaew86dtS7RM94ic2h11 zj|8z=1tdZUEOoRjrZ7Nc#YF4YQ-WCXW7hIEOjENeP5;IIcW1YrFLoFC;-kFOHN5}P zC;9E!?+^C$F4(X*toN&udb`~YdiUP=+g*_M*5XiY;Vd7c>I)Fe+Tq^D?`S}?)>e%l zW@Hx?GKft1Gpha!qG2<3!aGME!+|sF^vM+*E`>X1aPN%XQ6G+-`BVQ2Ino**UH+Ml z=`S|_qrf<$y_oG+m6oZJ1z|6*58vQhPYrOU)&tn~^0JNA3y)-L9X#3aFd40kKy+uV zUsq`@pVnlNHo)QA_*wh{KiVQ!^zSpWpUM!G=G{lt3y8)(VJmj*^{wA{@B^%0Ss3$A z`##=Vm=~b6(T05+_3c*Q4$wL)252(!E#OEn44bIgY6j234uozS?8!Q%u&H)%h9siL zC1`Z}lff%8+F79$9bIihw02z`s7v&CnZ%p1+j;Dz+rp`;=EiZx57(fD zSpg6D06%KiKe%y7Zakfz5l5&HO$bm%!C%k;JbFMi_R1y)tRdAs*KiDgwE-sd!O&T_ z@&G`75;e|>b0p*rVBUv+qB7d*AVoL*1kus}3BjaR%dBpl#Uwj;C1qRpiOOp^ayxW6 z)4Y&vkX7>q5`s1!Y{MyHBced9&pAoG3!@&O_PDwLOl@!CicXVJ7@UuCaz!qszzN1fqA7%uWXi8z5&+VSW;Y@psJ@ycjr8JjzloF$FAfra0q zYC{U^3d}mX*pubuPTBgSh5`;%W7@ybso9Jp2HS!WQLeJTTi4NBS>IX5J_zD8!S5Ju z)NO)K*|GbY+2IdoHwZolwkoj7o;iQxwR_?T>;UsuNHYlwI*-zX|&u z;=Q3BMw&?2I9ntfBV8jsBmL{l&@mXlAQBz*a8n!)FN~loePNRz%#VWBMnrBMVl7ZZ z1R?~qp?sRj1!e3c{Gw9x&y}i_q8nIy`=Wis$wBE1Ur z4h<8>4IdPF(*)yo*k|fY76q1{nla+)Et*7$$9z6qM@Q482A3Rbz&&fQ75Nq)Y)5|N zq1`dFkP`_E$&kKtPqCtI(pX4iN=)hrKKlEQYytuexDTi?DqfzU>zULSeAfBk59C-) Lp*S!hJh1-{L%R#` literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/SPF.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/SPF.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..60fee90ae4670589ed1f37dba25cade23da24840 GIT binary patch literal 407 zcmYLEO-sW-5Z%p26M_X%yh`vO^w37M2Q4D8LcJBSJ?J7Vv9oAnKGtjsR`8_%!?XX! zbFQBJ3!a>98+|a3H{Ub8M#CeBm-pS9Pe#a>acbBoLNvXD1O#Y8I6Ws|0ed6BB#o_@ z#r7-XD?o>&X@6rK8H^3rpeRB#y^bWY9|*UAat0Q5u!;>Y`p?@)ej&$s0iNe0LM>(2 zzwDp+ozC9jplMgG5LuK;Au3OZG>2(o^qLTl(13e-fk zCYdgyBx&tW4&tMSI~_o#)vUbFGoyk6%9)ZnI2~LEcu!l+3Ja%fnd6Oc?YZAv<(pXE tUY57Zr}8$^5+BMmca~A^)M00IHR@r0-ur*nLb*7$a*r49oNWAUV!y#LVUPd- literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/SSHFP.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/SSHFP.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89122e87f117f4007c5f10fb6839a6fbc0775684 GIT binary patch literal 2176 zcmZuyOK%%D5GMD%D=81>(WaLwho%)8+eO-&nfdtXNv{_X_-23H`{{XykiT$n z_Bo(Dh9)0^V1&_v#BEPwYQ|P^cisbV6f~`)rMMSoee;(>P!^SdU$S z`4HxBva9TxnU7u(hr}H?`<8aMx4-@R>CxY&>kFP$f<;juzQ_5?RP@tgT!~!m>}~bc z4nH5ZChD-hFt^puOLf6_R3~WAda``XrRw9v1>cp)CC|JZb5RSJZM{e56BoVDXSe!N zf%&*yl^jlGA|0vqoU75gK;NuN-pmey3OZ&?^=+1>hGSB3n5bUuUHZ=Jj z2t^ca$gwrI8roP3i;~7}NMbh*NT+c@x{N?>>2Tm_S59j#gawW|NRqtFRgwtYOyI7< z1p#J`-D^pDlLlj2lR znX-oez|mxIB@V}2B~yU?Lv4eqgK5cSmexG(A0%dBEtJCh1B8vLA>sm$_Rhtm==UqI>y z9c^cY6d~*?kpHx;s$H>$!y7180M=exP)(Jo*X4qQBT?;{l6(Yy@+}a=3TOaDv1k{1 z3tB*LLW!VASKA`3e6lkh#Akxdl<7Vwip;42parnA7xv6)=-g=>OuNwljHsKJXbq3- zyHB3LJM(}frkT=Coo2fiqHyrhrTOKw-dtArwd$e`!2a2?4UsLo$dF~a z$CE@yNwQb5X@Pn-NnT9TV!7fc39B-g1}>CEr6lkvCR5x3p*w~i_c(AL6Yt26SzSN!0IXLd*P>>95SSc_x4|S1fx0#f qbD2jN_f}&=;n&f|{Q;TH_?{ozYKFFgM{Tg5;h~1N;8EZ+vHt@F9TWcm literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/TLSA.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/TLSA.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13a53f76247d836f5c1018df3682c25cb6e956ae GIT binary patch literal 2307 zcmZuyOK%)S5bmDodF;#Ng&`6`3nGaYNDKr8Cm@tK0fay+lvqNHB8`UW-u0|!XExov z@k6r+VWXV*4eTEIN%WPI&)hgs)w6aSC%x|KS5;4S)mNW4I-MqgHv9AH^Up38y)U>XAm&uARuWBa7T`2zR)9NVqH9kvH-W+$iAm5$UlbuqOQ!<#EHC zv8l%(1i{-Phf}x>?%<4jLl&`TWI(ykgTpZL_yykNtwS35BH$N!n|BWB0gXa_iLdb2 zV7~$Tuk&;Kyxng;BaB2X`1-10o8LdWm%L92!AVz&w3NKr>_WSnJxyeHs*<6&)7{(> z-Bd`O4YD-RqTa66^xkB-zSGSLeacpeT%@{`wfXU?JIF-NPuU(HoHZZg&9&{daiY_$ ztQdB2@7haOELC6pJo>vdzkka0drFmQmguZ3x(^baynI`2sI-I+)_y7hjy(MOe)ra` z+v~=&K{4U6i z(}-iM7RP^)|2|*SNdwQ!ZaJE)osn+iGe_BJp z+?edi5Wfyx*;;WfP~ZOcJ67S?=l*7jUSmVY(dawq>OBw~!ZISzadfmhVj~E~$Va^Y z;SAU+hJ*F@TUU5@`KOM41;ZY^Bi))7+bY`^z2MAKjSDUtPjX0d6vSI%HyiBL!D6xj z=Eg5&Hp~jslp+T}JcV0~v%Moba9E2KR10(&Yq6_8hDH5Kcp-ydlkT_eE0+o>W&&Fq zI_CdAboC2}%AJ!1nfc2xSdQV4%o@9QU_}>X?tn(KYR=sSk)QrRV8#|iJGr%+wQyDu#1|kbsKTms;6w17{=eV^>8(VK zq0sRZ3T556Fg4+{5GqY3BI;x+7G)ln5{7|YW?U3l@_@keU~U>>Hx(1C9MgKVSLkH- zD=AB9{A4l_1vlQ)B%cc7iy|$#FlT+9N#N{OvFCsi@VP(a2stwgPiD$Fa7|3#L^Ms77-U30Kkm8R~hqhsK?CKKa4KlZ4 zGk0Q?A}q0CNnsvs?mmKvCUa^b>HsLAVn=MjW~`!fuVR=7I|I1l+*YpB-)HY^Y-~VH z`oJR7R2w!)((N;^GTx5Nw5Sp3)re$+EEgtB%ke}CrEEluza6NJh_}h4jO?^9K3dxl9($EWp)g1Rm&dXPwMEASuwOyjsJ8G+aU~ z;O=Eo1)N#wfebC&{AB=+Y#QO83pug^X{_hUt1uXUT3}3Y+>yzo*O2eR_H#r;4BaF0+0*|vb9Ghkw zk4rwyao&#OC(|Tfo&<5s%M`YOK~-LA1$>NbCRah2mL=7(0LJ9<3T}Uh;wGMTmXw={ zJO`tbZ1$)`zL3Z@mgz6UL|p(8wwcp*+F>&Q{GMxi4z=gK(1uWUK_zMc$=$FVXKOU- loUAST<28}@5INA=KL2bzvji7@Q9t%e)K>T!s2Z#t_kYBJE>i#i literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/TXT.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/TXT.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b57601bc05f41f2d9ab49f31196b49b5f188df12 GIT binary patch literal 387 zcmYLEy-LJD5Z=v36M_e#*o%db;_rM%j>3dlF48BQP zD__CNNiNZW`S|AVo0<7!;t{l$_ru#yM#xtejAkR5q3Z(#AV4!B=p_LQ*c$<+XlkV_ zwO^Uo0D47y`y2a67$G4<>T1MGWaioMYmhywt4l4KXbIMI#@hYjNNuf=YWz(bNI6Zm1*BlC6 zHRho#I>u`-O{Fxy2yZy<4yvZMP-U+>v?H$7$Nr|+#r9xm56rWE1WUy apwt}e{p|l)Yv!VC>z=LOIp6u)#C`$Rm0ffI literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/URI.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/URI.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f501e6df29a728da8ab1d8df65a5902ec929fabc GIT binary patch literal 2296 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 A#Q*>R literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/ANY/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e7d360646955a1f1f9dee15ca0d3201e56a951fd GIT binary patch literal 579 zcmb_Z+iuf95OsWMN+4Xy{ca!>^3Ymp3jzrNuI(fi$=dR|RWd?aMLAY5q>dGvhamAS zJo8I=#d z3~Zr^ZJa|3=WzjTT*M_@#ue<~Dz4!=Zr~e4b>4&?2}>lxO+^Red>_r*fupCm+=qY zL}o50-SMKB42RhxPZFOnX>*6CWVm%{>#tdrUc)=_k6zXE@`&_)7|7bdXT5;5fgh6Y zbC;1e3>;ENV^WzM&$#E1QQ;xAY6|Vh9#Ja@Jr?%E`XON)ks5_$L=pGbGN9b$-dPxV{2C8=?Tkjg2>5kg=No7Altv-n<_+G2{Tkoln|uqj zI#}%TOZ>96*x)z#6@C@=8*hk9q9#Oh)6nkp&u&YKq>#KdC}iu&VZTth(DfFKN9n7+ zZ1G~$PxFT@eJGZCs~Ff-pK~dcs%-Vicy<1;#dFok`yQo1FH9axdr z`=zfH$J^)dYA(>M|yI?byQ^Y!C1GbGgS#RpyQmtD> z+pz(g%gJF;C=pAM^>z9x)hA1=G5}x3FJyX<=BB z4TN!YaU?f!xrJg~?+V&EzS=+*Ba84euv4}lu#h(37t-lQx3fM^EP60Plxw74z~a0( zrL%A-(QNKOiOA5!VwH660YNE+E>abXef+HLSCzu_zD}huzS44%XycCi$&sy=@m|YR zi?&x4%^jqfFkw=R#&{zww#Ws2@D3!o3n6_8b4jyH=LN%mO7JG&z~>sqO<1g8Ea*i5 zI~RiXs-T+?G*1r%kbgfD@&>#s(LqHrX5+1L|9>*c55edgm`ftn>2%8y>D*a@1jT`c zK;6>m7!*y06v*RnyyxByG~`|K8@mCk1$)V6!7POR@IINj+L^oDc7+md%8s=H8#=3% zA+AgB$dNC=pEvY>rKQiwQB4lZU=9>qAW17i*2-W-NKDlfs|GZKi)~zFqp7HaIkhP; z{v^lZnVL9G#8{_A9@V}tK3QqPyOhm9Hk0(LgBCu26_*wo{ARPafL zdLxd1ne?;eNf5`pNMIZKu*wRppo3%Ik(WW34cnSW0{SkOJGhNEz>-a3l5DFm&1DNu zM3%wpYY1&Bk!upWo&8E+h152P(05tL8eZLHv=P*+=Z3Xu2hkP$04_UxXLO9cO197k rUWW+2CioFikzXA}{!cF+qY0+y{Ld@RHrnvp3jB9iPJ2N@8nXWYw@>aB literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/CH/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/CH/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88deb72550ce6915fdfadcdc61408fa7035d9e1a GIT binary patch literal 209 zcmZ?b<>g`kg4+3NF|(N&7#@Q-Fu(|8H~?`mACO34h+;@#OlOQ@OkoOU&}6QXan4CB zE>>{%P$)`CEJ;)-sVqoUNCt_e7VF(&boA3?y2TzJpOT*(9}i+A=H$f3uVg4<0U8D- ze%a}l}@`?*8OEU8FKrH>D6p-P?`pzEu@$s2? dnI-Y@dIgoYIBatBQ%ZAE?Sw#%WC9W_%m6^+ID!BG literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/A.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/A.py new file mode 100644 index 0000000..8998982 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/A.py @@ -0,0 +1,54 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.exception +import dns.ipv4 +import dns.rdata +import dns.tokenizer + + +class A(dns.rdata.Rdata): + + """A record. + + @ivar address: an IPv4 address + @type address: string (in the standard "dotted quad" format)""" + + __slots__ = ['address'] + + def __init__(self, rdclass, rdtype, address): + super(A, self).__init__(rdclass, rdtype) + # check that it's OK + dns.ipv4.inet_aton(address) + self.address = address + + def to_text(self, origin=None, relativize=True, **kw): + return self.address + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + address = tok.get_identifier() + tok.get_eol() + return cls(rdclass, rdtype, address) + + def to_wire(self, file, compress=None, origin=None): + file.write(dns.ipv4.inet_aton(self.address)) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + address = dns.ipv4.inet_ntoa(wire[current: current + rdlen]) + return cls(rdclass, rdtype, address) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/AAAA.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/AAAA.py new file mode 100644 index 0000000..a77c5bf --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/AAAA.py @@ -0,0 +1,55 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.exception +import dns.inet +import dns.rdata +import dns.tokenizer + + +class AAAA(dns.rdata.Rdata): + + """AAAA record. + + @ivar address: an IPv6 address + @type address: string (in the standard IPv6 format)""" + + __slots__ = ['address'] + + def __init__(self, rdclass, rdtype, address): + super(AAAA, self).__init__(rdclass, rdtype) + # check that it's OK + dns.inet.inet_pton(dns.inet.AF_INET6, address) + self.address = address + + def to_text(self, origin=None, relativize=True, **kw): + return self.address + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + address = tok.get_identifier() + tok.get_eol() + return cls(rdclass, rdtype, address) + + def to_wire(self, file, compress=None, origin=None): + file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.address)) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + address = dns.inet.inet_ntop(dns.inet.AF_INET6, + wire[current: current + rdlen]) + return cls(rdclass, rdtype, address) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/APL.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/APL.py new file mode 100644 index 0000000..48faf88 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/APL.py @@ -0,0 +1,165 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import binascii +import codecs +import struct + +import dns.exception +import dns.inet +import dns.rdata +import dns.tokenizer +from dns._compat import xrange, maybe_chr + + +class APLItem(object): + + """An APL list item. + + @ivar family: the address family (IANA address family registry) + @type family: int + @ivar negation: is this item negated? + @type negation: bool + @ivar address: the address + @type address: string + @ivar prefix: the prefix length + @type prefix: int + """ + + __slots__ = ['family', 'negation', 'address', 'prefix'] + + def __init__(self, family, negation, address, prefix): + self.family = family + self.negation = negation + self.address = address + self.prefix = prefix + + def __str__(self): + if self.negation: + return "!%d:%s/%s" % (self.family, self.address, self.prefix) + else: + return "%d:%s/%s" % (self.family, self.address, self.prefix) + + def to_wire(self, file): + if self.family == 1: + address = dns.inet.inet_pton(dns.inet.AF_INET, self.address) + elif self.family == 2: + address = dns.inet.inet_pton(dns.inet.AF_INET6, self.address) + else: + address = binascii.unhexlify(self.address) + # + # Truncate least significant zero bytes. + # + last = 0 + for i in xrange(len(address) - 1, -1, -1): + if address[i] != maybe_chr(0): + last = i + 1 + break + address = address[0: last] + l = len(address) + assert l < 128 + if self.negation: + l |= 0x80 + header = struct.pack('!HBB', self.family, self.prefix, l) + file.write(header) + file.write(address) + + +class APL(dns.rdata.Rdata): + + """APL record. + + @ivar items: a list of APL items + @type items: list of APL_Item + @see: RFC 3123""" + + __slots__ = ['items'] + + def __init__(self, rdclass, rdtype, items): + super(APL, self).__init__(rdclass, rdtype) + self.items = items + + def to_text(self, origin=None, relativize=True, **kw): + return ' '.join(map(str, self.items)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + items = [] + while 1: + token = tok.get().unescape() + if token.is_eol_or_eof(): + break + item = token.value + if item[0] == '!': + negation = True + item = item[1:] + else: + negation = False + (family, rest) = item.split(':', 1) + family = int(family) + (address, prefix) = rest.split('/', 1) + prefix = int(prefix) + item = APLItem(family, negation, address, prefix) + items.append(item) + + return cls(rdclass, rdtype, items) + + def to_wire(self, file, compress=None, origin=None): + for item in self.items: + item.to_wire(file) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + + items = [] + while 1: + if rdlen == 0: + break + if rdlen < 4: + raise dns.exception.FormError + header = struct.unpack('!HBB', wire[current: current + 4]) + afdlen = header[2] + if afdlen > 127: + negation = True + afdlen -= 128 + else: + negation = False + current += 4 + rdlen -= 4 + if rdlen < afdlen: + raise dns.exception.FormError + address = wire[current: current + afdlen].unwrap() + l = len(address) + if header[0] == 1: + if l < 4: + address += b'\x00' * (4 - l) + address = dns.inet.inet_ntop(dns.inet.AF_INET, address) + elif header[0] == 2: + if l < 16: + address += b'\x00' * (16 - l) + address = dns.inet.inet_ntop(dns.inet.AF_INET6, address) + else: + # + # This isn't really right according to the RFC, but it + # seems better than throwing an exception + # + address = codecs.encode(address, 'hex_codec') + current += afdlen + rdlen -= afdlen + item = APLItem(header[0], negation, address, header[1]) + items.append(item) + return cls(rdclass, rdtype, items) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/DHCID.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/DHCID.py new file mode 100644 index 0000000..cec6459 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/DHCID.py @@ -0,0 +1,61 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import base64 + +import dns.exception + + +class DHCID(dns.rdata.Rdata): + + """DHCID record + + @ivar data: the data (the content of the RR is opaque as far as the + DNS is concerned) + @type data: string + @see: RFC 4701""" + + __slots__ = ['data'] + + def __init__(self, rdclass, rdtype, data): + super(DHCID, self).__init__(rdclass, rdtype) + self.data = data + + def to_text(self, origin=None, relativize=True, **kw): + return dns.rdata._base64ify(self.data) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + data = base64.b64decode(b64) + return cls(rdclass, rdtype, data) + + def to_wire(self, file, compress=None, origin=None): + file.write(self.data) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + data = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, data) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/IPSECKEY.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/IPSECKEY.py new file mode 100644 index 0000000..8f49ba1 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/IPSECKEY.py @@ -0,0 +1,150 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2006, 2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct +import base64 + +import dns.exception +import dns.inet +import dns.name + + +class IPSECKEY(dns.rdata.Rdata): + + """IPSECKEY record + + @ivar precedence: the precedence for this key data + @type precedence: int + @ivar gateway_type: the gateway type + @type gateway_type: int + @ivar algorithm: the algorithm to use + @type algorithm: int + @ivar gateway: the public key + @type gateway: None, IPv4 address, IPV6 address, or domain name + @ivar key: the public key + @type key: string + @see: RFC 4025""" + + __slots__ = ['precedence', 'gateway_type', 'algorithm', 'gateway', 'key'] + + def __init__(self, rdclass, rdtype, precedence, gateway_type, algorithm, + gateway, key): + super(IPSECKEY, self).__init__(rdclass, rdtype) + if gateway_type == 0: + if gateway != '.' and gateway is not None: + raise SyntaxError('invalid gateway for gateway type 0') + gateway = None + elif gateway_type == 1: + # check that it's OK + dns.inet.inet_pton(dns.inet.AF_INET, gateway) + elif gateway_type == 2: + # check that it's OK + dns.inet.inet_pton(dns.inet.AF_INET6, gateway) + elif gateway_type == 3: + pass + else: + raise SyntaxError( + 'invalid IPSECKEY gateway type: %d' % gateway_type) + self.precedence = precedence + self.gateway_type = gateway_type + self.algorithm = algorithm + self.gateway = gateway + self.key = key + + def to_text(self, origin=None, relativize=True, **kw): + if self.gateway_type == 0: + gateway = '.' + elif self.gateway_type == 1: + gateway = self.gateway + elif self.gateway_type == 2: + gateway = self.gateway + elif self.gateway_type == 3: + gateway = str(self.gateway.choose_relativity(origin, relativize)) + else: + raise ValueError('invalid gateway type') + return '%d %d %d %s %s' % (self.precedence, self.gateway_type, + self.algorithm, gateway, + dns.rdata._base64ify(self.key)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + precedence = tok.get_uint8() + gateway_type = tok.get_uint8() + algorithm = tok.get_uint8() + if gateway_type == 3: + gateway = tok.get_name().choose_relativity(origin, relativize) + else: + gateway = tok.get_string() + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + key = base64.b64decode(b64) + return cls(rdclass, rdtype, precedence, gateway_type, algorithm, + gateway, key) + + def to_wire(self, file, compress=None, origin=None): + header = struct.pack("!BBB", self.precedence, self.gateway_type, + self.algorithm) + file.write(header) + if self.gateway_type == 0: + pass + elif self.gateway_type == 1: + file.write(dns.inet.inet_pton(dns.inet.AF_INET, self.gateway)) + elif self.gateway_type == 2: + file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.gateway)) + elif self.gateway_type == 3: + self.gateway.to_wire(file, None, origin) + else: + raise ValueError('invalid gateway type') + file.write(self.key) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + if rdlen < 3: + raise dns.exception.FormError + header = struct.unpack('!BBB', wire[current: current + 3]) + gateway_type = header[1] + current += 3 + rdlen -= 3 + if gateway_type == 0: + gateway = None + elif gateway_type == 1: + gateway = dns.inet.inet_ntop(dns.inet.AF_INET, + wire[current: current + 4]) + current += 4 + rdlen -= 4 + elif gateway_type == 2: + gateway = dns.inet.inet_ntop(dns.inet.AF_INET6, + wire[current: current + 16]) + current += 16 + rdlen -= 16 + elif gateway_type == 3: + (gateway, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + current += cused + rdlen -= cused + else: + raise dns.exception.FormError('invalid IPSECKEY gateway type') + key = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, header[0], gateway_type, header[2], + gateway, key) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/KX.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/KX.py new file mode 100644 index 0000000..1318a58 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/KX.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.mxbase + + +class KX(dns.rdtypes.mxbase.UncompressedMX): + + """KX record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/NAPTR.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/NAPTR.py new file mode 100644 index 0000000..32fa474 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/NAPTR.py @@ -0,0 +1,127 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.name +import dns.rdata +from dns._compat import xrange, text_type + + +def _write_string(file, s): + l = len(s) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(s) + + +def _sanitize(value): + if isinstance(value, text_type): + return value.encode() + return value + + +class NAPTR(dns.rdata.Rdata): + + """NAPTR record + + @ivar order: order + @type order: int + @ivar preference: preference + @type preference: int + @ivar flags: flags + @type flags: string + @ivar service: service + @type service: string + @ivar regexp: regular expression + @type regexp: string + @ivar replacement: replacement name + @type replacement: dns.name.Name object + @see: RFC 3403""" + + __slots__ = ['order', 'preference', 'flags', 'service', 'regexp', + 'replacement'] + + def __init__(self, rdclass, rdtype, order, preference, flags, service, + regexp, replacement): + super(NAPTR, self).__init__(rdclass, rdtype) + self.flags = _sanitize(flags) + self.service = _sanitize(service) + self.regexp = _sanitize(regexp) + self.order = order + self.preference = preference + self.replacement = replacement + + def to_text(self, origin=None, relativize=True, **kw): + replacement = self.replacement.choose_relativity(origin, relativize) + return '%d %d "%s" "%s" "%s" %s' % \ + (self.order, self.preference, + dns.rdata._escapify(self.flags), + dns.rdata._escapify(self.service), + dns.rdata._escapify(self.regexp), + replacement) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + order = tok.get_uint16() + preference = tok.get_uint16() + flags = tok.get_string() + service = tok.get_string() + regexp = tok.get_string() + replacement = tok.get_name() + replacement = replacement.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, order, preference, flags, service, + regexp, replacement) + + def to_wire(self, file, compress=None, origin=None): + two_ints = struct.pack("!HH", self.order, self.preference) + file.write(two_ints) + _write_string(file, self.flags) + _write_string(file, self.service) + _write_string(file, self.regexp) + self.replacement.to_wire(file, compress, origin) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (order, preference) = struct.unpack('!HH', wire[current: current + 4]) + current += 4 + rdlen -= 4 + strings = [] + for i in xrange(3): + l = wire[current] + current += 1 + rdlen -= 1 + if l > rdlen or rdlen < 0: + raise dns.exception.FormError + s = wire[current: current + l].unwrap() + current += l + rdlen -= l + strings.append(s) + (replacement, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if origin is not None: + replacement = replacement.relativize(origin) + return cls(rdclass, rdtype, order, preference, strings[0], strings[1], + strings[2], replacement) + + def choose_relativity(self, origin=None, relativize=True): + self.replacement = self.replacement.choose_relativity(origin, + relativize) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/NSAP.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/NSAP.py new file mode 100644 index 0000000..336befc --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/NSAP.py @@ -0,0 +1,60 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import binascii + +import dns.exception +import dns.rdata +import dns.tokenizer + + +class NSAP(dns.rdata.Rdata): + + """NSAP record. + + @ivar address: a NASP + @type address: string + @see: RFC 1706""" + + __slots__ = ['address'] + + def __init__(self, rdclass, rdtype, address): + super(NSAP, self).__init__(rdclass, rdtype) + self.address = address + + def to_text(self, origin=None, relativize=True, **kw): + return "0x%s" % binascii.hexlify(self.address).decode() + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + address = tok.get_string() + tok.get_eol() + if address[0:2] != '0x': + raise dns.exception.SyntaxError('string does not start with 0x') + address = address[2:].replace('.', '') + if len(address) % 2 != 0: + raise dns.exception.SyntaxError('hexstring has odd length') + address = binascii.unhexlify(address.encode()) + return cls(rdclass, rdtype, address) + + def to_wire(self, file, compress=None, origin=None): + file.write(self.address) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + address = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, address) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/NSAP_PTR.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/NSAP_PTR.py new file mode 100644 index 0000000..a5b66c8 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/NSAP_PTR.py @@ -0,0 +1,23 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import dns.rdtypes.nsbase + + +class NSAP_PTR(dns.rdtypes.nsbase.UncompressedNS): + + """NSAP-PTR record""" diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/PX.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/PX.py new file mode 100644 index 0000000..2dbaee6 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/PX.py @@ -0,0 +1,89 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.name + + +class PX(dns.rdata.Rdata): + + """PX record. + + @ivar preference: the preference value + @type preference: int + @ivar map822: the map822 name + @type map822: dns.name.Name object + @ivar mapx400: the mapx400 name + @type mapx400: dns.name.Name object + @see: RFC 2163""" + + __slots__ = ['preference', 'map822', 'mapx400'] + + def __init__(self, rdclass, rdtype, preference, map822, mapx400): + super(PX, self).__init__(rdclass, rdtype) + self.preference = preference + self.map822 = map822 + self.mapx400 = mapx400 + + def to_text(self, origin=None, relativize=True, **kw): + map822 = self.map822.choose_relativity(origin, relativize) + mapx400 = self.mapx400.choose_relativity(origin, relativize) + return '%d %s %s' % (self.preference, map822, mapx400) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + preference = tok.get_uint16() + map822 = tok.get_name() + map822 = map822.choose_relativity(origin, relativize) + mapx400 = tok.get_name(None) + mapx400 = mapx400.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, preference, map822, mapx400) + + def to_wire(self, file, compress=None, origin=None): + pref = struct.pack("!H", self.preference) + file.write(pref) + self.map822.to_wire(file, None, origin) + self.mapx400.to_wire(file, None, origin) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (preference, ) = struct.unpack('!H', wire[current: current + 2]) + current += 2 + rdlen -= 2 + (map822, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused > rdlen: + raise dns.exception.FormError + current += cused + rdlen -= cused + if origin is not None: + map822 = map822.relativize(origin) + (mapx400, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if origin is not None: + mapx400 = mapx400.relativize(origin) + return cls(rdclass, rdtype, preference, map822, mapx400) + + def choose_relativity(self, origin=None, relativize=True): + self.map822 = self.map822.choose_relativity(origin, relativize) + self.mapx400 = self.mapx400.choose_relativity(origin, relativize) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/SRV.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/SRV.py new file mode 100644 index 0000000..b2c1bc9 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/SRV.py @@ -0,0 +1,83 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct + +import dns.exception +import dns.rdata +import dns.name + + +class SRV(dns.rdata.Rdata): + + """SRV record + + @ivar priority: the priority + @type priority: int + @ivar weight: the weight + @type weight: int + @ivar port: the port of the service + @type port: int + @ivar target: the target host + @type target: dns.name.Name object + @see: RFC 2782""" + + __slots__ = ['priority', 'weight', 'port', 'target'] + + def __init__(self, rdclass, rdtype, priority, weight, port, target): + super(SRV, self).__init__(rdclass, rdtype) + self.priority = priority + self.weight = weight + self.port = port + self.target = target + + def to_text(self, origin=None, relativize=True, **kw): + target = self.target.choose_relativity(origin, relativize) + return '%d %d %d %s' % (self.priority, self.weight, self.port, + target) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + priority = tok.get_uint16() + weight = tok.get_uint16() + port = tok.get_uint16() + target = tok.get_name(None) + target = target.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, priority, weight, port, target) + + def to_wire(self, file, compress=None, origin=None): + three_ints = struct.pack("!HHH", self.priority, self.weight, self.port) + file.write(three_ints) + self.target.to_wire(file, compress, origin) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (priority, weight, port) = struct.unpack('!HHH', + wire[current: current + 6]) + current += 6 + rdlen -= 6 + (target, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if origin is not None: + target = target.relativize(origin) + return cls(rdclass, rdtype, priority, weight, port, target) + + def choose_relativity(self, origin=None, relativize=True): + self.target = self.target.choose_relativity(origin, relativize) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/WKS.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/WKS.py new file mode 100644 index 0000000..96f98ad --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/WKS.py @@ -0,0 +1,107 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import socket +import struct + +import dns.ipv4 +import dns.rdata +from dns._compat import xrange + +_proto_tcp = socket.getprotobyname('tcp') +_proto_udp = socket.getprotobyname('udp') + + +class WKS(dns.rdata.Rdata): + + """WKS record + + @ivar address: the address + @type address: string + @ivar protocol: the protocol + @type protocol: int + @ivar bitmap: the bitmap + @type bitmap: string + @see: RFC 1035""" + + __slots__ = ['address', 'protocol', 'bitmap'] + + def __init__(self, rdclass, rdtype, address, protocol, bitmap): + super(WKS, self).__init__(rdclass, rdtype) + self.address = address + self.protocol = protocol + if not isinstance(bitmap, bytearray): + self.bitmap = bytearray(bitmap) + else: + self.bitmap = bitmap + + def to_text(self, origin=None, relativize=True, **kw): + bits = [] + for i in xrange(0, len(self.bitmap)): + byte = self.bitmap[i] + for j in xrange(0, 8): + if byte & (0x80 >> j): + bits.append(str(i * 8 + j)) + text = ' '.join(bits) + return '%s %d %s' % (self.address, self.protocol, text) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + address = tok.get_string() + protocol = tok.get_string() + if protocol.isdigit(): + protocol = int(protocol) + else: + protocol = socket.getprotobyname(protocol) + bitmap = bytearray() + while 1: + token = tok.get().unescape() + if token.is_eol_or_eof(): + break + if token.value.isdigit(): + serv = int(token.value) + else: + if protocol != _proto_udp and protocol != _proto_tcp: + raise NotImplementedError("protocol must be TCP or UDP") + if protocol == _proto_udp: + protocol_text = "udp" + else: + protocol_text = "tcp" + serv = socket.getservbyname(token.value, protocol_text) + i = serv // 8 + l = len(bitmap) + if l < i + 1: + for j in xrange(l, i + 1): + bitmap.append(0) + bitmap[i] = bitmap[i] | (0x80 >> (serv % 8)) + bitmap = dns.rdata._truncate_bitmap(bitmap) + return cls(rdclass, rdtype, address, protocol, bitmap) + + def to_wire(self, file, compress=None, origin=None): + file.write(dns.ipv4.inet_aton(self.address)) + protocol = struct.pack('!B', self.protocol) + file.write(protocol) + file.write(self.bitmap) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + address = dns.ipv4.inet_ntoa(wire[current: current + 4]) + protocol, = struct.unpack('!B', wire[current + 4: current + 5]) + current += 5 + rdlen -= 5 + bitmap = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, address, protocol, bitmap) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/__init__.py b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__init__.py new file mode 100644 index 0000000..d7e69c9 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__init__.py @@ -0,0 +1,33 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Class IN rdata type classes.""" + +__all__ = [ + 'A', + 'AAAA', + 'APL', + 'DHCID', + 'IPSECKEY', + 'KX', + 'NAPTR', + 'NSAP', + 'NSAP_PTR', + 'PX', + 'SRV', + 'WKS', +] diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/A.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/A.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b743fb2c56a1a57e876e0122f1e4e7949dd50a20 GIT binary patch literal 1548 zcmZ`(PmkO*6t|sZlKHnSTOnGBL#PmRkUE2CC7?p60|!(gjSy5EA|xw{JyXwSl3;sx zyQAy@?V^4RW{!L%Upes=IPqSR=~4t9`PqKYet&-Xz4>Z99uOFpzkTr2FCig+;NdWQ z*gS=4J_8|$pgBosv$AgWy46qUH$*VuT@&F+x(?R8D=!HJ{eevUKjAf5WGD{xJx zf{=~ZgbA8>f~{!czamR2JmFtQNg!^CP(;@>>B&&s7JV_erdKqH#9Lx0MxgJ5{#cB~ zQKKKcB0fom5ciIw^KCJYwaiK_rh`EY)`R`CN>#P)@RV_Jw*i}=1Mt(7AF`7{;x<7KHgshzm6bDbS3#1*H9)jj}WiKR8U zVmnsTn(Y}S)?53#p!W8ZlG>{Y?+F6=)5RoofjONnVn9Zlvg$^LpdoWE81fj=lM7M+a^pN1s2;wOXmd4YbTttIpI`I(Bld$6##55nc;z$*p{8KSX~B3!&To zeA;QVCLd4&m7CCC!)o3IQF}YGCzm}~=^iqw3Bq3kOE9pTbNixBf1^Vr>|{qummw}(!C3t zn(lxnYqkSEto=PjZX8$W9Yu~HqOz&s{?i>AL+xpYxhZYpGYo9%x{M$2KMAzRWzlB*|Ip%_N8raG!3ev111wr5Z1KFC3v8qjHcydmBs9-} z^GzvEbKH+OhyKkwOUSt>Gf+d5n7p)x^M>jA7(%#V(>EIlO(FE#pwahGAi3PQ>#9uV zIXrp|^n~gWUP9_NO^n~xpt~sWS&xl+1CP;BfU>bqqGSvWHbLi)89fue#eLH z@L}^9X7dSvAc7Vop>AdU>h-Ii&~J!f!n+~DlQa+V!L^r!g8o2a{|`7#<{9F4;LSLi z9|5GhHDQ7#o?uIw_|M6L3QzbqQ4)wdA{5aLO$IU)cg0YQZs;{lB5_abh%wlQVBZrH zvFq%k=fo$;4#d50{U;0!%jw~FXOFgq?iF)U z%dO>L+8C|M<@5tpPR+4|$Fvlw7Tvi;rB|tmZP?$KZPUXQr-!NT0~lgxORm|PwX|g$ zMv3uqe;pv^gVsY!>$QZ3fhT$RdjZaq;p)>ox8c8JJpQ3(TwYQaj|_**X7}{CO}lt9n+e`hhATzoK~X zv3i()da`V05Uaj0$5n~DS$9V>JDkr@+Wq=M2N3ODn9Try&^@+CFDK5qB|JaMkP;45 zgu?t5raRD*yw8^Qyfqf39aLH^RcS|B7O7EZ>QY*Ea;|s5*})xrEi@H3@|k%b??agg zy&SvXy(4q1zzzlOqJIf%^Adw zjNgGxOV?0CIa_;(xewX}8@8bo8noj)u)(=jMru5#F=ZVg3=xo3?053|3sp!PW!0+2 zKIpjrhqmWR%a7pPzqCb1h5>M34BR`Wn4TdyT{FbogPQi?7raJ(W^a%Uy9#@y!>!W( zE#1DLOHp5QOL66|NpY%nTK#sFZ-B6jlLv1x??s! z>gODrZ;TCBrYi{zH{yI%iPHl2W6pm%O^eF|2k}%J%A|i*?^4)BahK>fav^jluV#C z_vN!p)<#vOQxpCq!G`}1$q;v1q$cfNgj$s)^pi&M&>DP?i@WTW$4gBXeb#0FIkIT* KV`JUI&-)8~Vs1VF literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/APL.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/APL.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d27e60cd7f212f1367c6e9a0d38627cb74c238f GIT binary patch literal 3880 zcmZuzTaO$^6|U-g&-Bc$H;ykMMB^k*GAQ;68w_3{;tO7|K!fF22^twS?XI5Pp6%%# zSNGbxs~&-}Mv-{R4?tq}4gLU6{0N@w3Bl7oBk|xD_)hig#l}6VQ&p#KXXf+7j=$43yoVSFgk&spC+#Hno1HCzA(OIP=z5>rzdgA9 zx>6<^*hlX6n?0)CX>zixkgynS`LtGqBw^Rx=X zE7+){0~vSpZ*O^lkE=&hV&Fu7R1*UAKf8uT&Bjc=Bk=#mRPYbS=EyvU|0SsXx{m&@ zIoR_rT^4JX%hk)}o_Ey3CFuXJZ{p+2qpRF7gjd7xIyxmSBiqj!drK#l z>+zV}Kp$;L^R(grL<7bl#(sb&JRVf;+|xZi zL*UKKog0;3wQ6IZ3w{CdF06g?C+yen%`CXxy2z@wF!%YEDMz&>_<1%nAF!vRF98Z+ z*5>bxi)>~z>t}Xt3ww)|f3AYB=mIH zL(8C+29`TGB!3;!9Z22!FTTUyp}S{Y`q`a3{S}QZWdb3}O7o;rKFM%e6*;oRdU$_u z?~z8N@)o@t%6pRLQ5mPH^0)KNWG72UyOPdOCZb51)au?Y%S2Lq-;=VC+Ox`mOSa=m zS<@)q(hyhnbBVC;yV}Xh8l_p%9A{-wSt*_>o+)QDi9{m*4+B*ZK2K$G69<+bLNMOq z=cpKgW$}0TGWURr05U-B@v|5^LC9kDpzl#AUhsWB^u!s_76J4=^edtxx?11*8X-GuBl6x- zCgNjn1ksa8TuAXsvZn-GuJxjZ3yP8E1+6@l7Z;N>T{Kg|`&ie^D3fHZ_i+7g@A`MI zU01fA8z22Ms;Lk_bXKfb1$gfpa|8L&I4}TU%8e&kQQ7786prs>MRVETK?{k3Qi5`& zh=Gz)IZbktdXSTYv>p!99?^avS3O24wKaT&?*+Jp;{-Q&6q8x>(FDptKSwE7AOxSo z&`PJaeMA>7(iptty}qTaagpZAoJ3P)0^E%S3-g>prW+V-$s_~QJxlizWo$iv4Is(| z4y$CR`VAeYvlZWKlW7Zmtg{;iyC`JWU7Gkuhz&M#cK%SCb9TVy{D95e+MOE*OuqYo z)$Z7wd9^3_MI>U%V#rZG`gpnMT;t_d zpzlE6shql1`*nbxh5enmTYHpmo;t{6L~};%?3=hDZ=f^IOMdB*B+J)d^0k+I6~Sh1 zAkBE&c~ZvFG#Pf%GE9mrEF`LtvY$oSb^^ywv$Rqs*jI;&a-!)p$wj}b%s4CMr`S>w zaVfJZwj|Mjqz94qfU==Wa%40B^Mq8Ch389k!mqD;!XL?EqJ0r#r}BLWW?0O|uS@^|1cmpCC5-bLJRnGd7Dx>M@%fH9~{tkkzTX&9}xB$Pa!QW}Xe@Fmmm{u;KdH7q1NAe8hx(9=Ue+0KbWseUe_sk{iKd`mCV{GC_D zRK88hb9%bo7l|^-sih-Ieuj~LSKgvo$Kf=z2r$Zxx1~(-YG_MAoUY@G(yOGX7&_5N zt0^@#@pOq=Z$PGMf{HesVM=)mf|(Y#5IzQq$1iAU@fHG$`t&=CLbSb%R=24g>U*H~ zE=^=_{2+y$$2ak@HiDdD1%QCp8tp2h*PYWK9AioVecxYWc zcB^(XXd626+R&$#6j2p56Ll5?ZOCDpMu3jVG^+Gdt9fNP#glOoHyM&#MJw%xR5g^T e>F-34;mZ3_^T7ErVXU#9Zq{gS9(QgofB%1?f_CHp literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/DHCID.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/DHCID.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2dbb3dd5df0fcf5b059a9223145b44b76976afd GIT binary patch literal 1717 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/KX.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/KX.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24e6bd2e4b27c2cd1a2294838f41915fe3c137b8 GIT binary patch literal 388 zcmYLEJxjzu5Z&y?OFTT01ADO$Qd|PsD2N<3BEd8wghg0lX3@latl1n~1S|a?*8T~9 zNLnlZf|Zk8P6y`kX7z9q!dBFcsrO9&`qAwEcDp>GdA$6lQ)PbF%W6uOSGY<8F&r6-T~ z+Ji!?rhX`kj(HW-jgs2C3_L${RZ~&)*zJz&h)w(28SyEK-9hZ;%ezQRyt~lc8k&4G ibhmGcxXe{0wU%%d_6Gl#t(cA8t$n)s(b@EG9s310_Fg;y literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/NAPTR.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/NAPTR.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24760893c3f2748dde4305b3d63b3cf86339b298 GIT binary patch literal 3344 zcmZuzTaz0{74Dw;=!G?vpMmtq@8F#u&`(tHw10sozSARVC>mL=k#~Z=}$VHgyEb2{Rc1q zd55w8P-FdhU_L_8e+Cgu@RFrX%~Qv=-Bs<`+9~}}kOreL4LK98@Lsbt621sf$G>4B z6wzxYBIyj1Ve8UO+k*d*_2Mh6&W?JH3C>i1Jdh@?*;y*%hfILIgV;Ss>uLW`FmiXJgfMnqjpKbB~+_PJ${6fCWW@=8Rt^bBooMS zJ`u9VjsL1&&ZIqkLw2Y?&UAlVRKMd|NHP@f*LqiWiBulwqxOkqr z!lCP?s}|uPNWHJwF&B}DUq`7g?uoYOyyj^jL$N1z#I4u3IRN9nxGnBL9z(t_cEwv( zo``qEUGX;Lt*@EK(l!+Pmhr9S`g54Va$P0!i4sZD#rIM1s;|0eN_E&&jhM{778m1c zYwT3XW2s;mdDy+?w`N@n54&$pJudqLeb}|t)`XR~xzDYg0IpXBZL?ywrd)Sf5Nu6S zav;y9hfs1bE1?=1N@@*|ZcSeg`o@+@PRo8SM{-=z5}QVM+#ks|7T9zhb^+AK)c^Ph zq&xXyDD#!Uw8ZJ3KYQAJ^8Qbr7~h)NB-aKqzSZ4?D}7ARoXoVg_RixKhNz~vLeSLD zKq?@)W|s~*D!DCZm0SClkYygYz;Zsg&~icTq9?39(5Q|;W9!<$eqww*n@XkbVp$Vq zSpisQnT4_1gG}8gvQOk~BIHVne6JT9Ps{Sygi7RPUu)=Kopx*7jRov94(G}21Z+b= zL6JwPcR@Zx(bQtjF1(3;0e%-dO$b;Y?&w8MmY~l^p&0Nx6#Xek&4z5j8>`Gc0gDVB z6u0t*{vrSuF8PL!w)l9-YwtL?M=`-Uy4ZUpy7)hQq#tgPN4l3-<;|V^%gIE`Ov$oe z6|aiw{90|}0vN_uqF?pXIFmZ>PmAO88|Li!>f1Q52_~u-6l0UDm%5O~IXSi4+zdNm zHOVN>69yVX@g45i_}4}Zyy!HBT8+xrp{I@EgrTQ2Ed{CF1zWN?aAE5ZHAg#I)$yuM zP$N>#TXk#U0zLlH0gq&{L`JBQOlqeN>JW&E>!fa7Mom2R(_|p4Y=#){)1Nnd<8LM+ zIeCntu$hL`l#{a8Hf~;O^&JS+cR`F>O-|JJsriV=HS+!sqHY=~K30>FHPi1gR}-+A z6TwL9UmM&Gzqr*HYco107o(3rMa7!y1(*tux`xuyoqIK3c(q44vhraDHViJw2^&7# z;v?eGA1@MXE_dm!@+v^)KKT6eUP}>x72VI4o*^|Uq1`}DgFeE+X`$o_LyDdwCdwxx z8}h8-(x^I}z?&<5!#?WA82l1N6D$}KX9DQlfDbL6(;4WaV{G69b=LMENZ{SD$NuK* zv!(OWnTLQ7Bp)zX$QRBp*xVnmd3-jmkn1k_r|d6Z%mJ#}+b2+Y!ds2>Xk^{0{S!|g zW2S$?)VOkoa9X@j>^^m?*=G>|kZtVTYUb80J2zg0b(`+vtHVDb7!IQaKr9%6wwZ_9 zq7!!JJM|9san-*z>j#3J#OmL52X_=K`Mk4&wgtBE_gNhaoES6!?O2$H&Fx(gX09k2 zUBNC)5xJuG*XmkLFdNfrNRdoE1TnEZ%jJ|FPig#YqDIXV3gb>ye`?39nrvl#id+&tu?f^j zNX=Ul3CU>!AH|2BYa`@V9I)x)I%m+JIf}NPi!)s8H9q}~;Ea&|VpWdl$w$o&r8_cn zmYF2WMiVhBiEn4wSF?V(>It(PI9dlPNNw z4RLt0Hn}dBWx39Gq(G0WE)BA|kL*FqX-clqZO=j8bJ|G~JG|XaBGCIbKleH|R-_$z zcx+%~VTGsR>M@eW#5KvMMQlcKpjctCt Ri_tdiM5}mu+l|5~_#c({0&f5S literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/NSAP.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/NSAP.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4cf169ae72ed1213a1975eab0c41a35c3422f3f GIT binary patch literal 1750 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 L;tXvM3Y~udg5(;( literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/SRV.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/IN/__pycache__/SRV.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..931bf74e37855facc057b3b641060576c1f25824 GIT binary patch literal 2327 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 KglXv7fAs@#>Q7Vv literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/__init__.py b/env/lib/python3.7/site-packages/dns/rdtypes/__init__.py new file mode 100644 index 0000000..1ac137f --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/__init__.py @@ -0,0 +1,27 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS rdata type classes""" + +__all__ = [ + 'ANY', + 'IN', + 'CH', + 'euibase', + 'mxbase', + 'nsbase', +] diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..509e5eb4cc4ac07e3acee643ec4bb033b568fd66 GIT binary patch literal 255 zcmZ?b<>g`kg4+3NG1r(G7#@Q-Fu(?6H~?|61dvE!h+;@#Okql4PGL!5O<_xCi(*V+ z4`$Hhs1kGW3sxvfNi0cJD5)$+RY=ZBEG|whzQye57kP`x(=Uq2*&~WQwKOv+u{bq~ zEw=(f=M{r!KTW1v?D6p_`N{F|AVy+NPJH}Ih9Xv=onYdZwSGx%fqp?|fo^7AaS2df z*C^9C%Q8E?SU)ANxS+BmBR>zs(l1H@SzoLlAD@|*SrQ+wS5SG2!zMRBr8FniP6*@? M9w5QO%)|(T0EG2KPXGV_ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/dnskeybase.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/dnskeybase.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8f5506ba33eca8902aaa0b74198fce91d00ec97d GIT binary patch literal 3659 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 V)pR@OM(gUAxKr5H96(~v_zzlk9!&rM literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/mxbase.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/mxbase.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d68bb16c4c482e1fb21c503ed165a6d1f748a75 GIT binary patch literal 3512 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/txtbase.cpython-37.pyc b/env/lib/python3.7/site-packages/dns/rdtypes/__pycache__/txtbase.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e30a141b5c3495033ab9258b7457355d51d990a GIT binary patch literal 2470 zcmZ8jOOqQl5SBDgzjim9@JLmt8eS<(k=^hPDT;zX-~hO&un=krYHD^QJL4VCIFdH& zHRB5#Dt~}G_L0A&E2sR0T%cQHZy*}$)!mZ1TVJ<)tJiB2D2qR@{!Ds={Ed@MabfT& zRP_xsoWz7v&I%e++q2lQy}Rx`+dG9n3F2T9#vvtN5$p2I#;tMt%!xakeNX!S z{L;Zs2iJ=HNJNLJ5>Zy9O6@&{bI732Oy@8!Q+b-`)2T3BrDa}@>_lZKvMHz_7WE@E zf`DQqW}Jc|Y(!)C5gAhMaQ9&tdwiP*JbXxFUj%%Iw|M&@J)?2RFYpfU0=)(FUEbqc zmfn6uToQLc)r%$oRd0ck^D}H4Rij}gBgs>pM*3c=qg+MSm^1?6NQ$hIyxoqVe40N< zWz?9UZi2MfOd2+txS`yHO_YwRVbs{)NGKt0Mt8paJbL^3yYHJ|y;Zg`-UHil?4TnK zq0vOsnw+sEt7*+vj1ukCj&{$Ox@t$>8Iy0-&WJ9Y5vfVy&)%$^FUT*iEL`Bb8u^3T zT?Q+%aBDL5mtpO$C?)rA+yxwfQ|O@IGM+k~3Muhy6DCPs<~m7CJ6CzBbXsOYGGIy6 zOQMp-7iCs)Vf=JD6(#R`##N#inm}@U|HhXb-LaN#4DD0XN)pRYlE284oBMh)-Jj;u zYxbC;xb{x|?)amlk=o~_nx5)=Rf(hhW-qm`XBr{4H$9aBXmJ&)+J%PDUD}4vhY$OZ z&Ue-~y|=MuaFC(;Sa59!^=qi=1~i;5T&Ny6kBkYpFIxDu%h{6Fo@Qfb>DK;=uGoj* zMD8rS`#X0@?Sk{%fgyAM*TpOFdqShWx3(7`HA%H`KzZX?Y{jias4Si4!_$5sJ8-D+ zE18e-(zK;0Qk_4@=fbd~6XSrH#-B9=8`y3i2n!q=rQ zqTSmYyVp{gj}lN?Q1O00hpLv)jL5>D&1+{#R%A&5A3+@~*^0<3-w_x&EAS2UF8103 zEfq?f~w}+Fy3-(4x(6#>?J{H1oRz_VHmC z_lU_qaF_8G>_8CbKzG2o-e7(~%%&pKf=B5(upa*ds?WC@Kt;N$qM|BCk^;5AZJd$N zCOj^!t3}+)RU)b)sU&p6cn7BUk1N zI=d}pC5=;v(s&Qj;#f#TPZJWDawYmU?)^}1w7m@x(K1d}D2W#&AsZ98*6K*UfYTST zv0>x^O_cIABs_D?t)Z+Y_M$%mu8N=`%%u!2I)ruy`Yosk_%7SE)cJ+Y<)5!TPb~-o z#J#=#FJLhHWR3OrAXU)XJp=sL9;ZiemS%7jbP0)O>2X$jD~6Ybly&k5*U7^fJSO1! zIeYn5-?t{oS7C3n^_fyaq7NJ2c_%X0kS)ON$C)0r?Sv3L3E7iE@ z3hqLSXPtuBKgp%|7TC(ZcGmDN#Q*=0k1`pWiv{J*k*{F_$PZ?R)>u~#YcT3ESwLRo zHo$?-ZV+%rSbKo*4>TFmF**d~;0s?Mzq88(<73gnIVOb~r0p7rm%6n<_!`ZDMYA)o zAbo6+>RG7CmqD4h^(7>W#!dclc_P!PM2-7x`8sq@0TjDvl?k$ADFLxD05R$3>&(rrj?&RIU{|femr^+=Wo1epv8<%{7FOyBsE(=-X=pE-@ D@{M1C literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/dnskeybase.py b/env/lib/python3.7/site-packages/dns/rdtypes/dnskeybase.py new file mode 100644 index 0000000..3e7e87e --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/dnskeybase.py @@ -0,0 +1,138 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2004-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import base64 +import struct + +import dns.exception +import dns.dnssec +import dns.rdata + +# wildcard import +__all__ = ["SEP", "REVOKE", "ZONE", + "flags_to_text_set", "flags_from_text_set"] + +# flag constants +SEP = 0x0001 +REVOKE = 0x0080 +ZONE = 0x0100 + +_flag_by_text = { + 'SEP': SEP, + 'REVOKE': REVOKE, + 'ZONE': ZONE +} + +# We construct the inverse mapping programmatically to ensure that we +# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that +# would cause the mapping not to be true inverse. +_flag_by_value = {y: x for x, y in _flag_by_text.items()} + + +def flags_to_text_set(flags): + """Convert a DNSKEY flags value to set texts + @rtype: set([string])""" + + flags_set = set() + mask = 0x1 + while mask <= 0x8000: + if flags & mask: + text = _flag_by_value.get(mask) + if not text: + text = hex(mask) + flags_set.add(text) + mask <<= 1 + return flags_set + + +def flags_from_text_set(texts_set): + """Convert set of DNSKEY flag mnemonic texts to DNSKEY flag value + @rtype: int""" + + flags = 0 + for text in texts_set: + try: + flags += _flag_by_text[text] + except KeyError: + raise NotImplementedError( + "DNSKEY flag '%s' is not supported" % text) + return flags + + +class DNSKEYBase(dns.rdata.Rdata): + + """Base class for rdata that is like a DNSKEY record + + @ivar flags: the key flags + @type flags: int + @ivar protocol: the protocol for which this key may be used + @type protocol: int + @ivar algorithm: the algorithm used for the key + @type algorithm: int + @ivar key: the public key + @type key: string""" + + __slots__ = ['flags', 'protocol', 'algorithm', 'key'] + + def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key): + super(DNSKEYBase, self).__init__(rdclass, rdtype) + self.flags = flags + self.protocol = protocol + self.algorithm = algorithm + self.key = key + + def to_text(self, origin=None, relativize=True, **kw): + return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm, + dns.rdata._base64ify(self.key)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + flags = tok.get_uint16() + protocol = tok.get_uint8() + algorithm = dns.dnssec.algorithm_from_text(tok.get_string()) + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + key = base64.b64decode(b64) + return cls(rdclass, rdtype, flags, protocol, algorithm, key) + + def to_wire(self, file, compress=None, origin=None): + header = struct.pack("!HBB", self.flags, self.protocol, self.algorithm) + file.write(header) + file.write(self.key) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + if rdlen < 4: + raise dns.exception.FormError + header = struct.unpack('!HBB', wire[current: current + 4]) + current += 4 + rdlen -= 4 + key = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, header[0], header[1], header[2], + key) + + def flags_to_text_set(self): + """Convert a DNSKEY flags value to set texts + @rtype: set([string])""" + return flags_to_text_set(self.flags) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/dsbase.py b/env/lib/python3.7/site-packages/dns/rdtypes/dsbase.py new file mode 100644 index 0000000..26ae9d5 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/dsbase.py @@ -0,0 +1,85 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2010, 2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import struct +import binascii + +import dns.rdata +import dns.rdatatype + + +class DSBase(dns.rdata.Rdata): + + """Base class for rdata that is like a DS record + + @ivar key_tag: the key tag + @type key_tag: int + @ivar algorithm: the algorithm + @type algorithm: int + @ivar digest_type: the digest type + @type digest_type: int + @ivar digest: the digest + @type digest: int + @see: draft-ietf-dnsext-delegation-signer-14.txt""" + + __slots__ = ['key_tag', 'algorithm', 'digest_type', 'digest'] + + def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type, + digest): + super(DSBase, self).__init__(rdclass, rdtype) + self.key_tag = key_tag + self.algorithm = algorithm + self.digest_type = digest_type + self.digest = digest + + def to_text(self, origin=None, relativize=True, **kw): + return '%d %d %d %s' % (self.key_tag, self.algorithm, + self.digest_type, + dns.rdata._hexify(self.digest, + chunksize=128)) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + key_tag = tok.get_uint16() + algorithm = tok.get_uint8() + digest_type = tok.get_uint8() + chunks = [] + while 1: + t = tok.get().unescape() + if t.is_eol_or_eof(): + break + if not t.is_identifier(): + raise dns.exception.SyntaxError + chunks.append(t.value.encode()) + digest = b''.join(chunks) + digest = binascii.unhexlify(digest) + return cls(rdclass, rdtype, key_tag, algorithm, digest_type, + digest) + + def to_wire(self, file, compress=None, origin=None): + header = struct.pack("!HBB", self.key_tag, self.algorithm, + self.digest_type) + file.write(header) + file.write(self.digest) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + header = struct.unpack("!HBB", wire[current: current + 4]) + current += 4 + rdlen -= 4 + digest = wire[current: current + rdlen].unwrap() + return cls(rdclass, rdtype, header[0], header[1], header[2], digest) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/euibase.py b/env/lib/python3.7/site-packages/dns/rdtypes/euibase.py new file mode 100644 index 0000000..cc5fdaa --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/euibase.py @@ -0,0 +1,71 @@ +# Copyright (C) 2015 Red Hat, Inc. +# Author: Petr Spacek +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED 'AS IS' AND RED HAT DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +import binascii + +import dns.rdata +from dns._compat import xrange + + +class EUIBase(dns.rdata.Rdata): + + """EUIxx record + + @ivar fingerprint: xx-bit Extended Unique Identifier (EUI-xx) + @type fingerprint: string + @see: rfc7043.txt""" + + __slots__ = ['eui'] + # define these in subclasses + # byte_len = 6 # 0123456789ab (in hex) + # text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab + + def __init__(self, rdclass, rdtype, eui): + super(EUIBase, self).__init__(rdclass, rdtype) + if len(eui) != self.byte_len: + raise dns.exception.FormError('EUI%s rdata has to have %s bytes' + % (self.byte_len * 8, self.byte_len)) + self.eui = eui + + def to_text(self, origin=None, relativize=True, **kw): + return dns.rdata._hexify(self.eui, chunksize=2).replace(' ', '-') + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + text = tok.get_string() + tok.get_eol() + if len(text) != cls.text_len: + raise dns.exception.SyntaxError( + 'Input text must have %s characters' % cls.text_len) + expected_dash_idxs = xrange(2, cls.byte_len * 3 - 1, 3) + for i in expected_dash_idxs: + if text[i] != '-': + raise dns.exception.SyntaxError('Dash expected at position %s' + % i) + text = text.replace('-', '') + try: + data = binascii.unhexlify(text.encode()) + except (ValueError, TypeError) as ex: + raise dns.exception.SyntaxError('Hex decoding error: %s' % str(ex)) + return cls(rdclass, rdtype, data) + + def to_wire(self, file, compress=None, origin=None): + file.write(self.eui) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + eui = wire[current:current + rdlen].unwrap() + return cls(rdclass, rdtype, eui) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/mxbase.py b/env/lib/python3.7/site-packages/dns/rdtypes/mxbase.py new file mode 100644 index 0000000..9a3fa62 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/mxbase.py @@ -0,0 +1,103 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""MX-like base classes.""" + +from io import BytesIO +import struct + +import dns.exception +import dns.rdata +import dns.name + + +class MXBase(dns.rdata.Rdata): + + """Base class for rdata that is like an MX record. + + @ivar preference: the preference value + @type preference: int + @ivar exchange: the exchange name + @type exchange: dns.name.Name object""" + + __slots__ = ['preference', 'exchange'] + + def __init__(self, rdclass, rdtype, preference, exchange): + super(MXBase, self).__init__(rdclass, rdtype) + self.preference = preference + self.exchange = exchange + + def to_text(self, origin=None, relativize=True, **kw): + exchange = self.exchange.choose_relativity(origin, relativize) + return '%d %s' % (self.preference, exchange) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + preference = tok.get_uint16() + exchange = tok.get_name() + exchange = exchange.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, preference, exchange) + + def to_wire(self, file, compress=None, origin=None): + pref = struct.pack("!H", self.preference) + file.write(pref) + self.exchange.to_wire(file, compress, origin) + + def to_digestable(self, origin=None): + return struct.pack("!H", self.preference) + \ + self.exchange.to_digestable(origin) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (preference, ) = struct.unpack('!H', wire[current: current + 2]) + current += 2 + rdlen -= 2 + (exchange, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if origin is not None: + exchange = exchange.relativize(origin) + return cls(rdclass, rdtype, preference, exchange) + + def choose_relativity(self, origin=None, relativize=True): + self.exchange = self.exchange.choose_relativity(origin, relativize) + + +class UncompressedMX(MXBase): + + """Base class for rdata that is like an MX record, but whose name + is not compressed when converted to DNS wire format, and whose + digestable form is not downcased.""" + + def to_wire(self, file, compress=None, origin=None): + super(UncompressedMX, self).to_wire(file, None, origin) + + def to_digestable(self, origin=None): + f = BytesIO() + self.to_wire(f, None, origin) + return f.getvalue() + + +class UncompressedDowncasingMX(MXBase): + + """Base class for rdata that is like an MX record, but whose name + is not compressed when convert to DNS wire format.""" + + def to_wire(self, file, compress=None, origin=None): + super(UncompressedDowncasingMX, self).to_wire(file, None, origin) diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/nsbase.py b/env/lib/python3.7/site-packages/dns/rdtypes/nsbase.py new file mode 100644 index 0000000..97a2232 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/nsbase.py @@ -0,0 +1,83 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""NS-like base classes.""" + +from io import BytesIO + +import dns.exception +import dns.rdata +import dns.name + + +class NSBase(dns.rdata.Rdata): + + """Base class for rdata that is like an NS record. + + @ivar target: the target name of the rdata + @type target: dns.name.Name object""" + + __slots__ = ['target'] + + def __init__(self, rdclass, rdtype, target): + super(NSBase, self).__init__(rdclass, rdtype) + self.target = target + + def to_text(self, origin=None, relativize=True, **kw): + target = self.target.choose_relativity(origin, relativize) + return str(target) + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + target = tok.get_name() + target = target.choose_relativity(origin, relativize) + tok.get_eol() + return cls(rdclass, rdtype, target) + + def to_wire(self, file, compress=None, origin=None): + self.target.to_wire(file, compress, origin) + + def to_digestable(self, origin=None): + return self.target.to_digestable(origin) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (target, cused) = dns.name.from_wire(wire[: current + rdlen], + current) + if cused != rdlen: + raise dns.exception.FormError + if origin is not None: + target = target.relativize(origin) + return cls(rdclass, rdtype, target) + + def choose_relativity(self, origin=None, relativize=True): + self.target = self.target.choose_relativity(origin, relativize) + + +class UncompressedNS(NSBase): + + """Base class for rdata that is like an NS record, but whose name + is not compressed when convert to DNS wire format, and whose + digestable form is not downcased.""" + + def to_wire(self, file, compress=None, origin=None): + super(UncompressedNS, self).to_wire(file, None, origin) + + def to_digestable(self, origin=None): + f = BytesIO() + self.to_wire(f, None, origin) + return f.getvalue() diff --git a/env/lib/python3.7/site-packages/dns/rdtypes/txtbase.py b/env/lib/python3.7/site-packages/dns/rdtypes/txtbase.py new file mode 100644 index 0000000..645a57e --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rdtypes/txtbase.py @@ -0,0 +1,97 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2006-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""TXT-like base class.""" + +import struct + +import dns.exception +import dns.rdata +import dns.tokenizer +from dns._compat import binary_type, string_types + + +class TXTBase(dns.rdata.Rdata): + + """Base class for rdata that is like a TXT record + + @ivar strings: the strings + @type strings: list of binary + @see: RFC 1035""" + + __slots__ = ['strings'] + + def __init__(self, rdclass, rdtype, strings): + super(TXTBase, self).__init__(rdclass, rdtype) + if isinstance(strings, binary_type) or \ + isinstance(strings, string_types): + strings = [strings] + self.strings = [] + for string in strings: + if isinstance(string, string_types): + string = string.encode() + self.strings.append(string) + + def to_text(self, origin=None, relativize=True, **kw): + txt = '' + prefix = '' + for s in self.strings: + txt += '{}"{}"'.format(prefix, dns.rdata._escapify(s)) + prefix = ' ' + return txt + + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): + strings = [] + while 1: + token = tok.get().unescape() + if token.is_eol_or_eof(): + break + if not (token.is_quoted_string() or token.is_identifier()): + raise dns.exception.SyntaxError("expected a string") + if len(token.value) > 255: + raise dns.exception.SyntaxError("string too long") + value = token.value + if isinstance(value, binary_type): + strings.append(value) + else: + strings.append(value.encode()) + if len(strings) == 0: + raise dns.exception.UnexpectedEnd + return cls(rdclass, rdtype, strings) + + def to_wire(self, file, compress=None, origin=None): + for s in self.strings: + l = len(s) + assert l < 256 + file.write(struct.pack('!B', l)) + file.write(s) + + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + strings = [] + while rdlen > 0: + l = wire[current] + current += 1 + rdlen -= 1 + if l > rdlen: + raise dns.exception.FormError + s = wire[current: current + l].unwrap() + current += l + rdlen -= l + strings.append(s) + return cls(rdclass, rdtype, strings) diff --git a/env/lib/python3.7/site-packages/dns/renderer.py b/env/lib/python3.7/site-packages/dns/renderer.py new file mode 100644 index 0000000..d7ef8c7 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/renderer.py @@ -0,0 +1,291 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Help for building DNS wire format messages""" + +from io import BytesIO +import struct +import random +import time + +import dns.exception +import dns.tsig +from ._compat import long + + +QUESTION = 0 +ANSWER = 1 +AUTHORITY = 2 +ADDITIONAL = 3 + + +class Renderer(object): + """Helper class for building DNS wire-format messages. + + Most applications can use the higher-level L{dns.message.Message} + class and its to_wire() method to generate wire-format messages. + This class is for those applications which need finer control + over the generation of messages. + + Typical use:: + + r = dns.renderer.Renderer(id=1, flags=0x80, max_size=512) + r.add_question(qname, qtype, qclass) + r.add_rrset(dns.renderer.ANSWER, rrset_1) + r.add_rrset(dns.renderer.ANSWER, rrset_2) + r.add_rrset(dns.renderer.AUTHORITY, ns_rrset) + r.add_edns(0, 0, 4096) + r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_1) + r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_2) + r.write_header() + r.add_tsig(keyname, secret, 300, 1, 0, '', request_mac) + wire = r.get_wire() + + output, a BytesIO, where rendering is written + + id: the message id + + flags: the message flags + + max_size: the maximum size of the message + + origin: the origin to use when rendering relative names + + compress: the compression table + + section: an int, the section currently being rendered + + counts: list of the number of RRs in each section + + mac: the MAC of the rendered message (if TSIG was used) + """ + + def __init__(self, id=None, flags=0, max_size=65535, origin=None): + """Initialize a new renderer.""" + + self.output = BytesIO() + if id is None: + self.id = random.randint(0, 65535) + else: + self.id = id + self.flags = flags + self.max_size = max_size + self.origin = origin + self.compress = {} + self.section = QUESTION + self.counts = [0, 0, 0, 0] + self.output.write(b'\x00' * 12) + self.mac = '' + + def _rollback(self, where): + """Truncate the output buffer at offset *where*, and remove any + compression table entries that pointed beyond the truncation + point. + """ + + self.output.seek(where) + self.output.truncate() + keys_to_delete = [] + for k, v in self.compress.items(): + if v >= where: + keys_to_delete.append(k) + for k in keys_to_delete: + del self.compress[k] + + def _set_section(self, section): + """Set the renderer's current section. + + Sections must be rendered order: QUESTION, ANSWER, AUTHORITY, + ADDITIONAL. Sections may be empty. + + Raises dns.exception.FormError if an attempt was made to set + a section value less than the current section. + """ + + if self.section != section: + if self.section > section: + raise dns.exception.FormError + self.section = section + + def add_question(self, qname, rdtype, rdclass=dns.rdataclass.IN): + """Add a question to the message.""" + + self._set_section(QUESTION) + before = self.output.tell() + qname.to_wire(self.output, self.compress, self.origin) + self.output.write(struct.pack("!HH", rdtype, rdclass)) + after = self.output.tell() + if after >= self.max_size: + self._rollback(before) + raise dns.exception.TooBig + self.counts[QUESTION] += 1 + + def add_rrset(self, section, rrset, **kw): + """Add the rrset to the specified section. + + Any keyword arguments are passed on to the rdataset's to_wire() + routine. + """ + + self._set_section(section) + before = self.output.tell() + n = rrset.to_wire(self.output, self.compress, self.origin, **kw) + after = self.output.tell() + if after >= self.max_size: + self._rollback(before) + raise dns.exception.TooBig + self.counts[section] += n + + def add_rdataset(self, section, name, rdataset, **kw): + """Add the rdataset to the specified section, using the specified + name as the owner name. + + Any keyword arguments are passed on to the rdataset's to_wire() + routine. + """ + + self._set_section(section) + before = self.output.tell() + n = rdataset.to_wire(name, self.output, self.compress, self.origin, + **kw) + after = self.output.tell() + if after >= self.max_size: + self._rollback(before) + raise dns.exception.TooBig + self.counts[section] += n + + def add_edns(self, edns, ednsflags, payload, options=None): + """Add an EDNS OPT record to the message.""" + + # make sure the EDNS version in ednsflags agrees with edns + ednsflags &= long(0xFF00FFFF) + ednsflags |= (edns << 16) + self._set_section(ADDITIONAL) + before = self.output.tell() + self.output.write(struct.pack('!BHHIH', 0, dns.rdatatype.OPT, payload, + ednsflags, 0)) + if options is not None: + lstart = self.output.tell() + for opt in options: + stuff = struct.pack("!HH", opt.otype, 0) + self.output.write(stuff) + start = self.output.tell() + opt.to_wire(self.output) + end = self.output.tell() + assert end - start < 65536 + self.output.seek(start - 2) + stuff = struct.pack("!H", end - start) + self.output.write(stuff) + self.output.seek(0, 2) + lend = self.output.tell() + assert lend - lstart < 65536 + self.output.seek(lstart - 2) + stuff = struct.pack("!H", lend - lstart) + self.output.write(stuff) + self.output.seek(0, 2) + after = self.output.tell() + if after >= self.max_size: + self._rollback(before) + raise dns.exception.TooBig + self.counts[ADDITIONAL] += 1 + + def add_tsig(self, keyname, secret, fudge, id, tsig_error, other_data, + request_mac, algorithm=dns.tsig.default_algorithm): + """Add a TSIG signature to the message.""" + + s = self.output.getvalue() + (tsig_rdata, self.mac, ctx) = dns.tsig.sign(s, + keyname, + secret, + int(time.time()), + fudge, + id, + tsig_error, + other_data, + request_mac, + algorithm=algorithm) + self._write_tsig(tsig_rdata, keyname) + + def add_multi_tsig(self, ctx, keyname, secret, fudge, id, tsig_error, + other_data, request_mac, + algorithm=dns.tsig.default_algorithm): + """Add a TSIG signature to the message. Unlike add_tsig(), this can be + used for a series of consecutive DNS envelopes, e.g. for a zone + transfer over TCP [RFC2845, 4.4]. + + For the first message in the sequence, give ctx=None. For each + subsequent message, give the ctx that was returned from the + add_multi_tsig() call for the previous message.""" + + s = self.output.getvalue() + (tsig_rdata, self.mac, ctx) = dns.tsig.sign(s, + keyname, + secret, + int(time.time()), + fudge, + id, + tsig_error, + other_data, + request_mac, + ctx=ctx, + first=ctx is None, + multi=True, + algorithm=algorithm) + self._write_tsig(tsig_rdata, keyname) + return ctx + + def _write_tsig(self, tsig_rdata, keyname): + self._set_section(ADDITIONAL) + before = self.output.tell() + + keyname.to_wire(self.output, self.compress, self.origin) + self.output.write(struct.pack('!HHIH', dns.rdatatype.TSIG, + dns.rdataclass.ANY, 0, 0)) + rdata_start = self.output.tell() + self.output.write(tsig_rdata) + + after = self.output.tell() + assert after - rdata_start < 65536 + if after >= self.max_size: + self._rollback(before) + raise dns.exception.TooBig + + self.output.seek(rdata_start - 2) + self.output.write(struct.pack('!H', after - rdata_start)) + self.counts[ADDITIONAL] += 1 + self.output.seek(10) + self.output.write(struct.pack('!H', self.counts[ADDITIONAL])) + self.output.seek(0, 2) + + def write_header(self): + """Write the DNS message header. + + Writing the DNS message header is done after all sections + have been rendered, but before the optional TSIG signature + is added. + """ + + self.output.seek(0) + self.output.write(struct.pack('!HHHHHH', self.id, self.flags, + self.counts[0], self.counts[1], + self.counts[2], self.counts[3])) + self.output.seek(0, 2) + + def get_wire(self): + """Return the wire format message.""" + + return self.output.getvalue() diff --git a/env/lib/python3.7/site-packages/dns/resolver.py b/env/lib/python3.7/site-packages/dns/resolver.py new file mode 100644 index 0000000..806e5b2 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/resolver.py @@ -0,0 +1,1383 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS stub resolver.""" + +import socket +import sys +import time +import random + +try: + import threading as _threading +except ImportError: + import dummy_threading as _threading + +import dns.exception +import dns.flags +import dns.ipv4 +import dns.ipv6 +import dns.message +import dns.name +import dns.query +import dns.rcode +import dns.rdataclass +import dns.rdatatype +import dns.reversename +import dns.tsig +from ._compat import xrange, string_types + +if sys.platform == 'win32': + try: + import winreg as _winreg + except ImportError: + import _winreg # pylint: disable=import-error + +class NXDOMAIN(dns.exception.DNSException): + """The DNS query name does not exist.""" + supp_kwargs = {'qnames', 'responses'} + fmt = None # we have our own __str__ implementation + + def _check_kwargs(self, qnames, responses=None): + if not isinstance(qnames, (list, tuple, set)): + raise AttributeError("qnames must be a list, tuple or set") + if len(qnames) == 0: + raise AttributeError("qnames must contain at least one element") + if responses is None: + responses = {} + elif not isinstance(responses, dict): + raise AttributeError("responses must be a dict(qname=response)") + kwargs = dict(qnames=qnames, responses=responses) + return kwargs + + def __str__(self): + if 'qnames' not in self.kwargs: + return super(NXDOMAIN, self).__str__() + qnames = self.kwargs['qnames'] + if len(qnames) > 1: + msg = 'None of DNS query names exist' + else: + msg = 'The DNS query name does not exist' + qnames = ', '.join(map(str, qnames)) + return "{}: {}".format(msg, qnames) + + def canonical_name(self): + if not 'qnames' in self.kwargs: + raise TypeError("parametrized exception required") + IN = dns.rdataclass.IN + CNAME = dns.rdatatype.CNAME + cname = None + for qname in self.kwargs['qnames']: + response = self.kwargs['responses'][qname] + for answer in response.answer: + if answer.rdtype != CNAME or answer.rdclass != IN: + continue + cname = answer.items[0].target.to_text() + if cname is not None: + return dns.name.from_text(cname) + return self.kwargs['qnames'][0] + canonical_name = property(canonical_name, doc=( + "Return the unresolved canonical name.")) + + def __add__(self, e_nx): + """Augment by results from another NXDOMAIN exception.""" + qnames0 = list(self.kwargs.get('qnames', [])) + responses0 = dict(self.kwargs.get('responses', {})) + responses1 = e_nx.kwargs.get('responses', {}) + for qname1 in e_nx.kwargs.get('qnames', []): + if qname1 not in qnames0: + qnames0.append(qname1) + if qname1 in responses1: + responses0[qname1] = responses1[qname1] + return NXDOMAIN(qnames=qnames0, responses=responses0) + + def qnames(self): + """All of the names that were tried. + + Returns a list of ``dns.name.Name``. + """ + return self.kwargs['qnames'] + + def responses(self): + """A map from queried names to their NXDOMAIN responses. + + Returns a dict mapping a ``dns.name.Name`` to a + ``dns.message.Message``. + """ + return self.kwargs['responses'] + + def response(self, qname): + """The response for query *qname*. + + Returns a ``dns.message.Message``. + """ + return self.kwargs['responses'][qname] + + +class YXDOMAIN(dns.exception.DNSException): + """The DNS query name is too long after DNAME substitution.""" + +# The definition of the Timeout exception has moved from here to the +# dns.exception module. We keep dns.resolver.Timeout defined for +# backwards compatibility. + +Timeout = dns.exception.Timeout + + +class NoAnswer(dns.exception.DNSException): + """The DNS response does not contain an answer to the question.""" + fmt = 'The DNS response does not contain an answer ' + \ + 'to the question: {query}' + supp_kwargs = {'response'} + + def _fmt_kwargs(self, **kwargs): + return super(NoAnswer, self)._fmt_kwargs( + query=kwargs['response'].question) + + +class NoNameservers(dns.exception.DNSException): + """All nameservers failed to answer the query. + + errors: list of servers and respective errors + The type of errors is + [(server IP address, any object convertible to string)]. + Non-empty errors list will add explanatory message () + """ + + msg = "All nameservers failed to answer the query." + fmt = "%s {query}: {errors}" % msg[:-1] + supp_kwargs = {'request', 'errors'} + + def _fmt_kwargs(self, **kwargs): + srv_msgs = [] + for err in kwargs['errors']: + srv_msgs.append('Server {} {} port {} answered {}'.format(err[0], + 'TCP' if err[1] else 'UDP', err[2], err[3])) + return super(NoNameservers, self)._fmt_kwargs( + query=kwargs['request'].question, errors='; '.join(srv_msgs)) + + +class NotAbsolute(dns.exception.DNSException): + """An absolute domain name is required but a relative name was provided.""" + + +class NoRootSOA(dns.exception.DNSException): + """There is no SOA RR at the DNS root name. This should never happen!""" + + +class NoMetaqueries(dns.exception.DNSException): + """DNS metaqueries are not allowed.""" + + +class Answer(object): + """DNS stub resolver answer. + + Instances of this class bundle up the result of a successful DNS + resolution. + + For convenience, the answer object implements much of the sequence + protocol, forwarding to its ``rrset`` attribute. E.g. + ``for a in answer`` is equivalent to ``for a in answer.rrset``. + ``answer[i]`` is equivalent to ``answer.rrset[i]``, and + ``answer[i:j]`` is equivalent to ``answer.rrset[i:j]``. + + Note that CNAMEs or DNAMEs in the response may mean that answer + RRset's name might not be the query name. + """ + + def __init__(self, qname, rdtype, rdclass, response, + raise_on_no_answer=True): + self.qname = qname + self.rdtype = rdtype + self.rdclass = rdclass + self.response = response + min_ttl = -1 + rrset = None + for count in xrange(0, 15): + try: + rrset = response.find_rrset(response.answer, qname, + rdclass, rdtype) + if min_ttl == -1 or rrset.ttl < min_ttl: + min_ttl = rrset.ttl + break + except KeyError: + if rdtype != dns.rdatatype.CNAME: + try: + crrset = response.find_rrset(response.answer, + qname, + rdclass, + dns.rdatatype.CNAME) + if min_ttl == -1 or crrset.ttl < min_ttl: + min_ttl = crrset.ttl + for rd in crrset: + qname = rd.target + break + continue + except KeyError: + if raise_on_no_answer: + raise NoAnswer(response=response) + if raise_on_no_answer: + raise NoAnswer(response=response) + if rrset is None and raise_on_no_answer: + raise NoAnswer(response=response) + self.canonical_name = qname + self.rrset = rrset + if rrset is None: + while 1: + # Look for a SOA RR whose owner name is a superdomain + # of qname. + try: + srrset = response.find_rrset(response.authority, qname, + rdclass, dns.rdatatype.SOA) + if min_ttl == -1 or srrset.ttl < min_ttl: + min_ttl = srrset.ttl + if srrset[0].minimum < min_ttl: + min_ttl = srrset[0].minimum + break + except KeyError: + try: + qname = qname.parent() + except dns.name.NoParent: + break + self.expiration = time.time() + min_ttl + + def __getattr__(self, attr): + if attr == 'name': + return self.rrset.name + elif attr == 'ttl': + return self.rrset.ttl + elif attr == 'covers': + return self.rrset.covers + elif attr == 'rdclass': + return self.rrset.rdclass + elif attr == 'rdtype': + return self.rrset.rdtype + else: + raise AttributeError(attr) + + def __len__(self): + return self.rrset and len(self.rrset) or 0 + + def __iter__(self): + return self.rrset and iter(self.rrset) or iter(tuple()) + + def __getitem__(self, i): + if self.rrset is None: + raise IndexError + return self.rrset[i] + + def __delitem__(self, i): + if self.rrset is None: + raise IndexError + del self.rrset[i] + + +class Cache(object): + """Simple thread-safe DNS answer cache.""" + + def __init__(self, cleaning_interval=300.0): + """*cleaning_interval*, a ``float`` is the number of seconds between + periodic cleanings. + """ + + self.data = {} + self.cleaning_interval = cleaning_interval + self.next_cleaning = time.time() + self.cleaning_interval + self.lock = _threading.Lock() + + def _maybe_clean(self): + """Clean the cache if it's time to do so.""" + + now = time.time() + if self.next_cleaning <= now: + keys_to_delete = [] + for (k, v) in self.data.items(): + if v.expiration <= now: + keys_to_delete.append(k) + for k in keys_to_delete: + del self.data[k] + now = time.time() + self.next_cleaning = now + self.cleaning_interval + + def get(self, key): + """Get the answer associated with *key*. + + Returns None if no answer is cached for the key. + + *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the + query name, rdtype, and rdclass respectively. + + Returns a ``dns.resolver.Answer`` or ``None``. + """ + + try: + self.lock.acquire() + self._maybe_clean() + v = self.data.get(key) + if v is None or v.expiration <= time.time(): + return None + return v + finally: + self.lock.release() + + def put(self, key, value): + """Associate key and value in the cache. + + *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the + query name, rdtype, and rdclass respectively. + + *value*, a ``dns.resolver.Answer``, the answer. + """ + + try: + self.lock.acquire() + self._maybe_clean() + self.data[key] = value + finally: + self.lock.release() + + def flush(self, key=None): + """Flush the cache. + + If *key* is not ``None``, only that item is flushed. Otherwise + the entire cache is flushed. + + *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the + query name, rdtype, and rdclass respectively. + """ + + try: + self.lock.acquire() + if key is not None: + if key in self.data: + del self.data[key] + else: + self.data = {} + self.next_cleaning = time.time() + self.cleaning_interval + finally: + self.lock.release() + + +class LRUCacheNode(object): + """LRUCache node.""" + + def __init__(self, key, value): + self.key = key + self.value = value + self.prev = self + self.next = self + + def link_before(self, node): + self.prev = node.prev + self.next = node + node.prev.next = self + node.prev = self + + def link_after(self, node): + self.prev = node + self.next = node.next + node.next.prev = self + node.next = self + + def unlink(self): + self.next.prev = self.prev + self.prev.next = self.next + + +class LRUCache(object): + """Thread-safe, bounded, least-recently-used DNS answer cache. + + This cache is better than the simple cache (above) if you're + running a web crawler or other process that does a lot of + resolutions. The LRUCache has a maximum number of nodes, and when + it is full, the least-recently used node is removed to make space + for a new one. + """ + + def __init__(self, max_size=100000): + """*max_size*, an ``int``, is the maximum number of nodes to cache; + it must be greater than 0. + """ + + self.data = {} + self.set_max_size(max_size) + self.sentinel = LRUCacheNode(None, None) + self.lock = _threading.Lock() + + def set_max_size(self, max_size): + if max_size < 1: + max_size = 1 + self.max_size = max_size + + def get(self, key): + """Get the answer associated with *key*. + + Returns None if no answer is cached for the key. + + *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the + query name, rdtype, and rdclass respectively. + + Returns a ``dns.resolver.Answer`` or ``None``. + """ + + try: + self.lock.acquire() + node = self.data.get(key) + if node is None: + return None + # Unlink because we're either going to move the node to the front + # of the LRU list or we're going to free it. + node.unlink() + if node.value.expiration <= time.time(): + del self.data[node.key] + return None + node.link_after(self.sentinel) + return node.value + finally: + self.lock.release() + + def put(self, key, value): + """Associate key and value in the cache. + + *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the + query name, rdtype, and rdclass respectively. + + *value*, a ``dns.resolver.Answer``, the answer. + """ + + try: + self.lock.acquire() + node = self.data.get(key) + if node is not None: + node.unlink() + del self.data[node.key] + while len(self.data) >= self.max_size: + node = self.sentinel.prev + node.unlink() + del self.data[node.key] + node = LRUCacheNode(key, value) + node.link_after(self.sentinel) + self.data[key] = node + finally: + self.lock.release() + + def flush(self, key=None): + """Flush the cache. + + If *key* is not ``None``, only that item is flushed. Otherwise + the entire cache is flushed. + + *key*, a ``(dns.name.Name, int, int)`` tuple whose values are the + query name, rdtype, and rdclass respectively. + """ + + try: + self.lock.acquire() + if key is not None: + node = self.data.get(key) + if node is not None: + node.unlink() + del self.data[node.key] + else: + node = self.sentinel.next + while node != self.sentinel: + next = node.next + node.prev = None + node.next = None + node = next + self.data = {} + finally: + self.lock.release() + + +class Resolver(object): + """DNS stub resolver.""" + + def __init__(self, filename='/etc/resolv.conf', configure=True): + """*filename*, a ``text`` or file object, specifying a file + in standard /etc/resolv.conf format. This parameter is meaningful + only when *configure* is true and the platform is POSIX. + + *configure*, a ``bool``. If True (the default), the resolver + instance is configured in the normal fashion for the operating + system the resolver is running on. (I.e. by reading a + /etc/resolv.conf file on POSIX systems and from the registry + on Windows systems.) + """ + + self.domain = None + self.nameservers = None + self.nameserver_ports = None + self.port = None + self.search = None + self.timeout = None + self.lifetime = None + self.keyring = None + self.keyname = None + self.keyalgorithm = None + self.edns = None + self.ednsflags = None + self.payload = None + self.cache = None + self.flags = None + self.retry_servfail = False + self.rotate = False + + self.reset() + if configure: + if sys.platform == 'win32': + self.read_registry() + elif filename: + self.read_resolv_conf(filename) + + def reset(self): + """Reset all resolver configuration to the defaults.""" + + self.domain = \ + dns.name.Name(dns.name.from_text(socket.gethostname())[1:]) + if len(self.domain) == 0: + self.domain = dns.name.root + self.nameservers = [] + self.nameserver_ports = {} + self.port = 53 + self.search = [] + self.timeout = 2.0 + self.lifetime = 30.0 + self.keyring = None + self.keyname = None + self.keyalgorithm = dns.tsig.default_algorithm + self.edns = -1 + self.ednsflags = 0 + self.payload = 0 + self.cache = None + self.flags = None + self.retry_servfail = False + self.rotate = False + + def read_resolv_conf(self, f): + """Process *f* as a file in the /etc/resolv.conf format. If f is + a ``text``, it is used as the name of the file to open; otherwise it + is treated as the file itself.""" + + if isinstance(f, string_types): + try: + f = open(f, 'r') + except IOError: + # /etc/resolv.conf doesn't exist, can't be read, etc. + # We'll just use the default resolver configuration. + self.nameservers = ['127.0.0.1'] + return + want_close = True + else: + want_close = False + try: + for l in f: + if len(l) == 0 or l[0] == '#' or l[0] == ';': + continue + tokens = l.split() + + # Any line containing less than 2 tokens is malformed + if len(tokens) < 2: + continue + + if tokens[0] == 'nameserver': + self.nameservers.append(tokens[1]) + elif tokens[0] == 'domain': + self.domain = dns.name.from_text(tokens[1]) + elif tokens[0] == 'search': + for suffix in tokens[1:]: + self.search.append(dns.name.from_text(suffix)) + elif tokens[0] == 'options': + if 'rotate' in tokens[1:]: + self.rotate = True + finally: + if want_close: + f.close() + if len(self.nameservers) == 0: + self.nameservers.append('127.0.0.1') + + def _determine_split_char(self, entry): + # + # The windows registry irritatingly changes the list element + # delimiter in between ' ' and ',' (and vice-versa) in various + # versions of windows. + # + if entry.find(' ') >= 0: + split_char = ' ' + elif entry.find(',') >= 0: + split_char = ',' + else: + # probably a singleton; treat as a space-separated list. + split_char = ' ' + return split_char + + def _config_win32_nameservers(self, nameservers): + # we call str() on nameservers to convert it from unicode to ascii + nameservers = str(nameservers) + split_char = self._determine_split_char(nameservers) + ns_list = nameservers.split(split_char) + for ns in ns_list: + if ns not in self.nameservers: + self.nameservers.append(ns) + + def _config_win32_domain(self, domain): + # we call str() on domain to convert it from unicode to ascii + self.domain = dns.name.from_text(str(domain)) + + def _config_win32_search(self, search): + # we call str() on search to convert it from unicode to ascii + search = str(search) + split_char = self._determine_split_char(search) + search_list = search.split(split_char) + for s in search_list: + if s not in self.search: + self.search.append(dns.name.from_text(s)) + + def _config_win32_fromkey(self, key, always_try_domain): + try: + servers, rtype = _winreg.QueryValueEx(key, 'NameServer') + except WindowsError: # pylint: disable=undefined-variable + servers = None + if servers: + self._config_win32_nameservers(servers) + if servers or always_try_domain: + try: + dom, rtype = _winreg.QueryValueEx(key, 'Domain') + if dom: + self._config_win32_domain(dom) + except WindowsError: # pylint: disable=undefined-variable + pass + else: + try: + servers, rtype = _winreg.QueryValueEx(key, 'DhcpNameServer') + except WindowsError: # pylint: disable=undefined-variable + servers = None + if servers: + self._config_win32_nameservers(servers) + try: + dom, rtype = _winreg.QueryValueEx(key, 'DhcpDomain') + if dom: + self._config_win32_domain(dom) + except WindowsError: # pylint: disable=undefined-variable + pass + try: + search, rtype = _winreg.QueryValueEx(key, 'SearchList') + except WindowsError: # pylint: disable=undefined-variable + search = None + if search: + self._config_win32_search(search) + + def read_registry(self): + """Extract resolver configuration from the Windows registry.""" + + lm = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE) + want_scan = False + try: + try: + # XP, 2000 + tcp_params = _winreg.OpenKey(lm, + r'SYSTEM\CurrentControlSet' + r'\Services\Tcpip\Parameters') + want_scan = True + except EnvironmentError: + # ME + tcp_params = _winreg.OpenKey(lm, + r'SYSTEM\CurrentControlSet' + r'\Services\VxD\MSTCP') + try: + self._config_win32_fromkey(tcp_params, True) + finally: + tcp_params.Close() + if want_scan: + interfaces = _winreg.OpenKey(lm, + r'SYSTEM\CurrentControlSet' + r'\Services\Tcpip\Parameters' + r'\Interfaces') + try: + i = 0 + while True: + try: + guid = _winreg.EnumKey(interfaces, i) + i += 1 + key = _winreg.OpenKey(interfaces, guid) + if not self._win32_is_nic_enabled(lm, guid, key): + continue + try: + self._config_win32_fromkey(key, False) + finally: + key.Close() + except EnvironmentError: + break + finally: + interfaces.Close() + finally: + lm.Close() + + def _win32_is_nic_enabled(self, lm, guid, interface_key): + # Look in the Windows Registry to determine whether the network + # interface corresponding to the given guid is enabled. + # + # (Code contributed by Paul Marks, thanks!) + # + try: + # This hard-coded location seems to be consistent, at least + # from Windows 2000 through Vista. + connection_key = _winreg.OpenKey( + lm, + r'SYSTEM\CurrentControlSet\Control\Network' + r'\{4D36E972-E325-11CE-BFC1-08002BE10318}' + r'\%s\Connection' % guid) + + try: + # The PnpInstanceID points to a key inside Enum + (pnp_id, ttype) = _winreg.QueryValueEx( + connection_key, 'PnpInstanceID') + + if ttype != _winreg.REG_SZ: + raise ValueError + + device_key = _winreg.OpenKey( + lm, r'SYSTEM\CurrentControlSet\Enum\%s' % pnp_id) + + try: + # Get ConfigFlags for this device + (flags, ttype) = _winreg.QueryValueEx( + device_key, 'ConfigFlags') + + if ttype != _winreg.REG_DWORD: + raise ValueError + + # Based on experimentation, bit 0x1 indicates that the + # device is disabled. + return not flags & 0x1 + + finally: + device_key.Close() + finally: + connection_key.Close() + except (EnvironmentError, ValueError): + # Pre-vista, enabled interfaces seem to have a non-empty + # NTEContextList; this was how dnspython detected enabled + # nics before the code above was contributed. We've retained + # the old method since we don't know if the code above works + # on Windows 95/98/ME. + try: + (nte, ttype) = _winreg.QueryValueEx(interface_key, + 'NTEContextList') + return nte is not None + except WindowsError: # pylint: disable=undefined-variable + return False + + def _compute_timeout(self, start, lifetime=None): + lifetime = self.lifetime if lifetime is None else lifetime + now = time.time() + duration = now - start + if duration < 0: + if duration < -1: + # Time going backwards is bad. Just give up. + raise Timeout(timeout=duration) + else: + # Time went backwards, but only a little. This can + # happen, e.g. under vmware with older linux kernels. + # Pretend it didn't happen. + now = start + if duration >= lifetime: + raise Timeout(timeout=duration) + return min(lifetime - duration, self.timeout) + + def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, + tcp=False, source=None, raise_on_no_answer=True, source_port=0, + lifetime=None): + """Query nameservers to find the answer to the question. + + The *qname*, *rdtype*, and *rdclass* parameters may be objects + of the appropriate type, or strings that can be converted into objects + of the appropriate type. + + *qname*, a ``dns.name.Name`` or ``text``, the query name. + + *rdtype*, an ``int`` or ``text``, the query type. + + *rdclass*, an ``int`` or ``text``, the query class. + + *tcp*, a ``bool``. If ``True``, use TCP to make the query. + + *source*, a ``text`` or ``None``. If not ``None``, bind to this IP + address when making queries. + + *raise_on_no_answer*, a ``bool``. If ``True``, raise + ``dns.resolver.NoAnswer`` if there's no answer to the question. + + *source_port*, an ``int``, the port from which to send the message. + + *lifetime*, a ``float``, how long query should run before timing out. + + Raises ``dns.exception.Timeout`` if no answers could be found + in the specified lifetime. + + Raises ``dns.resolver.NXDOMAIN`` if the query name does not exist. + + Raises ``dns.resolver.YXDOMAIN`` if the query name is too long after + DNAME substitution. + + Raises ``dns.resolver.NoAnswer`` if *raise_on_no_answer* is + ``True`` and the query name exists but has no RRset of the + desired type and class. + + Raises ``dns.resolver.NoNameservers`` if no non-broken + nameservers are available to answer the question. + + Returns a ``dns.resolver.Answer`` instance. + """ + + if isinstance(qname, string_types): + qname = dns.name.from_text(qname, None) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if dns.rdatatype.is_metatype(rdtype): + raise NoMetaqueries + if isinstance(rdclass, string_types): + rdclass = dns.rdataclass.from_text(rdclass) + if dns.rdataclass.is_metaclass(rdclass): + raise NoMetaqueries + qnames_to_try = [] + if qname.is_absolute(): + qnames_to_try.append(qname) + else: + if len(qname) > 1: + qnames_to_try.append(qname.concatenate(dns.name.root)) + if self.search: + for suffix in self.search: + qnames_to_try.append(qname.concatenate(suffix)) + else: + qnames_to_try.append(qname.concatenate(self.domain)) + all_nxdomain = True + nxdomain_responses = {} + start = time.time() + _qname = None # make pylint happy + for _qname in qnames_to_try: + if self.cache: + answer = self.cache.get((_qname, rdtype, rdclass)) + if answer is not None: + if answer.rrset is None and raise_on_no_answer: + raise NoAnswer(response=answer.response) + else: + return answer + request = dns.message.make_query(_qname, rdtype, rdclass) + if self.keyname is not None: + request.use_tsig(self.keyring, self.keyname, + algorithm=self.keyalgorithm) + request.use_edns(self.edns, self.ednsflags, self.payload) + if self.flags is not None: + request.flags = self.flags + response = None + # + # make a copy of the servers list so we can alter it later. + # + nameservers = self.nameservers[:] + errors = [] + if self.rotate: + random.shuffle(nameservers) + backoff = 0.10 + while response is None: + if len(nameservers) == 0: + raise NoNameservers(request=request, errors=errors) + for nameserver in nameservers[:]: + timeout = self._compute_timeout(start, lifetime) + port = self.nameserver_ports.get(nameserver, self.port) + try: + tcp_attempt = tcp + if tcp: + response = dns.query.tcp(request, nameserver, + timeout, port, + source=source, + source_port=source_port) + else: + response = dns.query.udp(request, nameserver, + timeout, port, + source=source, + source_port=source_port) + if response.flags & dns.flags.TC: + # Response truncated; retry with TCP. + tcp_attempt = True + timeout = self._compute_timeout(start, lifetime) + response = \ + dns.query.tcp(request, nameserver, + timeout, port, + source=source, + source_port=source_port) + except (socket.error, dns.exception.Timeout) as ex: + # + # Communication failure or timeout. Go to the + # next server + # + errors.append((nameserver, tcp_attempt, port, ex, + response)) + response = None + continue + except dns.query.UnexpectedSource as ex: + # + # Who knows? Keep going. + # + errors.append((nameserver, tcp_attempt, port, ex, + response)) + response = None + continue + except dns.exception.FormError as ex: + # + # We don't understand what this server is + # saying. Take it out of the mix and + # continue. + # + nameservers.remove(nameserver) + errors.append((nameserver, tcp_attempt, port, ex, + response)) + response = None + continue + except EOFError as ex: + # + # We're using TCP and they hung up on us. + # Probably they don't support TCP (though + # they're supposed to!). Take it out of the + # mix and continue. + # + nameservers.remove(nameserver) + errors.append((nameserver, tcp_attempt, port, ex, + response)) + response = None + continue + rcode = response.rcode() + if rcode == dns.rcode.YXDOMAIN: + ex = YXDOMAIN() + errors.append((nameserver, tcp_attempt, port, ex, + response)) + raise ex + if rcode == dns.rcode.NOERROR or \ + rcode == dns.rcode.NXDOMAIN: + break + # + # We got a response, but we're not happy with the + # rcode in it. Remove the server from the mix if + # the rcode isn't SERVFAIL. + # + if rcode != dns.rcode.SERVFAIL or not self.retry_servfail: + nameservers.remove(nameserver) + errors.append((nameserver, tcp_attempt, port, + dns.rcode.to_text(rcode), response)) + response = None + if response is not None: + break + # + # All nameservers failed! + # + if len(nameservers) > 0: + # + # But we still have servers to try. Sleep a bit + # so we don't pound them! + # + timeout = self._compute_timeout(start, lifetime) + sleep_time = min(timeout, backoff) + backoff *= 2 + time.sleep(sleep_time) + if response.rcode() == dns.rcode.NXDOMAIN: + nxdomain_responses[_qname] = response + continue + all_nxdomain = False + break + if all_nxdomain: + raise NXDOMAIN(qnames=qnames_to_try, responses=nxdomain_responses) + answer = Answer(_qname, rdtype, rdclass, response, + raise_on_no_answer) + if self.cache: + self.cache.put((_qname, rdtype, rdclass), answer) + return answer + + def use_tsig(self, keyring, keyname=None, + algorithm=dns.tsig.default_algorithm): + """Add a TSIG signature to the query. + + See the documentation of the Message class for a complete + description of the keyring dictionary. + + *keyring*, a ``dict``, the TSIG keyring to use. If a + *keyring* is specified but a *keyname* is not, then the key + used will be the first key in the *keyring*. Note that the + order of keys in a dictionary is not defined, so applications + should supply a keyname when a keyring is used, unless they + know the keyring contains only one key. + + *keyname*, a ``dns.name.Name`` or ``None``, the name of the TSIG key + to use; defaults to ``None``. The key must be defined in the keyring. + + *algorithm*, a ``dns.name.Name``, the TSIG algorithm to use. + """ + + self.keyring = keyring + if keyname is None: + self.keyname = list(self.keyring.keys())[0] + else: + self.keyname = keyname + self.keyalgorithm = algorithm + + def use_edns(self, edns, ednsflags, payload): + """Configure EDNS behavior. + + *edns*, an ``int``, is the EDNS level to use. Specifying + ``None``, ``False``, or ``-1`` means "do not use EDNS", and in this case + the other parameters are ignored. Specifying ``True`` is + equivalent to specifying 0, i.e. "use EDNS0". + + *ednsflags*, an ``int``, the EDNS flag values. + + *payload*, an ``int``, is the EDNS sender's payload field, which is the + maximum size of UDP datagram the sender can handle. I.e. how big + a response to this message can be. + """ + + if edns is None: + edns = -1 + self.edns = edns + self.ednsflags = ednsflags + self.payload = payload + + def set_flags(self, flags): + """Overrides the default flags with your own. + + *flags*, an ``int``, the message flags to use. + """ + + self.flags = flags + + +#: The default resolver. +default_resolver = None + + +def get_default_resolver(): + """Get the default resolver, initializing it if necessary.""" + if default_resolver is None: + reset_default_resolver() + return default_resolver + + +def reset_default_resolver(): + """Re-initialize default resolver. + + Note that the resolver configuration (i.e. /etc/resolv.conf on UNIX + systems) will be re-read immediately. + """ + + global default_resolver + default_resolver = Resolver() + + +def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, + tcp=False, source=None, raise_on_no_answer=True, + source_port=0, lifetime=None): + """Query nameservers to find the answer to the question. + + This is a convenience function that uses the default resolver + object to make the query. + + See ``dns.resolver.Resolver.query`` for more information on the + parameters. + """ + + return get_default_resolver().query(qname, rdtype, rdclass, tcp, source, + raise_on_no_answer, source_port, + lifetime) + + +def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None): + """Find the name of the zone which contains the specified name. + + *name*, an absolute ``dns.name.Name`` or ``text``, the query name. + + *rdclass*, an ``int``, the query class. + + *tcp*, a ``bool``. If ``True``, use TCP to make the query. + + *resolver*, a ``dns.resolver.Resolver`` or ``None``, the resolver to use. + If ``None``, the default resolver is used. + + Raises ``dns.resolver.NoRootSOA`` if there is no SOA RR at the DNS + root. (This is only likely to happen if you're using non-default + root servers in your network and they are misconfigured.) + + Returns a ``dns.name.Name``. + """ + + if isinstance(name, string_types): + name = dns.name.from_text(name, dns.name.root) + if resolver is None: + resolver = get_default_resolver() + if not name.is_absolute(): + raise NotAbsolute(name) + while 1: + try: + answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp) + if answer.rrset.name == name: + return name + # otherwise we were CNAMEd or DNAMEd and need to look higher + except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): + pass + try: + name = name.parent() + except dns.name.NoParent: + raise NoRootSOA + +# +# Support for overriding the system resolver for all python code in the +# running process. +# + +_protocols_for_socktype = { + socket.SOCK_DGRAM: [socket.SOL_UDP], + socket.SOCK_STREAM: [socket.SOL_TCP], +} + +_resolver = None +_original_getaddrinfo = socket.getaddrinfo +_original_getnameinfo = socket.getnameinfo +_original_getfqdn = socket.getfqdn +_original_gethostbyname = socket.gethostbyname +_original_gethostbyname_ex = socket.gethostbyname_ex +_original_gethostbyaddr = socket.gethostbyaddr + + +def _getaddrinfo(host=None, service=None, family=socket.AF_UNSPEC, socktype=0, + proto=0, flags=0): + if flags & (socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) != 0: + raise NotImplementedError + if host is None and service is None: + raise socket.gaierror(socket.EAI_NONAME) + v6addrs = [] + v4addrs = [] + canonical_name = None + try: + # Is host None or a V6 address literal? + if host is None: + canonical_name = 'localhost' + if flags & socket.AI_PASSIVE != 0: + v6addrs.append('::') + v4addrs.append('0.0.0.0') + else: + v6addrs.append('::1') + v4addrs.append('127.0.0.1') + else: + parts = host.split('%') + if len(parts) == 2: + ahost = parts[0] + else: + ahost = host + addr = dns.ipv6.inet_aton(ahost) + v6addrs.append(host) + canonical_name = host + except Exception: + try: + # Is it a V4 address literal? + addr = dns.ipv4.inet_aton(host) + v4addrs.append(host) + canonical_name = host + except Exception: + if flags & socket.AI_NUMERICHOST == 0: + try: + if family == socket.AF_INET6 or family == socket.AF_UNSPEC: + v6 = _resolver.query(host, dns.rdatatype.AAAA, + raise_on_no_answer=False) + # Note that setting host ensures we query the same name + # for A as we did for AAAA. + host = v6.qname + canonical_name = v6.canonical_name.to_text(True) + if v6.rrset is not None: + for rdata in v6.rrset: + v6addrs.append(rdata.address) + if family == socket.AF_INET or family == socket.AF_UNSPEC: + v4 = _resolver.query(host, dns.rdatatype.A, + raise_on_no_answer=False) + host = v4.qname + canonical_name = v4.canonical_name.to_text(True) + if v4.rrset is not None: + for rdata in v4.rrset: + v4addrs.append(rdata.address) + except dns.resolver.NXDOMAIN: + raise socket.gaierror(socket.EAI_NONAME) + except Exception: + raise socket.gaierror(socket.EAI_SYSTEM) + port = None + try: + # Is it a port literal? + if service is None: + port = 0 + else: + port = int(service) + except Exception: + if flags & socket.AI_NUMERICSERV == 0: + try: + port = socket.getservbyname(service) + except Exception: + pass + if port is None: + raise socket.gaierror(socket.EAI_NONAME) + tuples = [] + if socktype == 0: + socktypes = [socket.SOCK_DGRAM, socket.SOCK_STREAM] + else: + socktypes = [socktype] + if flags & socket.AI_CANONNAME != 0: + cname = canonical_name + else: + cname = '' + if family == socket.AF_INET6 or family == socket.AF_UNSPEC: + for addr in v6addrs: + for socktype in socktypes: + for proto in _protocols_for_socktype[socktype]: + tuples.append((socket.AF_INET6, socktype, proto, + cname, (addr, port, 0, 0))) + if family == socket.AF_INET or family == socket.AF_UNSPEC: + for addr in v4addrs: + for socktype in socktypes: + for proto in _protocols_for_socktype[socktype]: + tuples.append((socket.AF_INET, socktype, proto, + cname, (addr, port))) + if len(tuples) == 0: + raise socket.gaierror(socket.EAI_NONAME) + return tuples + + +def _getnameinfo(sockaddr, flags=0): + host = sockaddr[0] + port = sockaddr[1] + if len(sockaddr) == 4: + scope = sockaddr[3] + family = socket.AF_INET6 + else: + scope = None + family = socket.AF_INET + tuples = _getaddrinfo(host, port, family, socket.SOCK_STREAM, + socket.SOL_TCP, 0) + if len(tuples) > 1: + raise socket.error('sockaddr resolved to multiple addresses') + addr = tuples[0][4][0] + if flags & socket.NI_DGRAM: + pname = 'udp' + else: + pname = 'tcp' + qname = dns.reversename.from_address(addr) + if flags & socket.NI_NUMERICHOST == 0: + try: + answer = _resolver.query(qname, 'PTR') + hostname = answer.rrset[0].target.to_text(True) + except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer): + if flags & socket.NI_NAMEREQD: + raise socket.gaierror(socket.EAI_NONAME) + hostname = addr + if scope is not None: + hostname += '%' + str(scope) + else: + hostname = addr + if scope is not None: + hostname += '%' + str(scope) + if flags & socket.NI_NUMERICSERV: + service = str(port) + else: + service = socket.getservbyport(port, pname) + return (hostname, service) + + +def _getfqdn(name=None): + if name is None: + name = socket.gethostname() + try: + return _getnameinfo(_getaddrinfo(name, 80)[0][4])[0] + except Exception: + return name + + +def _gethostbyname(name): + return _gethostbyname_ex(name)[2][0] + + +def _gethostbyname_ex(name): + aliases = [] + addresses = [] + tuples = _getaddrinfo(name, 0, socket.AF_INET, socket.SOCK_STREAM, + socket.SOL_TCP, socket.AI_CANONNAME) + canonical = tuples[0][3] + for item in tuples: + addresses.append(item[4][0]) + # XXX we just ignore aliases + return (canonical, aliases, addresses) + + +def _gethostbyaddr(ip): + try: + dns.ipv6.inet_aton(ip) + sockaddr = (ip, 80, 0, 0) + family = socket.AF_INET6 + except Exception: + sockaddr = (ip, 80) + family = socket.AF_INET + (name, port) = _getnameinfo(sockaddr, socket.NI_NAMEREQD) + aliases = [] + addresses = [] + tuples = _getaddrinfo(name, 0, family, socket.SOCK_STREAM, socket.SOL_TCP, + socket.AI_CANONNAME) + canonical = tuples[0][3] + for item in tuples: + addresses.append(item[4][0]) + # XXX we just ignore aliases + return (canonical, aliases, addresses) + + +def override_system_resolver(resolver=None): + """Override the system resolver routines in the socket module with + versions which use dnspython's resolver. + + This can be useful in testing situations where you want to control + the resolution behavior of python code without having to change + the system's resolver settings (e.g. /etc/resolv.conf). + + The resolver to use may be specified; if it's not, the default + resolver will be used. + + resolver, a ``dns.resolver.Resolver`` or ``None``, the resolver to use. + """ + + if resolver is None: + resolver = get_default_resolver() + global _resolver + _resolver = resolver + socket.getaddrinfo = _getaddrinfo + socket.getnameinfo = _getnameinfo + socket.getfqdn = _getfqdn + socket.gethostbyname = _gethostbyname + socket.gethostbyname_ex = _gethostbyname_ex + socket.gethostbyaddr = _gethostbyaddr + + +def restore_system_resolver(): + """Undo the effects of prior override_system_resolver().""" + + global _resolver + _resolver = None + socket.getaddrinfo = _original_getaddrinfo + socket.getnameinfo = _original_getnameinfo + socket.getfqdn = _original_getfqdn + socket.gethostbyname = _original_gethostbyname + socket.gethostbyname_ex = _original_gethostbyname_ex + socket.gethostbyaddr = _original_gethostbyaddr diff --git a/env/lib/python3.7/site-packages/dns/reversename.py b/env/lib/python3.7/site-packages/dns/reversename.py new file mode 100644 index 0000000..8f095fa --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/reversename.py @@ -0,0 +1,96 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2006-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Reverse Map Names.""" + +import binascii + +import dns.name +import dns.ipv6 +import dns.ipv4 + +from dns._compat import PY3 + +ipv4_reverse_domain = dns.name.from_text('in-addr.arpa.') +ipv6_reverse_domain = dns.name.from_text('ip6.arpa.') + + +def from_address(text): + """Convert an IPv4 or IPv6 address in textual form into a Name object whose + value is the reverse-map domain name of the address. + + *text*, a ``text``, is an IPv4 or IPv6 address in textual form + (e.g. '127.0.0.1', '::1') + + Raises ``dns.exception.SyntaxError`` if the address is badly formed. + + Returns a ``dns.name.Name``. + """ + + try: + v6 = dns.ipv6.inet_aton(text) + if dns.ipv6.is_mapped(v6): + if PY3: + parts = ['%d' % byte for byte in v6[12:]] + else: + parts = ['%d' % ord(byte) for byte in v6[12:]] + origin = ipv4_reverse_domain + else: + parts = [x for x in str(binascii.hexlify(v6).decode())] + origin = ipv6_reverse_domain + except Exception: + parts = ['%d' % + byte for byte in bytearray(dns.ipv4.inet_aton(text))] + origin = ipv4_reverse_domain + parts.reverse() + return dns.name.from_text('.'.join(parts), origin=origin) + + +def to_address(name): + """Convert a reverse map domain name into textual address form. + + *name*, a ``dns.name.Name``, an IPv4 or IPv6 address in reverse-map name + form. + + Raises ``dns.exception.SyntaxError`` if the name does not have a + reverse-map form. + + Returns a ``text``. + """ + + if name.is_subdomain(ipv4_reverse_domain): + name = name.relativize(ipv4_reverse_domain) + labels = list(name.labels) + labels.reverse() + text = b'.'.join(labels) + # run through inet_aton() to check syntax and make pretty. + return dns.ipv4.inet_ntoa(dns.ipv4.inet_aton(text)) + elif name.is_subdomain(ipv6_reverse_domain): + name = name.relativize(ipv6_reverse_domain) + labels = list(name.labels) + labels.reverse() + parts = [] + i = 0 + l = len(labels) + while i < l: + parts.append(b''.join(labels[i:i + 4])) + i += 4 + text = b':'.join(parts) + # run through inet_aton() to check syntax and make pretty. + return dns.ipv6.inet_ntoa(dns.ipv6.inet_aton(text)) + else: + raise dns.exception.SyntaxError('unknown reverse-map address family') diff --git a/env/lib/python3.7/site-packages/dns/rrset.py b/env/lib/python3.7/site-packages/dns/rrset.py new file mode 100644 index 0000000..a53ec32 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/rrset.py @@ -0,0 +1,189 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS RRsets (an RRset is a named rdataset)""" + + +import dns.name +import dns.rdataset +import dns.rdataclass +import dns.renderer +from ._compat import string_types + + +class RRset(dns.rdataset.Rdataset): + + """A DNS RRset (named rdataset). + + RRset inherits from Rdataset, and RRsets can be treated as + Rdatasets in most cases. There are, however, a few notable + exceptions. RRsets have different to_wire() and to_text() method + arguments, reflecting the fact that RRsets always have an owner + name. + """ + + __slots__ = ['name', 'deleting'] + + def __init__(self, name, rdclass, rdtype, covers=dns.rdatatype.NONE, + deleting=None): + """Create a new RRset.""" + + super(RRset, self).__init__(rdclass, rdtype, covers) + self.name = name + self.deleting = deleting + + def _clone(self): + obj = super(RRset, self)._clone() + obj.name = self.name + obj.deleting = self.deleting + return obj + + def __repr__(self): + if self.covers == 0: + ctext = '' + else: + ctext = '(' + dns.rdatatype.to_text(self.covers) + ')' + if self.deleting is not None: + dtext = ' delete=' + dns.rdataclass.to_text(self.deleting) + else: + dtext = '' + return '' + + def __str__(self): + return self.to_text() + + def __eq__(self, other): + if not isinstance(other, RRset): + return False + if self.name != other.name: + return False + return super(RRset, self).__eq__(other) + + def match(self, name, rdclass, rdtype, covers, deleting=None): + """Returns ``True`` if this rrset matches the specified class, type, + covers, and deletion state. + """ + + if not super(RRset, self).match(rdclass, rdtype, covers): + return False + if self.name != name or self.deleting != deleting: + return False + return True + + def to_text(self, origin=None, relativize=True, **kw): + """Convert the RRset into DNS master file format. + + See ``dns.name.Name.choose_relativity`` for more information + on how *origin* and *relativize* determine the way names + are emitted. + + Any additional keyword arguments are passed on to the rdata + ``to_text()`` method. + + *origin*, a ``dns.name.Name`` or ``None``, the origin for relative + names. + + *relativize*, a ``bool``. If ``True``, names will be relativized + to *origin*. + """ + + return super(RRset, self).to_text(self.name, origin, relativize, + self.deleting, **kw) + + def to_wire(self, file, compress=None, origin=None, **kw): + """Convert the RRset to wire format. + + All keyword arguments are passed to ``dns.rdataset.to_wire()``; see + that function for details. + + Returns an ``int``, the number of records emitted. + """ + + return super(RRset, self).to_wire(self.name, file, compress, origin, + self.deleting, **kw) + + def to_rdataset(self): + """Convert an RRset into an Rdataset. + + Returns a ``dns.rdataset.Rdataset``. + """ + return dns.rdataset.from_rdata_list(self.ttl, list(self)) + + +def from_text_list(name, ttl, rdclass, rdtype, text_rdatas, + idna_codec=None): + """Create an RRset with the specified name, TTL, class, and type, and with + the specified list of rdatas in text format. + + Returns a ``dns.rrset.RRset`` object. + """ + + if isinstance(name, string_types): + name = dns.name.from_text(name, None, idna_codec=idna_codec) + if isinstance(rdclass, string_types): + rdclass = dns.rdataclass.from_text(rdclass) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + r = RRset(name, rdclass, rdtype) + r.update_ttl(ttl) + for t in text_rdatas: + rd = dns.rdata.from_text(r.rdclass, r.rdtype, t) + r.add(rd) + return r + + +def from_text(name, ttl, rdclass, rdtype, *text_rdatas): + """Create an RRset with the specified name, TTL, class, and type and with + the specified rdatas in text format. + + Returns a ``dns.rrset.RRset`` object. + """ + + return from_text_list(name, ttl, rdclass, rdtype, text_rdatas) + + +def from_rdata_list(name, ttl, rdatas, idna_codec=None): + """Create an RRset with the specified name and TTL, and with + the specified list of rdata objects. + + Returns a ``dns.rrset.RRset`` object. + """ + + if isinstance(name, string_types): + name = dns.name.from_text(name, None, idna_codec=idna_codec) + + if len(rdatas) == 0: + raise ValueError("rdata list must not be empty") + r = None + for rd in rdatas: + if r is None: + r = RRset(name, rd.rdclass, rd.rdtype) + r.update_ttl(ttl) + r.add(rd) + return r + + +def from_rdata(name, ttl, *rdatas): + """Create an RRset with the specified name and TTL, and with + the specified rdata objects. + + Returns a ``dns.rrset.RRset`` object. + """ + + return from_rdata_list(name, ttl, rdatas) diff --git a/env/lib/python3.7/site-packages/dns/set.py b/env/lib/python3.7/site-packages/dns/set.py new file mode 100644 index 0000000..81329bf --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/set.py @@ -0,0 +1,261 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +class Set(object): + + """A simple set class. + + This class was originally used to deal with sets being missing in + ancient versions of python, but dnspython will continue to use it + as these sets are based on lists and are thus indexable, and this + ability is widely used in dnspython applications. + """ + + __slots__ = ['items'] + + def __init__(self, items=None): + """Initialize the set. + + *items*, an iterable or ``None``, the initial set of items. + """ + + self.items = [] + if items is not None: + for item in items: + self.add(item) + + def __repr__(self): + return "dns.simpleset.Set(%s)" % repr(self.items) + + def add(self, item): + """Add an item to the set. + """ + + if item not in self.items: + self.items.append(item) + + def remove(self, item): + """Remove an item from the set. + """ + + self.items.remove(item) + + def discard(self, item): + """Remove an item from the set if present. + """ + + try: + self.items.remove(item) + except ValueError: + pass + + def _clone(self): + """Make a (shallow) copy of the set. + + There is a 'clone protocol' that subclasses of this class + should use. To make a copy, first call your super's _clone() + method, and use the object returned as the new instance. Then + make shallow copies of the attributes defined in the subclass. + + This protocol allows us to write the set algorithms that + return new instances (e.g. union) once, and keep using them in + subclasses. + """ + + cls = self.__class__ + obj = cls.__new__(cls) + obj.items = list(self.items) + return obj + + def __copy__(self): + """Make a (shallow) copy of the set. + """ + + return self._clone() + + def copy(self): + """Make a (shallow) copy of the set. + """ + + return self._clone() + + def union_update(self, other): + """Update the set, adding any elements from other which are not + already in the set. + """ + + if not isinstance(other, Set): + raise ValueError('other must be a Set instance') + if self is other: + return + for item in other.items: + self.add(item) + + def intersection_update(self, other): + """Update the set, removing any elements from other which are not + in both sets. + """ + + if not isinstance(other, Set): + raise ValueError('other must be a Set instance') + if self is other: + return + # we make a copy of the list so that we can remove items from + # the list without breaking the iterator. + for item in list(self.items): + if item not in other.items: + self.items.remove(item) + + def difference_update(self, other): + """Update the set, removing any elements from other which are in + the set. + """ + + if not isinstance(other, Set): + raise ValueError('other must be a Set instance') + if self is other: + self.items = [] + else: + for item in other.items: + self.discard(item) + + def union(self, other): + """Return a new set which is the union of ``self`` and ``other``. + + Returns the same Set type as this set. + """ + + obj = self._clone() + obj.union_update(other) + return obj + + def intersection(self, other): + """Return a new set which is the intersection of ``self`` and + ``other``. + + Returns the same Set type as this set. + """ + + obj = self._clone() + obj.intersection_update(other) + return obj + + def difference(self, other): + """Return a new set which ``self`` - ``other``, i.e. the items + in ``self`` which are not also in ``other``. + + Returns the same Set type as this set. + """ + + obj = self._clone() + obj.difference_update(other) + return obj + + def __or__(self, other): + return self.union(other) + + def __and__(self, other): + return self.intersection(other) + + def __add__(self, other): + return self.union(other) + + def __sub__(self, other): + return self.difference(other) + + def __ior__(self, other): + self.union_update(other) + return self + + def __iand__(self, other): + self.intersection_update(other) + return self + + def __iadd__(self, other): + self.union_update(other) + return self + + def __isub__(self, other): + self.difference_update(other) + return self + + def update(self, other): + """Update the set, adding any elements from other which are not + already in the set. + + *other*, the collection of items with which to update the set, which + may be any iterable type. + """ + + for item in other: + self.add(item) + + def clear(self): + """Make the set empty.""" + self.items = [] + + def __eq__(self, other): + # Yes, this is inefficient but the sets we're dealing with are + # usually quite small, so it shouldn't hurt too much. + for item in self.items: + if item not in other.items: + return False + for item in other.items: + if item not in self.items: + return False + return True + + def __ne__(self, other): + return not self.__eq__(other) + + def __len__(self): + return len(self.items) + + def __iter__(self): + return iter(self.items) + + def __getitem__(self, i): + return self.items[i] + + def __delitem__(self, i): + del self.items[i] + + def issubset(self, other): + """Is this set a subset of *other*? + + Returns a ``bool``. + """ + + if not isinstance(other, Set): + raise ValueError('other must be a Set instance') + for item in self.items: + if item not in other.items: + return False + return True + + def issuperset(self, other): + """Is this set a superset of *other*? + + Returns a ``bool``. + """ + + if not isinstance(other, Set): + raise ValueError('other must be a Set instance') + for item in other.items: + if item not in self.items: + return False + return True diff --git a/env/lib/python3.7/site-packages/dns/tokenizer.py b/env/lib/python3.7/site-packages/dns/tokenizer.py new file mode 100644 index 0000000..880b71c --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/tokenizer.py @@ -0,0 +1,571 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""Tokenize DNS master file format""" + +from io import StringIO +import sys + +import dns.exception +import dns.name +import dns.ttl +from ._compat import long, text_type, binary_type + +_DELIMITERS = { + ' ': True, + '\t': True, + '\n': True, + ';': True, + '(': True, + ')': True, + '"': True} + +_QUOTING_DELIMITERS = {'"': True} + +EOF = 0 +EOL = 1 +WHITESPACE = 2 +IDENTIFIER = 3 +QUOTED_STRING = 4 +COMMENT = 5 +DELIMITER = 6 + + +class UngetBufferFull(dns.exception.DNSException): + """An attempt was made to unget a token when the unget buffer was full.""" + + +class Token(object): + """A DNS master file format token. + + ttype: The token type + value: The token value + has_escape: Does the token value contain escapes? + """ + + def __init__(self, ttype, value='', has_escape=False): + """Initialize a token instance.""" + + self.ttype = ttype + self.value = value + self.has_escape = has_escape + + def is_eof(self): + return self.ttype == EOF + + def is_eol(self): + return self.ttype == EOL + + def is_whitespace(self): + return self.ttype == WHITESPACE + + def is_identifier(self): + return self.ttype == IDENTIFIER + + def is_quoted_string(self): + return self.ttype == QUOTED_STRING + + def is_comment(self): + return self.ttype == COMMENT + + def is_delimiter(self): + return self.ttype == DELIMITER + + def is_eol_or_eof(self): + return self.ttype == EOL or self.ttype == EOF + + def __eq__(self, other): + if not isinstance(other, Token): + return False + return (self.ttype == other.ttype and + self.value == other.value) + + def __ne__(self, other): + if not isinstance(other, Token): + return True + return (self.ttype != other.ttype or + self.value != other.value) + + def __str__(self): + return '%d "%s"' % (self.ttype, self.value) + + def unescape(self): + if not self.has_escape: + return self + unescaped = '' + l = len(self.value) + i = 0 + while i < l: + c = self.value[i] + i += 1 + if c == '\\': + if i >= l: + raise dns.exception.UnexpectedEnd + c = self.value[i] + i += 1 + if c.isdigit(): + if i >= l: + raise dns.exception.UnexpectedEnd + c2 = self.value[i] + i += 1 + if i >= l: + raise dns.exception.UnexpectedEnd + c3 = self.value[i] + i += 1 + if not (c2.isdigit() and c3.isdigit()): + raise dns.exception.SyntaxError + c = chr(int(c) * 100 + int(c2) * 10 + int(c3)) + unescaped += c + return Token(self.ttype, unescaped) + + # compatibility for old-style tuple tokens + + def __len__(self): + return 2 + + def __iter__(self): + return iter((self.ttype, self.value)) + + def __getitem__(self, i): + if i == 0: + return self.ttype + elif i == 1: + return self.value + else: + raise IndexError + + +class Tokenizer(object): + """A DNS master file format tokenizer. + + A token object is basically a (type, value) tuple. The valid + types are EOF, EOL, WHITESPACE, IDENTIFIER, QUOTED_STRING, + COMMENT, and DELIMITER. + + file: The file to tokenize + + ungotten_char: The most recently ungotten character, or None. + + ungotten_token: The most recently ungotten token, or None. + + multiline: The current multiline level. This value is increased + by one every time a '(' delimiter is read, and decreased by one every time + a ')' delimiter is read. + + quoting: This variable is true if the tokenizer is currently + reading a quoted string. + + eof: This variable is true if the tokenizer has encountered EOF. + + delimiters: The current delimiter dictionary. + + line_number: The current line number + + filename: A filename that will be returned by the where() method. + """ + + def __init__(self, f=sys.stdin, filename=None): + """Initialize a tokenizer instance. + + f: The file to tokenize. The default is sys.stdin. + This parameter may also be a string, in which case the tokenizer + will take its input from the contents of the string. + + filename: the name of the filename that the where() method + will return. + """ + + if isinstance(f, text_type): + f = StringIO(f) + if filename is None: + filename = '' + elif isinstance(f, binary_type): + f = StringIO(f.decode()) + if filename is None: + filename = '' + else: + if filename is None: + if f is sys.stdin: + filename = '' + else: + filename = '' + self.file = f + self.ungotten_char = None + self.ungotten_token = None + self.multiline = 0 + self.quoting = False + self.eof = False + self.delimiters = _DELIMITERS + self.line_number = 1 + self.filename = filename + + def _get_char(self): + """Read a character from input. + """ + + if self.ungotten_char is None: + if self.eof: + c = '' + else: + c = self.file.read(1) + if c == '': + self.eof = True + elif c == '\n': + self.line_number += 1 + else: + c = self.ungotten_char + self.ungotten_char = None + return c + + def where(self): + """Return the current location in the input. + + Returns a (string, int) tuple. The first item is the filename of + the input, the second is the current line number. + """ + + return (self.filename, self.line_number) + + def _unget_char(self, c): + """Unget a character. + + The unget buffer for characters is only one character large; it is + an error to try to unget a character when the unget buffer is not + empty. + + c: the character to unget + raises UngetBufferFull: there is already an ungotten char + """ + + if self.ungotten_char is not None: + raise UngetBufferFull + self.ungotten_char = c + + def skip_whitespace(self): + """Consume input until a non-whitespace character is encountered. + + The non-whitespace character is then ungotten, and the number of + whitespace characters consumed is returned. + + If the tokenizer is in multiline mode, then newlines are whitespace. + + Returns the number of characters skipped. + """ + + skipped = 0 + while True: + c = self._get_char() + if c != ' ' and c != '\t': + if (c != '\n') or not self.multiline: + self._unget_char(c) + return skipped + skipped += 1 + + def get(self, want_leading=False, want_comment=False): + """Get the next token. + + want_leading: If True, return a WHITESPACE token if the + first character read is whitespace. The default is False. + + want_comment: If True, return a COMMENT token if the + first token read is a comment. The default is False. + + Raises dns.exception.UnexpectedEnd: input ended prematurely + + Raises dns.exception.SyntaxError: input was badly formed + + Returns a Token. + """ + + if self.ungotten_token is not None: + token = self.ungotten_token + self.ungotten_token = None + if token.is_whitespace(): + if want_leading: + return token + elif token.is_comment(): + if want_comment: + return token + else: + return token + skipped = self.skip_whitespace() + if want_leading and skipped > 0: + return Token(WHITESPACE, ' ') + token = '' + ttype = IDENTIFIER + has_escape = False + while True: + c = self._get_char() + if c == '' or c in self.delimiters: + if c == '' and self.quoting: + raise dns.exception.UnexpectedEnd + if token == '' and ttype != QUOTED_STRING: + if c == '(': + self.multiline += 1 + self.skip_whitespace() + continue + elif c == ')': + if self.multiline <= 0: + raise dns.exception.SyntaxError + self.multiline -= 1 + self.skip_whitespace() + continue + elif c == '"': + if not self.quoting: + self.quoting = True + self.delimiters = _QUOTING_DELIMITERS + ttype = QUOTED_STRING + continue + else: + self.quoting = False + self.delimiters = _DELIMITERS + self.skip_whitespace() + continue + elif c == '\n': + return Token(EOL, '\n') + elif c == ';': + while 1: + c = self._get_char() + if c == '\n' or c == '': + break + token += c + if want_comment: + self._unget_char(c) + return Token(COMMENT, token) + elif c == '': + if self.multiline: + raise dns.exception.SyntaxError( + 'unbalanced parentheses') + return Token(EOF) + elif self.multiline: + self.skip_whitespace() + token = '' + continue + else: + return Token(EOL, '\n') + else: + # This code exists in case we ever want a + # delimiter to be returned. It never produces + # a token currently. + token = c + ttype = DELIMITER + else: + self._unget_char(c) + break + elif self.quoting: + if c == '\\': + c = self._get_char() + if c == '': + raise dns.exception.UnexpectedEnd + if c.isdigit(): + c2 = self._get_char() + if c2 == '': + raise dns.exception.UnexpectedEnd + c3 = self._get_char() + if c == '': + raise dns.exception.UnexpectedEnd + if not (c2.isdigit() and c3.isdigit()): + raise dns.exception.SyntaxError + c = chr(int(c) * 100 + int(c2) * 10 + int(c3)) + elif c == '\n': + raise dns.exception.SyntaxError('newline in quoted string') + elif c == '\\': + # + # It's an escape. Put it and the next character into + # the token; it will be checked later for goodness. + # + token += c + has_escape = True + c = self._get_char() + if c == '' or c == '\n': + raise dns.exception.UnexpectedEnd + token += c + if token == '' and ttype != QUOTED_STRING: + if self.multiline: + raise dns.exception.SyntaxError('unbalanced parentheses') + ttype = EOF + return Token(ttype, token, has_escape) + + def unget(self, token): + """Unget a token. + + The unget buffer for tokens is only one token large; it is + an error to try to unget a token when the unget buffer is not + empty. + + token: the token to unget + + Raises UngetBufferFull: there is already an ungotten token + """ + + if self.ungotten_token is not None: + raise UngetBufferFull + self.ungotten_token = token + + def next(self): + """Return the next item in an iteration. + + Returns a Token. + """ + + token = self.get() + if token.is_eof(): + raise StopIteration + return token + + __next__ = next + + def __iter__(self): + return self + + # Helpers + + def get_int(self, base=10): + """Read the next token and interpret it as an integer. + + Raises dns.exception.SyntaxError if not an integer. + + Returns an int. + """ + + token = self.get().unescape() + if not token.is_identifier(): + raise dns.exception.SyntaxError('expecting an identifier') + if not token.value.isdigit(): + raise dns.exception.SyntaxError('expecting an integer') + return int(token.value, base) + + def get_uint8(self): + """Read the next token and interpret it as an 8-bit unsigned + integer. + + Raises dns.exception.SyntaxError if not an 8-bit unsigned integer. + + Returns an int. + """ + + value = self.get_int() + if value < 0 or value > 255: + raise dns.exception.SyntaxError( + '%d is not an unsigned 8-bit integer' % value) + return value + + def get_uint16(self, base=10): + """Read the next token and interpret it as a 16-bit unsigned + integer. + + Raises dns.exception.SyntaxError if not a 16-bit unsigned integer. + + Returns an int. + """ + + value = self.get_int(base=base) + if value < 0 or value > 65535: + if base == 8: + raise dns.exception.SyntaxError( + '%o is not an octal unsigned 16-bit integer' % value) + else: + raise dns.exception.SyntaxError( + '%d is not an unsigned 16-bit integer' % value) + return value + + def get_uint32(self): + """Read the next token and interpret it as a 32-bit unsigned + integer. + + Raises dns.exception.SyntaxError if not a 32-bit unsigned integer. + + Returns an int. + """ + + token = self.get().unescape() + if not token.is_identifier(): + raise dns.exception.SyntaxError('expecting an identifier') + if not token.value.isdigit(): + raise dns.exception.SyntaxError('expecting an integer') + value = long(token.value) + if value < 0 or value > long(4294967296): + raise dns.exception.SyntaxError( + '%d is not an unsigned 32-bit integer' % value) + return value + + def get_string(self, origin=None): + """Read the next token and interpret it as a string. + + Raises dns.exception.SyntaxError if not a string. + + Returns a string. + """ + + token = self.get().unescape() + if not (token.is_identifier() or token.is_quoted_string()): + raise dns.exception.SyntaxError('expecting a string') + return token.value + + def get_identifier(self, origin=None): + """Read the next token, which should be an identifier. + + Raises dns.exception.SyntaxError if not an identifier. + + Returns a string. + """ + + token = self.get().unescape() + if not token.is_identifier(): + raise dns.exception.SyntaxError('expecting an identifier') + return token.value + + def get_name(self, origin=None): + """Read the next token and interpret it as a DNS name. + + Raises dns.exception.SyntaxError if not a name. + + Returns a dns.name.Name. + """ + + token = self.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError('expecting an identifier') + return dns.name.from_text(token.value, origin) + + def get_eol(self): + """Read the next token and raise an exception if it isn't EOL or + EOF. + + Returns a string. + """ + + token = self.get() + if not token.is_eol_or_eof(): + raise dns.exception.SyntaxError( + 'expected EOL or EOF, got %d "%s"' % (token.ttype, + token.value)) + return token.value + + def get_ttl(self): + """Read the next token and interpret it as a DNS TTL. + + Raises dns.exception.SyntaxError or dns.ttl.BadTTL if not an + identifier or badly formed. + + Returns an int. + """ + + token = self.get().unescape() + if not token.is_identifier(): + raise dns.exception.SyntaxError('expecting an identifier') + return dns.ttl.from_text(token.value) diff --git a/env/lib/python3.7/site-packages/dns/tsig.py b/env/lib/python3.7/site-packages/dns/tsig.py new file mode 100644 index 0000000..3daa387 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/tsig.py @@ -0,0 +1,236 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2001-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS TSIG support.""" + +import hashlib +import hmac +import struct + +import dns.exception +import dns.rdataclass +import dns.name +from ._compat import long, string_types, text_type + +class BadTime(dns.exception.DNSException): + + """The current time is not within the TSIG's validity time.""" + + +class BadSignature(dns.exception.DNSException): + + """The TSIG signature fails to verify.""" + + +class PeerError(dns.exception.DNSException): + + """Base class for all TSIG errors generated by the remote peer""" + + +class PeerBadKey(PeerError): + + """The peer didn't know the key we used""" + + +class PeerBadSignature(PeerError): + + """The peer didn't like the signature we sent""" + + +class PeerBadTime(PeerError): + + """The peer didn't like the time we sent""" + + +class PeerBadTruncation(PeerError): + + """The peer didn't like amount of truncation in the TSIG we sent""" + +# TSIG Algorithms + +HMAC_MD5 = dns.name.from_text("HMAC-MD5.SIG-ALG.REG.INT") +HMAC_SHA1 = dns.name.from_text("hmac-sha1") +HMAC_SHA224 = dns.name.from_text("hmac-sha224") +HMAC_SHA256 = dns.name.from_text("hmac-sha256") +HMAC_SHA384 = dns.name.from_text("hmac-sha384") +HMAC_SHA512 = dns.name.from_text("hmac-sha512") + +_hashes = { + HMAC_SHA224: hashlib.sha224, + HMAC_SHA256: hashlib.sha256, + HMAC_SHA384: hashlib.sha384, + HMAC_SHA512: hashlib.sha512, + HMAC_SHA1: hashlib.sha1, + HMAC_MD5: hashlib.md5, +} + +default_algorithm = HMAC_MD5 + +BADSIG = 16 +BADKEY = 17 +BADTIME = 18 +BADTRUNC = 22 + + +def sign(wire, keyname, secret, time, fudge, original_id, error, + other_data, request_mac, ctx=None, multi=False, first=True, + algorithm=default_algorithm): + """Return a (tsig_rdata, mac, ctx) tuple containing the HMAC TSIG rdata + for the input parameters, the HMAC MAC calculated by applying the + TSIG signature algorithm, and the TSIG digest context. + @rtype: (string, string, hmac.HMAC object) + @raises ValueError: I{other_data} is too long + @raises NotImplementedError: I{algorithm} is not supported + """ + + if isinstance(other_data, text_type): + other_data = other_data.encode() + (algorithm_name, digestmod) = get_algorithm(algorithm) + if first: + ctx = hmac.new(secret, digestmod=digestmod) + ml = len(request_mac) + if ml > 0: + ctx.update(struct.pack('!H', ml)) + ctx.update(request_mac) + id = struct.pack('!H', original_id) + ctx.update(id) + ctx.update(wire[2:]) + if first: + ctx.update(keyname.to_digestable()) + ctx.update(struct.pack('!H', dns.rdataclass.ANY)) + ctx.update(struct.pack('!I', 0)) + long_time = time + long(0) + upper_time = (long_time >> 32) & long(0xffff) + lower_time = long_time & long(0xffffffff) + time_mac = struct.pack('!HIH', upper_time, lower_time, fudge) + pre_mac = algorithm_name + time_mac + ol = len(other_data) + if ol > 65535: + raise ValueError('TSIG Other Data is > 65535 bytes') + post_mac = struct.pack('!HH', error, ol) + other_data + if first: + ctx.update(pre_mac) + ctx.update(post_mac) + else: + ctx.update(time_mac) + mac = ctx.digest() + mpack = struct.pack('!H', len(mac)) + tsig_rdata = pre_mac + mpack + mac + id + post_mac + if multi: + ctx = hmac.new(secret, digestmod=digestmod) + ml = len(mac) + ctx.update(struct.pack('!H', ml)) + ctx.update(mac) + else: + ctx = None + return (tsig_rdata, mac, ctx) + + +def hmac_md5(wire, keyname, secret, time, fudge, original_id, error, + other_data, request_mac, ctx=None, multi=False, first=True, + algorithm=default_algorithm): + return sign(wire, keyname, secret, time, fudge, original_id, error, + other_data, request_mac, ctx, multi, first, algorithm) + + +def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata, + tsig_rdlen, ctx=None, multi=False, first=True): + """Validate the specified TSIG rdata against the other input parameters. + + @raises FormError: The TSIG is badly formed. + @raises BadTime: There is too much time skew between the client and the + server. + @raises BadSignature: The TSIG signature did not validate + @rtype: hmac.HMAC object""" + + (adcount,) = struct.unpack("!H", wire[10:12]) + if adcount == 0: + raise dns.exception.FormError + adcount -= 1 + new_wire = wire[0:10] + struct.pack("!H", adcount) + wire[12:tsig_start] + current = tsig_rdata + (aname, used) = dns.name.from_wire(wire, current) + current = current + used + (upper_time, lower_time, fudge, mac_size) = \ + struct.unpack("!HIHH", wire[current:current + 10]) + time = ((upper_time + long(0)) << 32) + (lower_time + long(0)) + current += 10 + mac = wire[current:current + mac_size] + current += mac_size + (original_id, error, other_size) = \ + struct.unpack("!HHH", wire[current:current + 6]) + current += 6 + other_data = wire[current:current + other_size] + current += other_size + if current != tsig_rdata + tsig_rdlen: + raise dns.exception.FormError + if error != 0: + if error == BADSIG: + raise PeerBadSignature + elif error == BADKEY: + raise PeerBadKey + elif error == BADTIME: + raise PeerBadTime + elif error == BADTRUNC: + raise PeerBadTruncation + else: + raise PeerError('unknown TSIG error code %d' % error) + time_low = time - fudge + time_high = time + fudge + if now < time_low or now > time_high: + raise BadTime + (junk, our_mac, ctx) = sign(new_wire, keyname, secret, time, fudge, + original_id, error, other_data, + request_mac, ctx, multi, first, aname) + if our_mac != mac: + raise BadSignature + return ctx + + +def get_algorithm(algorithm): + """Returns the wire format string and the hash module to use for the + specified TSIG algorithm + + @rtype: (string, hash constructor) + @raises NotImplementedError: I{algorithm} is not supported + """ + + if isinstance(algorithm, string_types): + algorithm = dns.name.from_text(algorithm) + + try: + return (algorithm.to_digestable(), _hashes[algorithm]) + except KeyError: + raise NotImplementedError("TSIG algorithm " + str(algorithm) + + " is not supported") + + +def get_algorithm_and_mac(wire, tsig_rdata, tsig_rdlen): + """Return the tsig algorithm for the specified tsig_rdata + @raises FormError: The TSIG is badly formed. + """ + current = tsig_rdata + (aname, used) = dns.name.from_wire(wire, current) + current = current + used + (upper_time, lower_time, fudge, mac_size) = \ + struct.unpack("!HIHH", wire[current:current + 10]) + current += 10 + mac = wire[current:current + mac_size] + current += mac_size + if current > tsig_rdata + tsig_rdlen: + raise dns.exception.FormError + return (aname, mac) diff --git a/env/lib/python3.7/site-packages/dns/tsigkeyring.py b/env/lib/python3.7/site-packages/dns/tsigkeyring.py new file mode 100644 index 0000000..5e5fe1c --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/tsigkeyring.py @@ -0,0 +1,50 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""A place to store TSIG keys.""" + +from dns._compat import maybe_decode, maybe_encode + +import base64 + +import dns.name + + +def from_text(textring): + """Convert a dictionary containing (textual DNS name, base64 secret) pairs + into a binary keyring which has (dns.name.Name, binary secret) pairs. + @rtype: dict""" + + keyring = {} + for keytext in textring: + keyname = dns.name.from_text(keytext) + secret = base64.decodestring(maybe_encode(textring[keytext])) + keyring[keyname] = secret + return keyring + + +def to_text(keyring): + """Convert a dictionary containing (dns.name.Name, binary secret) pairs + into a text keyring which has (textual DNS name, base64 secret) pairs. + @rtype: dict""" + + textring = {} + for keyname in keyring: + keytext = maybe_decode(keyname.to_text()) + secret = maybe_decode(base64.encodestring(keyring[keyname])) + textring[keytext] = secret + return textring diff --git a/env/lib/python3.7/site-packages/dns/ttl.py b/env/lib/python3.7/site-packages/dns/ttl.py new file mode 100644 index 0000000..4be16be --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/ttl.py @@ -0,0 +1,70 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS TTL conversion.""" + +import dns.exception +from ._compat import long + + +class BadTTL(dns.exception.SyntaxError): + """DNS TTL value is not well-formed.""" + + +def from_text(text): + """Convert the text form of a TTL to an integer. + + The BIND 8 units syntax for TTLs (e.g. '1w6d4h3m10s') is supported. + + *text*, a ``text``, the textual TTL. + + Raises ``dns.ttl.BadTTL`` if the TTL is not well-formed. + + Returns an ``int``. + """ + + if text.isdigit(): + total = long(text) + else: + if not text[0].isdigit(): + raise BadTTL + total = long(0) + current = long(0) + for c in text: + if c.isdigit(): + current *= 10 + current += long(c) + else: + c = c.lower() + if c == 'w': + total += current * long(604800) + elif c == 'd': + total += current * long(86400) + elif c == 'h': + total += current * long(3600) + elif c == 'm': + total += current * long(60) + elif c == 's': + total += current + else: + raise BadTTL("unknown unit '%s'" % c) + current = 0 + if not current == 0: + raise BadTTL("trailing integer") + if total < long(0) or total > long(2147483647): + raise BadTTL("TTL should be between 0 and 2^31 - 1 (inclusive)") + return total diff --git a/env/lib/python3.7/site-packages/dns/update.py b/env/lib/python3.7/site-packages/dns/update.py new file mode 100644 index 0000000..96a00d5 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/update.py @@ -0,0 +1,279 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Dynamic Update Support""" + + +import dns.message +import dns.name +import dns.opcode +import dns.rdata +import dns.rdataclass +import dns.rdataset +import dns.tsig +from ._compat import string_types + + +class Update(dns.message.Message): + + def __init__(self, zone, rdclass=dns.rdataclass.IN, keyring=None, + keyname=None, keyalgorithm=dns.tsig.default_algorithm): + """Initialize a new DNS Update object. + + See the documentation of the Message class for a complete + description of the keyring dictionary. + + *zone*, a ``dns.name.Name`` or ``text``, the zone which is being + updated. + + *rdclass*, an ``int`` or ``text``, the class of the zone. + + *keyring*, a ``dict``, the TSIG keyring to use. If a + *keyring* is specified but a *keyname* is not, then the key + used will be the first key in the *keyring*. Note that the + order of keys in a dictionary is not defined, so applications + should supply a keyname when a keyring is used, unless they + know the keyring contains only one key. + + *keyname*, a ``dns.name.Name`` or ``None``, the name of the TSIG key + to use; defaults to ``None``. The key must be defined in the keyring. + + *keyalgorithm*, a ``dns.name.Name``, the TSIG algorithm to use. + """ + super(Update, self).__init__() + self.flags |= dns.opcode.to_flags(dns.opcode.UPDATE) + if isinstance(zone, string_types): + zone = dns.name.from_text(zone) + self.origin = zone + if isinstance(rdclass, string_types): + rdclass = dns.rdataclass.from_text(rdclass) + self.zone_rdclass = rdclass + self.find_rrset(self.question, self.origin, rdclass, dns.rdatatype.SOA, + create=True, force_unique=True) + if keyring is not None: + self.use_tsig(keyring, keyname, algorithm=keyalgorithm) + + def _add_rr(self, name, ttl, rd, deleting=None, section=None): + """Add a single RR to the update section.""" + + if section is None: + section = self.authority + covers = rd.covers() + rrset = self.find_rrset(section, name, self.zone_rdclass, rd.rdtype, + covers, deleting, True, True) + rrset.add(rd, ttl) + + def _add(self, replace, section, name, *args): + """Add records. + + *replace* is the replacement mode. If ``False``, + RRs are added to an existing RRset; if ``True``, the RRset + is replaced with the specified contents. The second + argument is the section to add to. The third argument + is always a name. The other arguments can be: + + - rdataset... + + - ttl, rdata... + + - ttl, rdtype, string... + """ + + if isinstance(name, string_types): + name = dns.name.from_text(name, None) + if isinstance(args[0], dns.rdataset.Rdataset): + for rds in args: + if replace: + self.delete(name, rds.rdtype) + for rd in rds: + self._add_rr(name, rds.ttl, rd, section=section) + else: + args = list(args) + ttl = int(args.pop(0)) + if isinstance(args[0], dns.rdata.Rdata): + if replace: + self.delete(name, args[0].rdtype) + for rd in args: + self._add_rr(name, ttl, rd, section=section) + else: + rdtype = args.pop(0) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if replace: + self.delete(name, rdtype) + for s in args: + rd = dns.rdata.from_text(self.zone_rdclass, rdtype, s, + self.origin) + self._add_rr(name, ttl, rd, section=section) + + def add(self, name, *args): + """Add records. + + The first argument is always a name. The other + arguments can be: + + - rdataset... + + - ttl, rdata... + + - ttl, rdtype, string... + """ + + self._add(False, self.authority, name, *args) + + def delete(self, name, *args): + """Delete records. + + The first argument is always a name. The other + arguments can be: + + - *empty* + + - rdataset... + + - rdata... + + - rdtype, [string...] + """ + + if isinstance(name, string_types): + name = dns.name.from_text(name, None) + if len(args) == 0: + self.find_rrset(self.authority, name, dns.rdataclass.ANY, + dns.rdatatype.ANY, dns.rdatatype.NONE, + dns.rdatatype.ANY, True, True) + elif isinstance(args[0], dns.rdataset.Rdataset): + for rds in args: + for rd in rds: + self._add_rr(name, 0, rd, dns.rdataclass.NONE) + else: + args = list(args) + if isinstance(args[0], dns.rdata.Rdata): + for rd in args: + self._add_rr(name, 0, rd, dns.rdataclass.NONE) + else: + rdtype = args.pop(0) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if len(args) == 0: + self.find_rrset(self.authority, name, + self.zone_rdclass, rdtype, + dns.rdatatype.NONE, + dns.rdataclass.ANY, + True, True) + else: + for s in args: + rd = dns.rdata.from_text(self.zone_rdclass, rdtype, s, + self.origin) + self._add_rr(name, 0, rd, dns.rdataclass.NONE) + + def replace(self, name, *args): + """Replace records. + + The first argument is always a name. The other + arguments can be: + + - rdataset... + + - ttl, rdata... + + - ttl, rdtype, string... + + Note that if you want to replace the entire node, you should do + a delete of the name followed by one or more calls to add. + """ + + self._add(True, self.authority, name, *args) + + def present(self, name, *args): + """Require that an owner name (and optionally an rdata type, + or specific rdataset) exists as a prerequisite to the + execution of the update. + + The first argument is always a name. + The other arguments can be: + + - rdataset... + + - rdata... + + - rdtype, string... + """ + + if isinstance(name, string_types): + name = dns.name.from_text(name, None) + if len(args) == 0: + self.find_rrset(self.answer, name, + dns.rdataclass.ANY, dns.rdatatype.ANY, + dns.rdatatype.NONE, None, + True, True) + elif isinstance(args[0], dns.rdataset.Rdataset) or \ + isinstance(args[0], dns.rdata.Rdata) or \ + len(args) > 1: + if not isinstance(args[0], dns.rdataset.Rdataset): + # Add a 0 TTL + args = list(args) + args.insert(0, 0) + self._add(False, self.answer, name, *args) + else: + rdtype = args[0] + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + self.find_rrset(self.answer, name, + dns.rdataclass.ANY, rdtype, + dns.rdatatype.NONE, None, + True, True) + + def absent(self, name, rdtype=None): + """Require that an owner name (and optionally an rdata type) does + not exist as a prerequisite to the execution of the update.""" + + if isinstance(name, string_types): + name = dns.name.from_text(name, None) + if rdtype is None: + self.find_rrset(self.answer, name, + dns.rdataclass.NONE, dns.rdatatype.ANY, + dns.rdatatype.NONE, None, + True, True) + else: + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + self.find_rrset(self.answer, name, + dns.rdataclass.NONE, rdtype, + dns.rdatatype.NONE, None, + True, True) + + def to_wire(self, origin=None, max_size=65535): + """Return a string containing the update in DNS compressed wire + format. + + *origin*, a ``dns.name.Name`` or ``None``, the origin to be + appended to any relative names. If *origin* is ``None``, then + the origin of the ``dns.update.Update`` message object is used + (i.e. the *zone* parameter passed when the Update object was + created). + + *max_size*, an ``int``, the maximum size of the wire format + output; default is 0, which means "the message's request + payload, if nonzero, or 65535". + + Returns a ``binary``. + """ + + if origin is None: + origin = self.origin + return super(Update, self).to_wire(origin, max_size) diff --git a/env/lib/python3.7/site-packages/dns/version.py b/env/lib/python3.7/site-packages/dns/version.py new file mode 100644 index 0000000..f116904 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/version.py @@ -0,0 +1,43 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""dnspython release version information.""" + +#: MAJOR +MAJOR = 1 +#: MINOR +MINOR = 16 +#: MICRO +MICRO = 0 +#: RELEASELEVEL +RELEASELEVEL = 0x0f +#: SERIAL +SERIAL = 0 + +if RELEASELEVEL == 0x0f: + #: version + version = '%d.%d.%d' % (MAJOR, MINOR, MICRO) +elif RELEASELEVEL == 0x00: + version = '%d.%d.%dx%d' % \ + (MAJOR, MINOR, MICRO, SERIAL) +else: + version = '%d.%d.%d%x%d' % \ + (MAJOR, MINOR, MICRO, RELEASELEVEL, SERIAL) + +#: hexversion +hexversion = MAJOR << 24 | MINOR << 16 | MICRO << 8 | RELEASELEVEL << 4 | \ + SERIAL diff --git a/env/lib/python3.7/site-packages/dns/wiredata.py b/env/lib/python3.7/site-packages/dns/wiredata.py new file mode 100644 index 0000000..ea3c1e6 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/wiredata.py @@ -0,0 +1,103 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2011,2017 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Wire Data Helper""" + +import dns.exception +from ._compat import binary_type, string_types, PY2 + +# Figure out what constant python passes for an unspecified slice bound. +# It's supposed to be sys.maxint, yet on 64-bit windows sys.maxint is 2^31 - 1 +# but Python uses 2^63 - 1 as the constant. Rather than making pointless +# extra comparisons, duplicating code, or weakening WireData, we just figure +# out what constant Python will use. + + +class _SliceUnspecifiedBound(binary_type): + + def __getitem__(self, key): + return key.stop + + if PY2: + def __getslice__(self, i, j): # pylint: disable=getslice-method + return self.__getitem__(slice(i, j)) + +_unspecified_bound = _SliceUnspecifiedBound()[1:] + + +class WireData(binary_type): + # WireData is a binary type with stricter slicing + + def __getitem__(self, key): + try: + if isinstance(key, slice): + # make sure we are not going outside of valid ranges, + # do stricter control of boundaries than python does + # by default + start = key.start + stop = key.stop + + if PY2: + if stop == _unspecified_bound: + # handle the case where the right bound is unspecified + stop = len(self) + + if start < 0 or stop < 0: + raise dns.exception.FormError + # If it's not an empty slice, access left and right bounds + # to make sure they're valid + if start != stop: + super(WireData, self).__getitem__(start) + super(WireData, self).__getitem__(stop - 1) + else: + for index in (start, stop): + if index is None: + continue + elif abs(index) > len(self): + raise dns.exception.FormError + + return WireData(super(WireData, self).__getitem__( + slice(start, stop))) + return bytearray(self.unwrap())[key] + except IndexError: + raise dns.exception.FormError + + if PY2: + def __getslice__(self, i, j): # pylint: disable=getslice-method + return self.__getitem__(slice(i, j)) + + def __iter__(self): + i = 0 + while 1: + try: + yield self[i] + i += 1 + except dns.exception.FormError: + raise StopIteration + + def unwrap(self): + return binary_type(self) + + +def maybe_wrap(wire): + if isinstance(wire, WireData): + return wire + elif isinstance(wire, binary_type): + return WireData(wire) + elif isinstance(wire, string_types): + return WireData(wire.encode()) + raise ValueError("unhandled type %s" % type(wire)) diff --git a/env/lib/python3.7/site-packages/dns/zone.py b/env/lib/python3.7/site-packages/dns/zone.py new file mode 100644 index 0000000..1e2fe78 --- /dev/null +++ b/env/lib/python3.7/site-packages/dns/zone.py @@ -0,0 +1,1127 @@ +# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license + +# Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. +# +# Permission to use, copy, modify, and distribute this software and its +# documentation for any purpose with or without fee is hereby granted, +# provided that the above copyright notice and this permission notice +# appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +"""DNS Zones.""" + +from __future__ import generators + +import sys +import re +import os +from io import BytesIO + +import dns.exception +import dns.name +import dns.node +import dns.rdataclass +import dns.rdatatype +import dns.rdata +import dns.rdtypes.ANY.SOA +import dns.rrset +import dns.tokenizer +import dns.ttl +import dns.grange +from ._compat import string_types, text_type, PY3 + + +class BadZone(dns.exception.DNSException): + + """The DNS zone is malformed.""" + + +class NoSOA(BadZone): + + """The DNS zone has no SOA RR at its origin.""" + + +class NoNS(BadZone): + + """The DNS zone has no NS RRset at its origin.""" + + +class UnknownOrigin(BadZone): + + """The DNS zone's origin is unknown.""" + + +class Zone(object): + + """A DNS zone. + + A Zone is a mapping from names to nodes. The zone object may be + treated like a Python dictionary, e.g. zone[name] will retrieve + the node associated with that name. The I{name} may be a + dns.name.Name object, or it may be a string. In the either case, + if the name is relative it is treated as relative to the origin of + the zone. + + @ivar rdclass: The zone's rdata class; the default is class IN. + @type rdclass: int + @ivar origin: The origin of the zone. + @type origin: dns.name.Name object + @ivar nodes: A dictionary mapping the names of nodes in the zone to the + nodes themselves. + @type nodes: dict + @ivar relativize: should names in the zone be relativized? + @type relativize: bool + @cvar node_factory: the factory used to create a new node + @type node_factory: class or callable + """ + + node_factory = dns.node.Node + + __slots__ = ['rdclass', 'origin', 'nodes', 'relativize'] + + def __init__(self, origin, rdclass=dns.rdataclass.IN, relativize=True): + """Initialize a zone object. + + @param origin: The origin of the zone. + @type origin: dns.name.Name object + @param rdclass: The zone's rdata class; the default is class IN. + @type rdclass: int""" + + if origin is not None: + if isinstance(origin, string_types): + origin = dns.name.from_text(origin) + elif not isinstance(origin, dns.name.Name): + raise ValueError("origin parameter must be convertible to a " + "DNS name") + if not origin.is_absolute(): + raise ValueError("origin parameter must be an absolute name") + self.origin = origin + self.rdclass = rdclass + self.nodes = {} + self.relativize = relativize + + def __eq__(self, other): + """Two zones are equal if they have the same origin, class, and + nodes. + @rtype: bool + """ + + if not isinstance(other, Zone): + return False + if self.rdclass != other.rdclass or \ + self.origin != other.origin or \ + self.nodes != other.nodes: + return False + return True + + def __ne__(self, other): + """Are two zones not equal? + @rtype: bool + """ + + return not self.__eq__(other) + + def _validate_name(self, name): + if isinstance(name, string_types): + name = dns.name.from_text(name, None) + elif not isinstance(name, dns.name.Name): + raise KeyError("name parameter must be convertible to a DNS name") + if name.is_absolute(): + if not name.is_subdomain(self.origin): + raise KeyError( + "name parameter must be a subdomain of the zone origin") + if self.relativize: + name = name.relativize(self.origin) + return name + + def __getitem__(self, key): + key = self._validate_name(key) + return self.nodes[key] + + def __setitem__(self, key, value): + key = self._validate_name(key) + self.nodes[key] = value + + def __delitem__(self, key): + key = self._validate_name(key) + del self.nodes[key] + + def __iter__(self): + return self.nodes.__iter__() + + def iterkeys(self): + if PY3: + return self.nodes.keys() # pylint: disable=dict-keys-not-iterating + else: + return self.nodes.iterkeys() # pylint: disable=dict-iter-method + + def keys(self): + return self.nodes.keys() # pylint: disable=dict-keys-not-iterating + + def itervalues(self): + if PY3: + return self.nodes.values() # pylint: disable=dict-values-not-iterating + else: + return self.nodes.itervalues() # pylint: disable=dict-iter-method + + def values(self): + return self.nodes.values() # pylint: disable=dict-values-not-iterating + + def items(self): + return self.nodes.items() # pylint: disable=dict-items-not-iterating + + iteritems = items + + def get(self, key): + key = self._validate_name(key) + return self.nodes.get(key) + + def __contains__(self, other): + return other in self.nodes + + def find_node(self, name, create=False): + """Find a node in the zone, possibly creating it. + + @param name: the name of the node to find + @type name: dns.name.Name object or string + @param create: should the node be created if it doesn't exist? + @type create: bool + @raises KeyError: the name is not known and create was not specified. + @rtype: dns.node.Node object + """ + + name = self._validate_name(name) + node = self.nodes.get(name) + if node is None: + if not create: + raise KeyError + node = self.node_factory() + self.nodes[name] = node + return node + + def get_node(self, name, create=False): + """Get a node in the zone, possibly creating it. + + This method is like L{find_node}, except it returns None instead + of raising an exception if the node does not exist and creation + has not been requested. + + @param name: the name of the node to find + @type name: dns.name.Name object or string + @param create: should the node be created if it doesn't exist? + @type create: bool + @rtype: dns.node.Node object or None + """ + + try: + node = self.find_node(name, create) + except KeyError: + node = None + return node + + def delete_node(self, name): + """Delete the specified node if it exists. + + It is not an error if the node does not exist. + """ + + name = self._validate_name(name) + if name in self.nodes: + del self.nodes[name] + + def find_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE, + create=False): + """Look for rdata with the specified name and type in the zone, + and return an rdataset encapsulating it. + + The I{name}, I{rdtype}, and I{covers} parameters may be + strings, in which case they will be converted to their proper + type. + + The rdataset returned is not a copy; changes to it will change + the zone. + + KeyError is raised if the name or type are not found. + Use L{get_rdataset} if you want to have None returned instead. + + @param name: the owner name to look for + @type name: DNS.name.Name object or string + @param rdtype: the rdata type desired + @type rdtype: int or string + @param covers: the covered type (defaults to None) + @type covers: int or string + @param create: should the node and rdataset be created if they do not + exist? + @type create: bool + @raises KeyError: the node or rdata could not be found + @rtype: dns.rdataset.Rdataset object + """ + + name = self._validate_name(name) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if isinstance(covers, string_types): + covers = dns.rdatatype.from_text(covers) + node = self.find_node(name, create) + return node.find_rdataset(self.rdclass, rdtype, covers, create) + + def get_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE, + create=False): + """Look for rdata with the specified name and type in the zone, + and return an rdataset encapsulating it. + + The I{name}, I{rdtype}, and I{covers} parameters may be + strings, in which case they will be converted to their proper + type. + + The rdataset returned is not a copy; changes to it will change + the zone. + + None is returned if the name or type are not found. + Use L{find_rdataset} if you want to have KeyError raised instead. + + @param name: the owner name to look for + @type name: DNS.name.Name object or string + @param rdtype: the rdata type desired + @type rdtype: int or string + @param covers: the covered type (defaults to None) + @type covers: int or string + @param create: should the node and rdataset be created if they do not + exist? + @type create: bool + @rtype: dns.rdataset.Rdataset object or None + """ + + try: + rdataset = self.find_rdataset(name, rdtype, covers, create) + except KeyError: + rdataset = None + return rdataset + + def delete_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE): + """Delete the rdataset matching I{rdtype} and I{covers}, if it + exists at the node specified by I{name}. + + The I{name}, I{rdtype}, and I{covers} parameters may be + strings, in which case they will be converted to their proper + type. + + It is not an error if the node does not exist, or if there is no + matching rdataset at the node. + + If the node has no rdatasets after the deletion, it will itself + be deleted. + + @param name: the owner name to look for + @type name: DNS.name.Name object or string + @param rdtype: the rdata type desired + @type rdtype: int or string + @param covers: the covered type (defaults to None) + @type covers: int or string + """ + + name = self._validate_name(name) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if isinstance(covers, string_types): + covers = dns.rdatatype.from_text(covers) + node = self.get_node(name) + if node is not None: + node.delete_rdataset(self.rdclass, rdtype, covers) + if len(node) == 0: + self.delete_node(name) + + def replace_rdataset(self, name, replacement): + """Replace an rdataset at name. + + It is not an error if there is no rdataset matching I{replacement}. + + Ownership of the I{replacement} object is transferred to the zone; + in other words, this method does not store a copy of I{replacement} + at the node, it stores I{replacement} itself. + + If the I{name} node does not exist, it is created. + + @param name: the owner name + @type name: DNS.name.Name object or string + @param replacement: the replacement rdataset + @type replacement: dns.rdataset.Rdataset + """ + + if replacement.rdclass != self.rdclass: + raise ValueError('replacement.rdclass != zone.rdclass') + node = self.find_node(name, True) + node.replace_rdataset(replacement) + + def find_rrset(self, name, rdtype, covers=dns.rdatatype.NONE): + """Look for rdata with the specified name and type in the zone, + and return an RRset encapsulating it. + + The I{name}, I{rdtype}, and I{covers} parameters may be + strings, in which case they will be converted to their proper + type. + + This method is less efficient than the similar + L{find_rdataset} because it creates an RRset instead of + returning the matching rdataset. It may be more convenient + for some uses since it returns an object which binds the owner + name to the rdata. + + This method may not be used to create new nodes or rdatasets; + use L{find_rdataset} instead. + + KeyError is raised if the name or type are not found. + Use L{get_rrset} if you want to have None returned instead. + + @param name: the owner name to look for + @type name: DNS.name.Name object or string + @param rdtype: the rdata type desired + @type rdtype: int or string + @param covers: the covered type (defaults to None) + @type covers: int or string + @raises KeyError: the node or rdata could not be found + @rtype: dns.rrset.RRset object + """ + + name = self._validate_name(name) + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if isinstance(covers, string_types): + covers = dns.rdatatype.from_text(covers) + rdataset = self.nodes[name].find_rdataset(self.rdclass, rdtype, covers) + rrset = dns.rrset.RRset(name, self.rdclass, rdtype, covers) + rrset.update(rdataset) + return rrset + + def get_rrset(self, name, rdtype, covers=dns.rdatatype.NONE): + """Look for rdata with the specified name and type in the zone, + and return an RRset encapsulating it. + + The I{name}, I{rdtype}, and I{covers} parameters may be + strings, in which case they will be converted to their proper + type. + + This method is less efficient than the similar L{get_rdataset} + because it creates an RRset instead of returning the matching + rdataset. It may be more convenient for some uses since it + returns an object which binds the owner name to the rdata. + + This method may not be used to create new nodes or rdatasets; + use L{find_rdataset} instead. + + None is returned if the name or type are not found. + Use L{find_rrset} if you want to have KeyError raised instead. + + @param name: the owner name to look for + @type name: DNS.name.Name object or string + @param rdtype: the rdata type desired + @type rdtype: int or string + @param covers: the covered type (defaults to None) + @type covers: int or string + @rtype: dns.rrset.RRset object + """ + + try: + rrset = self.find_rrset(name, rdtype, covers) + except KeyError: + rrset = None + return rrset + + def iterate_rdatasets(self, rdtype=dns.rdatatype.ANY, + covers=dns.rdatatype.NONE): + """Return a generator which yields (name, rdataset) tuples for + all rdatasets in the zone which have the specified I{rdtype} + and I{covers}. If I{rdtype} is dns.rdatatype.ANY, the default, + then all rdatasets will be matched. + + @param rdtype: int or string + @type rdtype: int or string + @param covers: the covered type (defaults to None) + @type covers: int or string + """ + + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if isinstance(covers, string_types): + covers = dns.rdatatype.from_text(covers) + for (name, node) in self.iteritems(): # pylint: disable=dict-iter-method + for rds in node: + if rdtype == dns.rdatatype.ANY or \ + (rds.rdtype == rdtype and rds.covers == covers): + yield (name, rds) + + def iterate_rdatas(self, rdtype=dns.rdatatype.ANY, + covers=dns.rdatatype.NONE): + """Return a generator which yields (name, ttl, rdata) tuples for + all rdatas in the zone which have the specified I{rdtype} + and I{covers}. If I{rdtype} is dns.rdatatype.ANY, the default, + then all rdatas will be matched. + + @param rdtype: int or string + @type rdtype: int or string + @param covers: the covered type (defaults to None) + @type covers: int or string + """ + + if isinstance(rdtype, string_types): + rdtype = dns.rdatatype.from_text(rdtype) + if isinstance(covers, string_types): + covers = dns.rdatatype.from_text(covers) + for (name, node) in self.iteritems(): # pylint: disable=dict-iter-method + for rds in node: + if rdtype == dns.rdatatype.ANY or \ + (rds.rdtype == rdtype and rds.covers == covers): + for rdata in rds: + yield (name, rds.ttl, rdata) + + def to_file(self, f, sorted=True, relativize=True, nl=None): + """Write a zone to a file. + + @param f: file or string. If I{f} is a string, it is treated + as the name of a file to open. + @param sorted: if True, the file will be written with the + names sorted in DNSSEC order from least to greatest. Otherwise + the names will be written in whatever order they happen to have + in the zone's dictionary. + @param relativize: if True, domain names in the output will be + relativized to the zone's origin (if possible). + @type relativize: bool + @param nl: The end of line string. If not specified, the + output will use the platform's native end-of-line marker (i.e. + LF on POSIX, CRLF on Windows, CR on Macintosh). + @type nl: string or None + """ + + if isinstance(f, string_types): + f = open(f, 'wb') + want_close = True + else: + want_close = False + + # must be in this way, f.encoding may contain None, or even attribute + # may not be there + file_enc = getattr(f, 'encoding', None) + if file_enc is None: + file_enc = 'utf-8' + + if nl is None: + nl_b = os.linesep.encode(file_enc) # binary mode, '\n' is not enough + nl = u'\n' + elif isinstance(nl, string_types): + nl_b = nl.encode(file_enc) + else: + nl_b = nl + nl = nl.decode() + + try: + if sorted: + names = list(self.keys()) + names.sort() + else: + names = self.iterkeys() # pylint: disable=dict-iter-method + for n in names: + l = self[n].to_text(n, origin=self.origin, + relativize=relativize) + if isinstance(l, text_type): + l_b = l.encode(file_enc) + else: + l_b = l + l = l.decode() + + try: + f.write(l_b) + f.write(nl_b) + except TypeError: # textual mode + f.write(l) + f.write(nl) + finally: + if want_close: + f.close() + + def to_text(self, sorted=True, relativize=True, nl=None): + """Return a zone's text as though it were written to a file. + + @param sorted: if True, the file will be written with the + names sorted in DNSSEC order from least to greatest. Otherwise + the names will be written in whatever order they happen to have + in the zone's dictionary. + @param relativize: if True, domain names in the output will be + relativized to the zone's origin (if possible). + @type relativize: bool + @param nl: The end of line string. If not specified, the + output will use the platform's native end-of-line marker (i.e. + LF on POSIX, CRLF on Windows, CR on Macintosh). + @type nl: string or None + """ + temp_buffer = BytesIO() + self.to_file(temp_buffer, sorted, relativize, nl) + return_value = temp_buffer.getvalue() + temp_buffer.close() + return return_value + + def check_origin(self): + """Do some simple checking of the zone's origin. + + @raises dns.zone.NoSOA: there is no SOA RR + @raises dns.zone.NoNS: there is no NS RRset + @raises KeyError: there is no origin node + """ + if self.relativize: + name = dns.name.empty + else: + name = self.origin + if self.get_rdataset(name, dns.rdatatype.SOA) is None: + raise NoSOA + if self.get_rdataset(name, dns.rdatatype.NS) is None: + raise NoNS + + +class _MasterReader(object): + + """Read a DNS master file + + @ivar tok: The tokenizer + @type tok: dns.tokenizer.Tokenizer object + @ivar last_ttl: The last seen explicit TTL for an RR + @type last_ttl: int + @ivar last_ttl_known: Has last TTL been detected + @type last_ttl_known: bool + @ivar default_ttl: The default TTL from a $TTL directive or SOA RR + @type default_ttl: int + @ivar default_ttl_known: Has default TTL been detected + @type default_ttl_known: bool + @ivar last_name: The last name read + @type last_name: dns.name.Name object + @ivar current_origin: The current origin + @type current_origin: dns.name.Name object + @ivar relativize: should names in the zone be relativized? + @type relativize: bool + @ivar zone: the zone + @type zone: dns.zone.Zone object + @ivar saved_state: saved reader state (used when processing $INCLUDE) + @type saved_state: list of (tokenizer, current_origin, last_name, file, + last_ttl, last_ttl_known, default_ttl, default_ttl_known) tuples. + @ivar current_file: the file object of the $INCLUDed file being parsed + (None if no $INCLUDE is active). + @ivar allow_include: is $INCLUDE allowed? + @type allow_include: bool + @ivar check_origin: should sanity checks of the origin node be done? + The default is True. + @type check_origin: bool + """ + + def __init__(self, tok, origin, rdclass, relativize, zone_factory=Zone, + allow_include=False, check_origin=True): + if isinstance(origin, string_types): + origin = dns.name.from_text(origin) + self.tok = tok + self.current_origin = origin + self.relativize = relativize + self.last_ttl = 0 + self.last_ttl_known = False + self.default_ttl = 0 + self.default_ttl_known = False + self.last_name = self.current_origin + self.zone = zone_factory(origin, rdclass, relativize=relativize) + self.saved_state = [] + self.current_file = None + self.allow_include = allow_include + self.check_origin = check_origin + + def _eat_line(self): + while 1: + token = self.tok.get() + if token.is_eol_or_eof(): + break + + def _rr_line(self): + """Process one line from a DNS master file.""" + # Name + if self.current_origin is None: + raise UnknownOrigin + token = self.tok.get(want_leading=True) + if not token.is_whitespace(): + self.last_name = dns.name.from_text( + token.value, self.current_origin) + else: + token = self.tok.get() + if token.is_eol_or_eof(): + # treat leading WS followed by EOL/EOF as if they were EOL/EOF. + return + self.tok.unget(token) + name = self.last_name + if not name.is_subdomain(self.zone.origin): + self._eat_line() + return + if self.relativize: + name = name.relativize(self.zone.origin) + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + # TTL + try: + ttl = dns.ttl.from_text(token.value) + self.last_ttl = ttl + self.last_ttl_known = True + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except dns.ttl.BadTTL: + if not (self.last_ttl_known or self.default_ttl_known): + raise dns.exception.SyntaxError("Missing default TTL value") + if self.default_ttl_known: + ttl = self.default_ttl + else: + ttl = self.last_ttl + # Class + try: + rdclass = dns.rdataclass.from_text(token.value) + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except dns.exception.SyntaxError: + raise dns.exception.SyntaxError + except Exception: + rdclass = self.zone.rdclass + if rdclass != self.zone.rdclass: + raise dns.exception.SyntaxError("RR class is not zone's class") + # Type + try: + rdtype = dns.rdatatype.from_text(token.value) + except: + raise dns.exception.SyntaxError( + "unknown rdatatype '%s'" % token.value) + n = self.zone.nodes.get(name) + if n is None: + n = self.zone.node_factory() + self.zone.nodes[name] = n + try: + rd = dns.rdata.from_text(rdclass, rdtype, self.tok, + self.current_origin, False) + except dns.exception.SyntaxError: + # Catch and reraise. + (ty, va) = sys.exc_info()[:2] + raise va + except: + # All exceptions that occur in the processing of rdata + # are treated as syntax errors. This is not strictly + # correct, but it is correct almost all of the time. + # We convert them to syntax errors so that we can emit + # helpful filename:line info. + (ty, va) = sys.exc_info()[:2] + raise dns.exception.SyntaxError( + "caught exception {}: {}".format(str(ty), str(va))) + + if not self.default_ttl_known and isinstance(rd, dns.rdtypes.ANY.SOA.SOA): + # The pre-RFC2308 and pre-BIND9 behavior inherits the zone default + # TTL from the SOA minttl if no $TTL statement is present before the + # SOA is parsed. + self.default_ttl = rd.minimum + self.default_ttl_known = True + + rd.choose_relativity(self.zone.origin, self.relativize) + covers = rd.covers() + rds = n.find_rdataset(rdclass, rdtype, covers, True) + rds.add(rd, ttl) + + def _parse_modify(self, side): + # Here we catch everything in '{' '}' in a group so we can replace it + # with ''. + is_generate1 = re.compile("^.*\$({(\+|-?)(\d+),(\d+),(.)}).*$") + is_generate2 = re.compile("^.*\$({(\+|-?)(\d+)}).*$") + is_generate3 = re.compile("^.*\$({(\+|-?)(\d+),(\d+)}).*$") + # Sometimes there are modifiers in the hostname. These come after + # the dollar sign. They are in the form: ${offset[,width[,base]]}. + # Make names + g1 = is_generate1.match(side) + if g1: + mod, sign, offset, width, base = g1.groups() + if sign == '': + sign = '+' + g2 = is_generate2.match(side) + if g2: + mod, sign, offset = g2.groups() + if sign == '': + sign = '+' + width = 0 + base = 'd' + g3 = is_generate3.match(side) + if g3: + mod, sign, offset, width = g1.groups() + if sign == '': + sign = '+' + width = g1.groups()[2] + base = 'd' + + if not (g1 or g2 or g3): + mod = '' + sign = '+' + offset = 0 + width = 0 + base = 'd' + + if base != 'd': + raise NotImplementedError() + + return mod, sign, offset, width, base + + def _generate_line(self): + # range lhs [ttl] [class] type rhs [ comment ] + """Process one line containing the GENERATE statement from a DNS + master file.""" + if self.current_origin is None: + raise UnknownOrigin + + token = self.tok.get() + # Range (required) + try: + start, stop, step = dns.grange.from_text(token.value) + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except: + raise dns.exception.SyntaxError + + # lhs (required) + try: + lhs = token.value + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except: + raise dns.exception.SyntaxError + + # TTL + try: + ttl = dns.ttl.from_text(token.value) + self.last_ttl = ttl + self.last_ttl_known = True + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except dns.ttl.BadTTL: + if not (self.last_ttl_known or self.default_ttl_known): + raise dns.exception.SyntaxError("Missing default TTL value") + if self.default_ttl_known: + ttl = self.default_ttl + else: + ttl = self.last_ttl + # Class + try: + rdclass = dns.rdataclass.from_text(token.value) + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except dns.exception.SyntaxError: + raise dns.exception.SyntaxError + except Exception: + rdclass = self.zone.rdclass + if rdclass != self.zone.rdclass: + raise dns.exception.SyntaxError("RR class is not zone's class") + # Type + try: + rdtype = dns.rdatatype.from_text(token.value) + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError + except Exception: + raise dns.exception.SyntaxError("unknown rdatatype '%s'" % + token.value) + + # lhs (required) + try: + rhs = token.value + except: + raise dns.exception.SyntaxError + + lmod, lsign, loffset, lwidth, lbase = self._parse_modify(lhs) + rmod, rsign, roffset, rwidth, rbase = self._parse_modify(rhs) + for i in range(start, stop + 1, step): + # +1 because bind is inclusive and python is exclusive + + if lsign == u'+': + lindex = i + int(loffset) + elif lsign == u'-': + lindex = i - int(loffset) + + if rsign == u'-': + rindex = i - int(roffset) + elif rsign == u'+': + rindex = i + int(roffset) + + lzfindex = str(lindex).zfill(int(lwidth)) + rzfindex = str(rindex).zfill(int(rwidth)) + + name = lhs.replace(u'$%s' % (lmod), lzfindex) + rdata = rhs.replace(u'$%s' % (rmod), rzfindex) + + self.last_name = dns.name.from_text(name, self.current_origin) + name = self.last_name + if not name.is_subdomain(self.zone.origin): + self._eat_line() + return + if self.relativize: + name = name.relativize(self.zone.origin) + + n = self.zone.nodes.get(name) + if n is None: + n = self.zone.node_factory() + self.zone.nodes[name] = n + try: + rd = dns.rdata.from_text(rdclass, rdtype, rdata, + self.current_origin, False) + except dns.exception.SyntaxError: + # Catch and reraise. + (ty, va) = sys.exc_info()[:2] + raise va + except: + # All exceptions that occur in the processing of rdata + # are treated as syntax errors. This is not strictly + # correct, but it is correct almost all of the time. + # We convert them to syntax errors so that we can emit + # helpful filename:line info. + (ty, va) = sys.exc_info()[:2] + raise dns.exception.SyntaxError("caught exception %s: %s" % + (str(ty), str(va))) + + rd.choose_relativity(self.zone.origin, self.relativize) + covers = rd.covers() + rds = n.find_rdataset(rdclass, rdtype, covers, True) + rds.add(rd, ttl) + + def read(self): + """Read a DNS master file and build a zone object. + + @raises dns.zone.NoSOA: No SOA RR was found at the zone origin + @raises dns.zone.NoNS: No NS RRset was found at the zone origin + """ + + try: + while 1: + token = self.tok.get(True, True) + if token.is_eof(): + if self.current_file is not None: + self.current_file.close() + if len(self.saved_state) > 0: + (self.tok, + self.current_origin, + self.last_name, + self.current_file, + self.last_ttl, + self.last_ttl_known, + self.default_ttl, + self.default_ttl_known) = self.saved_state.pop(-1) + continue + break + elif token.is_eol(): + continue + elif token.is_comment(): + self.tok.get_eol() + continue + elif token.value[0] == u'$': + c = token.value.upper() + if c == u'$TTL': + token = self.tok.get() + if not token.is_identifier(): + raise dns.exception.SyntaxError("bad $TTL") + self.default_ttl = dns.ttl.from_text(token.value) + self.default_ttl_known = True + self.tok.get_eol() + elif c == u'$ORIGIN': + self.current_origin = self.tok.get_name() + self.tok.get_eol() + if self.zone.origin is None: + self.zone.origin = self.current_origin + elif c == u'$INCLUDE' and self.allow_include: + token = self.tok.get() + filename = token.value + token = self.tok.get() + if token.is_identifier(): + new_origin =\ + dns.name.from_text(token.value, + self.current_origin) + self.tok.get_eol() + elif not token.is_eol_or_eof(): + raise dns.exception.SyntaxError( + "bad origin in $INCLUDE") + else: + new_origin = self.current_origin + self.saved_state.append((self.tok, + self.current_origin, + self.last_name, + self.current_file, + self.last_ttl, + self.last_ttl_known, + self.default_ttl, + self.default_ttl_known)) + self.current_file = open(filename, 'r') + self.tok = dns.tokenizer.Tokenizer(self.current_file, + filename) + self.current_origin = new_origin + elif c == u'$GENERATE': + self._generate_line() + else: + raise dns.exception.SyntaxError( + "Unknown master file directive '" + c + "'") + continue + self.tok.unget(token) + self._rr_line() + except dns.exception.SyntaxError as detail: + (filename, line_number) = self.tok.where() + if detail is None: + detail = "syntax error" + raise dns.exception.SyntaxError( + "%s:%d: %s" % (filename, line_number, detail)) + + # Now that we're done reading, do some basic checking of the zone. + if self.check_origin: + self.zone.check_origin() + + +def from_text(text, origin=None, rdclass=dns.rdataclass.IN, + relativize=True, zone_factory=Zone, filename=None, + allow_include=False, check_origin=True): + """Build a zone object from a master file format string. + + @param text: the master file format input + @type text: string. + @param origin: The origin of the zone; if not specified, the first + $ORIGIN statement in the master file will determine the origin of the + zone. + @type origin: dns.name.Name object or string + @param rdclass: The zone's rdata class; the default is class IN. + @type rdclass: int + @param relativize: should names be relativized? The default is True + @type relativize: bool + @param zone_factory: The zone factory to use + @type zone_factory: function returning a Zone + @param filename: The filename to emit when describing where an error + occurred; the default is ''. + @type filename: string + @param allow_include: is $INCLUDE allowed? + @type allow_include: bool + @param check_origin: should sanity checks of the origin node be done? + The default is True. + @type check_origin: bool + @raises dns.zone.NoSOA: No SOA RR was found at the zone origin + @raises dns.zone.NoNS: No NS RRset was found at the zone origin + @rtype: dns.zone.Zone object + """ + + # 'text' can also be a file, but we don't publish that fact + # since it's an implementation detail. The official file + # interface is from_file(). + + if filename is None: + filename = '' + tok = dns.tokenizer.Tokenizer(text, filename) + reader = _MasterReader(tok, origin, rdclass, relativize, zone_factory, + allow_include=allow_include, + check_origin=check_origin) + reader.read() + return reader.zone + + +def from_file(f, origin=None, rdclass=dns.rdataclass.IN, + relativize=True, zone_factory=Zone, filename=None, + allow_include=True, check_origin=True): + """Read a master file and build a zone object. + + @param f: file or string. If I{f} is a string, it is treated + as the name of a file to open. + @param origin: The origin of the zone; if not specified, the first + $ORIGIN statement in the master file will determine the origin of the + zone. + @type origin: dns.name.Name object or string + @param rdclass: The zone's rdata class; the default is class IN. + @type rdclass: int + @param relativize: should names be relativized? The default is True + @type relativize: bool + @param zone_factory: The zone factory to use + @type zone_factory: function returning a Zone + @param filename: The filename to emit when describing where an error + occurred; the default is '', or the value of I{f} if I{f} is a + string. + @type filename: string + @param allow_include: is $INCLUDE allowed? + @type allow_include: bool + @param check_origin: should sanity checks of the origin node be done? + The default is True. + @type check_origin: bool + @raises dns.zone.NoSOA: No SOA RR was found at the zone origin + @raises dns.zone.NoNS: No NS RRset was found at the zone origin + @rtype: dns.zone.Zone object + """ + + str_type = string_types + if PY3: + opts = 'r' + else: + opts = 'rU' + + if isinstance(f, str_type): + if filename is None: + filename = f + f = open(f, opts) + want_close = True + else: + if filename is None: + filename = '' + want_close = False + + try: + z = from_text(f, origin, rdclass, relativize, zone_factory, + filename, allow_include, check_origin) + finally: + if want_close: + f.close() + return z + + +def from_xfr(xfr, zone_factory=Zone, relativize=True, check_origin=True): + """Convert the output of a zone transfer generator into a zone object. + + @param xfr: The xfr generator + @type xfr: generator of dns.message.Message objects + @param relativize: should names be relativized? The default is True. + It is essential that the relativize setting matches the one specified + to dns.query.xfr(). + @type relativize: bool + @param check_origin: should sanity checks of the origin node be done? + The default is True. + @type check_origin: bool + @raises dns.zone.NoSOA: No SOA RR was found at the zone origin + @raises dns.zone.NoNS: No NS RRset was found at the zone origin + @rtype: dns.zone.Zone object + """ + + z = None + for r in xfr: + if z is None: + if relativize: + origin = r.origin + else: + origin = r.answer[0].name + rdclass = r.answer[0].rdclass + z = zone_factory(origin, rdclass, relativize=relativize) + for rrset in r.answer: + znode = z.nodes.get(rrset.name) + if not znode: + znode = z.node_factory() + z.nodes[rrset.name] = znode + zrds = znode.find_rdataset(rrset.rdclass, rrset.rdtype, + rrset.covers, True) + zrds.update_ttl(rrset.ttl) + for rd in rrset: + rd.choose_relativity(z.origin, relativize) + zrds.add(rd) + if check_origin: + z.check_origin() + return z diff --git a/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/DESCRIPTION.rst b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..615ae68 --- /dev/null +++ b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/DESCRIPTION.rst @@ -0,0 +1,9 @@ +dnspython is a DNS toolkit for Python. It supports almost all +record types. It can be used for queries, zone transfers, and dynamic +updates. It supports TSIG authenticated messages and EDNS0. + +dnspython provides both high and low level access to DNS. The high +level classes perform queries for data of a given name, type, and +class, and return an answer set. The low level classes allow +direct manipulation of DNS zones, messages, names, and records. + diff --git a/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/INSTALLER b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/LICENSE.txt b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/LICENSE.txt new file mode 100644 index 0000000..390a726 --- /dev/null +++ b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/LICENSE.txt @@ -0,0 +1,35 @@ +ISC License + +Copyright (C) Dnspython Contributors + +Permission to use, copy, modify, and/or distribute this software for +any purpose with or without fee is hereby granted, provided that the +above copyright notice and this permission notice appear in all +copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL +WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL +DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. + + + +Copyright (C) 2001-2017 Nominum, Inc. +Copyright (C) Google Inc. + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose with or without fee is hereby granted, +provided that the above copyright notice and this permission notice +appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/METADATA b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/METADATA new file mode 100644 index 0000000..0dc8f67 --- /dev/null +++ b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/METADATA @@ -0,0 +1,44 @@ +Metadata-Version: 2.0 +Name: dnspython +Version: 1.16.0 +Summary: DNS toolkit +Home-page: http://www.dnspython.org +Author: Bob Halley +Author-email: halley@dnspython.org +License: BSD-like +Download-URL: http://www.dnspython.org/kits/1.16.0/dnspython-1.16.0.tar.gz +Description-Content-Type: UNKNOWN +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: System Administrators +Classifier: License :: Freeware +Classifier: Operating System :: Microsoft :: Windows :: Windows 95/98/2000 +Classifier: Operating System :: POSIX +Classifier: Programming Language :: Python +Classifier: Topic :: Internet :: Name Service (DNS) +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Provides: dns +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Provides-Extra: DNSSEC +Requires-Dist: pycryptodome; extra == 'DNSSEC' +Requires-Dist: ecdsa (>=0.13); extra == 'DNSSEC' +Provides-Extra: IDNA +Requires-Dist: idna (>=2.1); extra == 'IDNA' + +dnspython is a DNS toolkit for Python. It supports almost all +record types. It can be used for queries, zone transfers, and dynamic +updates. It supports TSIG authenticated messages and EDNS0. + +dnspython provides both high and low level access to DNS. The high +level classes perform queries for data of a given name, type, and +class, and return an answer set. The low level classes allow +direct manipulation of DNS zones, messages, names, and records. + diff --git a/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/RECORD b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/RECORD new file mode 100644 index 0000000..899689b --- /dev/null +++ b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/RECORD @@ -0,0 +1,201 @@ +dns/__init__.py,sha256=YT8dlV94eA9ycHtSAbLNjvBHJSYl3pM9nPkkR5d7HCw,1404 +dns/__pycache__/__init__.cpython-37.pyc,, +dns/__pycache__/_compat.cpython-37.pyc,, +dns/__pycache__/dnssec.cpython-37.pyc,, +dns/__pycache__/e164.cpython-37.pyc,, +dns/__pycache__/edns.cpython-37.pyc,, +dns/__pycache__/entropy.cpython-37.pyc,, +dns/__pycache__/exception.cpython-37.pyc,, +dns/__pycache__/flags.cpython-37.pyc,, +dns/__pycache__/grange.cpython-37.pyc,, +dns/__pycache__/hash.cpython-37.pyc,, +dns/__pycache__/inet.cpython-37.pyc,, +dns/__pycache__/ipv4.cpython-37.pyc,, +dns/__pycache__/ipv6.cpython-37.pyc,, +dns/__pycache__/message.cpython-37.pyc,, +dns/__pycache__/name.cpython-37.pyc,, +dns/__pycache__/namedict.cpython-37.pyc,, +dns/__pycache__/node.cpython-37.pyc,, +dns/__pycache__/opcode.cpython-37.pyc,, +dns/__pycache__/query.cpython-37.pyc,, +dns/__pycache__/rcode.cpython-37.pyc,, +dns/__pycache__/rdata.cpython-37.pyc,, +dns/__pycache__/rdataclass.cpython-37.pyc,, +dns/__pycache__/rdataset.cpython-37.pyc,, +dns/__pycache__/rdatatype.cpython-37.pyc,, +dns/__pycache__/renderer.cpython-37.pyc,, +dns/__pycache__/resolver.cpython-37.pyc,, +dns/__pycache__/reversename.cpython-37.pyc,, +dns/__pycache__/rrset.cpython-37.pyc,, +dns/__pycache__/set.cpython-37.pyc,, +dns/__pycache__/tokenizer.cpython-37.pyc,, +dns/__pycache__/tsig.cpython-37.pyc,, +dns/__pycache__/tsigkeyring.cpython-37.pyc,, +dns/__pycache__/ttl.cpython-37.pyc,, +dns/__pycache__/update.cpython-37.pyc,, +dns/__pycache__/version.cpython-37.pyc,, +dns/__pycache__/wiredata.cpython-37.pyc,, +dns/__pycache__/zone.cpython-37.pyc,, +dns/_compat.py,sha256=_z_CnqBp0U_8VXGaAEgM6YP0xWsGWC7Xibm3uBlgJpg,1503 +dns/dnssec.py,sha256=MjoQ6ldvWSW3KHBSIO0bxCmsLpLapeYW2T8Rzy2DbI0,16504 +dns/e164.py,sha256=uEHNlLy8p6j4S2WPQdMU9wAM4b2xbprWz_Hsc2EPwO8,3753 +dns/edns.py,sha256=ITjQuaPXdW7ZHlk7qSyHYsFk3Yk1jqagwaia10aQx7g,7424 +dns/entropy.py,sha256=LZRtKxcTTd7Ng4P5m2rBJGz3r_qq0G-JqbqybrbBx8I,4771 +dns/exception.py,sha256=_SYm0BLa0MrfpU2B0jMnRDPdKCVs6jmx8_ZSAcwzAJY,4876 +dns/flags.py,sha256=5nsxoZCLqeNmxsLGIKpJBVk8_hhhgpTleEc-421kh-8,2933 +dns/grange.py,sha256=sfbj8pZPMSIdYVORMrBXPcSXusjwRipOxRgMEoywqTk,2055 +dns/hash.py,sha256=2UG0QEO_5D8NNEvr1YdDXcRQcxmQdzgbNCaXgtKYlY0,1319 +dns/inet.py,sha256=C78xVq0uxIh0PYLH7S48DPVaUeJ1GfF9re1w7BOIu70,3377 +dns/ipv4.py,sha256=fkXKFagx7pLwccrtXA4AF7iQCj_6lSkFYRSTbyC7DNk,2096 +dns/ipv6.py,sha256=Z3O21oNPpah3vRG0l4qQ9fnTrG0dy5DvfPU-GVBb20Q,5527 +dns/message.py,sha256=GRq9c8TsZTOd6Pin2v4wnAFT5N0OZ_daAP_Epx_fvrc,41458 +dns/name.py,sha256=TaQOg32XZ2rJKMpQdt-MZk_Kf5QDwDsv87OIPjIuBrY,31259 +dns/namedict.py,sha256=9_rRigVZkJGyfxEepLTjX-aaNiyP_ZgmW_tlEP4mR-U,3958 +dns/node.py,sha256=lOuOEIBvo8t4XumjYc0DxUPpmjXntbYI9qP4kMuqrCw,6352 +dns/opcode.py,sha256=fV5_ysudkxiUsXRHJPKOnzopShXTzLSNLtb5CauRosA,2832 +dns/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +dns/query.py,sha256=wXvMrhGRmGejSa2OOBZBOpl83WeD3-5D7u_isQCvtaY,23691 +dns/rcode.py,sha256=5t18m2ZaDgrNQsyguKjzFWAOR0oBaHXjujjZUxs1uJ4,3613 +dns/rdata.py,sha256=zcn8qsDK3oZlcnfEGcf275XCwJ1Vh1c49yey8TEfF7M,14451 +dns/rdataclass.py,sha256=E1zIUb8f3BotxiKvrcDZGTLt8jaEJ8WThvTU7_hDv2g,3219 +dns/rdataset.py,sha256=4Nrn5tPsb8dpz78UAej98GDiK6uNeHh0Cqss1p7oxPQ,11463 +dns/rdatatype.py,sha256=qTGY1IPbR8cu4oGcGw0e5HPyXWEluBNcrsLL9navOtA,5917 +dns/rdtypes/ANY/AFSDB.py,sha256=TivfOjrAjOCLrli_3xE33ufzbUGug28ZC2fHo6WOups,1925 +dns/rdtypes/ANY/AVC.py,sha256=eiCzYvivS3ecZjVWIW4KaJ_ki3WuNDXQ_Iv_1bnlrT0,1027 +dns/rdtypes/ANY/CAA.py,sha256=eOR3lhOk0PhVjhSwtup4XbstENKM_kn0XkeLRLF-DBw,2699 +dns/rdtypes/ANY/CDNSKEY.py,sha256=_C5m5PHSr3YWXJm-a50yRf11NQsGATjtQBm_9uGarso,1103 +dns/rdtypes/ANY/CDS.py,sha256=RglDWyG-ZQn8NiVhVeI1QuSj8Do5EREf2aclzE-JwGE,952 +dns/rdtypes/ANY/CERT.py,sha256=UGKOYvAtGmGnEDJFKgo1NOihsIyLJohQw4ExG4RHl_8,4028 +dns/rdtypes/ANY/CNAME.py,sha256=9kuO5FBKKIHaAjcvo02_65Sg6dletz2wAWd5qNGaHDw,1161 +dns/rdtypes/ANY/CSYNC.py,sha256=lNl6vrOgCWdrVx7WF0-l_T5_s7zYWI66_3D9VwCma8Q,4721 +dns/rdtypes/ANY/DLV.py,sha256=wM1BUX0ufYMXMOqNyfCTMVDFy5dBvwpqmrJydwEd4vQ,941 +dns/rdtypes/ANY/DNAME.py,sha256=Wf02V8IB-lEIJT2wVqTtvOP5_OCpHowKcG5wpLs-4Pk,1056 +dns/rdtypes/ANY/DNSKEY.py,sha256=gHEWjBjO0zHpz0yamASTfC3U7sUIom58gBRSOuPnxJ8,1101 +dns/rdtypes/ANY/DS.py,sha256=zE7c-rxxwzqnqBDEDotvCrD45piCgg_kTp7DOEKhpIA,950 +dns/rdtypes/ANY/EUI48.py,sha256=bX_FaWgbh96dRb_CNr9Ltc03rPRtheQp99luJJpP-WE,1124 +dns/rdtypes/ANY/EUI64.py,sha256=9FzHF90pc7Ls0RO1jfPFnezfC_5iDjAdZEdSljRqEt0,1134 +dns/rdtypes/ANY/GPOS.py,sha256=0A3uPPrb4FKuUQsKnPPxXcGkfR-STQi4P7ntlVOQi-k,5450 +dns/rdtypes/ANY/HINFO.py,sha256=OrmLq8oD-JxjlgZI5MJFP6OilW7YLLwKkKrGceuAtYQ,2750 +dns/rdtypes/ANY/HIP.py,sha256=qnjxZtJ27bh31o2RLWDdIm3uDis3oirqf5uwCrmiLvM,4221 +dns/rdtypes/ANY/ISDN.py,sha256=0Ysj_ugB1feFvSyjRh82cwnDlmzIECxk9R5HGrF8OcA,3350 +dns/rdtypes/ANY/LOC.py,sha256=ud8bHZ3dBJ4jtE_r8naH1rfKSI3TQnx6txohJMbDTaU,12351 +dns/rdtypes/ANY/MX.py,sha256=DMw5gGSBQcwokT6ScqaXqOuluXg9IebOg-Nyi__RS14,950 +dns/rdtypes/ANY/NS.py,sha256=OcTL4Cg9snF5tOBFcxm-qeB6aII-oXEzsxqJozNxQl4,950 +dns/rdtypes/ANY/NSEC.py,sha256=oYJZLMmj1isl7TOyo72zgkNLiskL1ud6aa52_qJy4CI,4771 +dns/rdtypes/ANY/NSEC3.py,sha256=vZJCQ7OWSgCsOIbOKLie5Q6a5LlfQuKOUj1mBN4As_M,7211 +dns/rdtypes/ANY/NSEC3PARAM.py,sha256=UcqvoUrFzsuu_6Ba6ufpwnqb-hwgnXi43qt69Pa2qGI,3175 +dns/rdtypes/ANY/OPENPGPKEY.py,sha256=eaOu9n_GSC1GBKpYzBshRnDzeObMoZ0G0csFZPvhZPg,2028 +dns/rdtypes/ANY/PTR.py,sha256=bWEntdSYSZHZl8yVOsiCaU1V_JRBOMYjmeRtzfJPUBU,952 +dns/rdtypes/ANY/RP.py,sha256=4xc4eEM-l6IQmKr0dlpzY3mRkZyAe1fUkeRKxd5JIWI,3151 +dns/rdtypes/ANY/RRSIG.py,sha256=PQp-jckD0s9GyI01vi24gwVv6mzDYtKX5I_X8jCi1l8,5740 +dns/rdtypes/ANY/RT.py,sha256=Pb57qTz4O_ZKzP3IBOeii4IX7gGV_DeUZADxh8UuDA4,968 +dns/rdtypes/ANY/SOA.py,sha256=hhcigkLhIMPlgoD9zBYSduKGsHJM4LO7hVjmnXUsfg8,4597 +dns/rdtypes/ANY/SPF.py,sha256=2shb4N_8gRfIy0Yi6WAHSE4kIau_4ca-3fACfIWxeCg,976 +dns/rdtypes/ANY/SSHFP.py,sha256=3uSooQ_wYkXIqi2jYeRkfPedLFdko90vqNexd9Wkyi8,2905 +dns/rdtypes/ANY/TLSA.py,sha256=7d3r3TqKDV9E_ElrfAv_ZIPi67OcXM2hvXRA3DWtom0,3033 +dns/rdtypes/ANY/TXT.py,sha256=6Xb_tt8MRgMv-G6FMBluoxUhMN1G18zrMGB7WvwZIyE,955 +dns/rdtypes/ANY/URI.py,sha256=-eXBeUQDClnaok4stZCyCg9GbkdZaBBqQ4Z5zrgFqmI,2975 +dns/rdtypes/ANY/X25.py,sha256=6IYIyZ2iVEh0fXnRJHHiO0XU-HwJi-eafbjbyU6CGK0,2196 +dns/rdtypes/ANY/__init__.py,sha256=Sn0vG1e7mSZuSfaRKauVLTLnalp8qLkjVE57bJ2F8ls,1362 +dns/rdtypes/ANY/__pycache__/AFSDB.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/AVC.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/CAA.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/CDNSKEY.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/CDS.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/CERT.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/CNAME.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/CSYNC.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/DLV.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/DNAME.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/DNSKEY.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/DS.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/EUI48.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/EUI64.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/GPOS.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/HINFO.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/HIP.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/ISDN.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/LOC.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/MX.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/NS.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/NSEC.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/NSEC3.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/NSEC3PARAM.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/OPENPGPKEY.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/PTR.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/RP.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/RRSIG.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/RT.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/SOA.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/SPF.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/SSHFP.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/TLSA.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/TXT.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/URI.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/X25.cpython-37.pyc,, +dns/rdtypes/ANY/__pycache__/__init__.cpython-37.pyc,, +dns/rdtypes/CH/A.py,sha256=m1UXsasKInSoeNNmmEl2Tp7B_2nI90PUVu01HzttguM,2797 +dns/rdtypes/CH/__init__.py,sha256=Ef8Z58kdxbLpTqtgP_u3MfVQoqwb3If2T68YEwIMosw,923 +dns/rdtypes/CH/__pycache__/A.cpython-37.pyc,, +dns/rdtypes/CH/__pycache__/__init__.cpython-37.pyc,, +dns/rdtypes/IN/A.py,sha256=QQgxIU06-fPMyO9g_lcitItWMa9HQMxP4hVK3s-X9BY,1921 +dns/rdtypes/IN/AAAA.py,sha256=GUs2fIXxJmNGaOJPdTkbJPoSd4841RE61wuwrDaB1B4,2015 +dns/rdtypes/IN/APL.py,sha256=O-dQdw6sDOYDkP0k34NjO0jGQ802yWULHYVNf0Q_wUE,5344 +dns/rdtypes/IN/DHCID.py,sha256=4J6H3ByUhNYWDD8HqZ3iL-xc0EiNmnBFzrwtB899PL0,2096 +dns/rdtypes/IN/IPSECKEY.py,sha256=twKeJ3fsWCAvJhwDCuF6TAKLLpQuoq0w6UElX1jk4cs,5758 +dns/rdtypes/IN/KX.py,sha256=vxNd0l6qH5lgxmyLpqB3wuAlBOdoCM1833zvoAgPuv4,958 +dns/rdtypes/IN/NAPTR.py,sha256=KF-NbGiG3156nolAn667sebs7oi8M3B54cNK9qHK1aw,4547 +dns/rdtypes/IN/NSAP.py,sha256=Z0WR3gba4PnOEL7JY-EiLEVOIFG1hUx7PPY446XuwaE,2156 +dns/rdtypes/IN/NSAP_PTR.py,sha256=EH_tKmNfHJqys5qmRv3GwwmRH2ojjGnw1mUgEDXOcaA,970 +dns/rdtypes/IN/PX.py,sha256=ZSsAI9zmQA2Io7Xbp-1cz3YwIIhRjaAsvYhYKH0b8JY,3471 +dns/rdtypes/IN/SRV.py,sha256=1S8PTQWI5WqcLSV4fheW32USi9edkUdkQEamJuF-RTg,3131 +dns/rdtypes/IN/WKS.py,sha256=5yMZhMZ6sxiyzKgeEEL-H-E4kyfnykjjeBCt6SqzEIU,3888 +dns/rdtypes/IN/__init__.py,sha256=mNZ9A4tfstUe-moGqbJUVC0QVih_72I1cyeOe7nyREY,1058 +dns/rdtypes/IN/__pycache__/A.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/AAAA.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/APL.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/DHCID.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/IPSECKEY.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/KX.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/NAPTR.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/NSAP.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/NSAP_PTR.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/PX.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/SRV.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/WKS.cpython-37.pyc,, +dns/rdtypes/IN/__pycache__/__init__.cpython-37.pyc,, +dns/rdtypes/__init__.py,sha256=7pq8IJL8HfnyKC0beC-jhh7pKQ0Gr7KFtzGAvUndhRQ,982 +dns/rdtypes/__pycache__/__init__.cpython-37.pyc,, +dns/rdtypes/__pycache__/dnskeybase.cpython-37.pyc,, +dns/rdtypes/__pycache__/dsbase.cpython-37.pyc,, +dns/rdtypes/__pycache__/euibase.cpython-37.pyc,, +dns/rdtypes/__pycache__/mxbase.cpython-37.pyc,, +dns/rdtypes/__pycache__/nsbase.cpython-37.pyc,, +dns/rdtypes/__pycache__/txtbase.cpython-37.pyc,, +dns/rdtypes/dnskeybase.py,sha256=xqmBGcdg0uFl1FVTOBVtL9LJUip5VoeiBzk2o4cZRXs,4458 +dns/rdtypes/dsbase.py,sha256=2aKIy2azXkEDLAsf-GMXlHvpxtQ5a2FQUhbfT6PKDCg,3157 +dns/rdtypes/euibase.py,sha256=UaY1YOQBPZ3KKMEmFku9JL6S1CyQVJVzeFtJzyrwZHU,2777 +dns/rdtypes/mxbase.py,sha256=Hn9RJqnIz9LAt4kizE9jciw5wFazJs-BOA9MbGVE-SE,3737 +dns/rdtypes/nsbase.py,sha256=lYWBj09-aqMHwAL2tJF_jC5-_QcBS_t9v2o1uvGOzYA,2928 +dns/rdtypes/txtbase.py,sha256=uai-BeKwCZZpK4IiftS4IckjYIk9T0zxKI5RcNVmCZM,3328 +dns/renderer.py,sha256=TOrnxiYw91UnPUd4tR1C3OE9C5mVBNsuTlOrD1GeSp4,10826 +dns/resolver.py,sha256=yAXPLBxex3uD0780bZZSeVjBaclnG8BhjLpuwvZ-ikI,50210 +dns/reversename.py,sha256=I0rLFjFF0YXo1S6oZm2_1V_PVJyI_JfLdwv_YLIKpA4,3291 +dns/rrset.py,sha256=MaIKqdUfgo6BBRavfXb5w0M68Or9LtpDn5wdmSf12qc,6159 +dns/set.py,sha256=t3LFOnlRzMVY8jjit7kn4v9dDER1HHB8V1uMnHW2J44,7310 +dns/tokenizer.py,sha256=Z7pUpN__yNfWDhl4IBAQ96BaXOi8sCnOXnVRmaxGwT8,18040 +dns/tsig.py,sha256=GPnq7VBLfLjZrD3Cp7uYBeGjHpMHUfqwsQqKHZ0FIno,7813 +dns/tsigkeyring.py,sha256=HuOyV7UAT2TzcX2Xxi1YFGW7tDR_MlfXgsuzWJBT4A8,1814 +dns/ttl.py,sha256=5sukYG5gdkXgtkRjh8cDAJ0ZthSdR42QsPRshDQJJuc,2349 +dns/update.py,sha256=MOqvO2mNn3SOnTo9acDeTGq-YGRHjw60_FIRG309bGI,10343 +dns/version.py,sha256=iXOyp-lf9A1LC-XfdUU1NbkIKtqV4s61KI5XElbtMRs,1406 +dns/wiredata.py,sha256=RtfOFtbkzmxGUnJ9EuK4fdHU8shJLA46hWWH1y2NTtI,3751 +dns/zone.py,sha256=2alLKjAQ3X5VS22rvauolG0J-251kd5sKJSGzjJiu1M,42381 +dnspython-1.16.0.dist-info/DESCRIPTION.rst,sha256=6hmWFB2RbH9czYdOGp9iL1mpM00S6_G0I4kfijc1kwQ,454 +dnspython-1.16.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +dnspython-1.16.0.dist-info/LICENSE.txt,sha256=w-o_9WVLMpwZ07xfdIGvYjw93tSmFFWFSZ-EOtPXQc0,1526 +dnspython-1.16.0.dist-info/METADATA,sha256=MhWnFzd-dWhj5UKVHxoet9SSCcqgH5JQc6crlSbnfBI,1837 +dnspython-1.16.0.dist-info/RECORD,, +dnspython-1.16.0.dist-info/WHEEL,sha256=kdsN-5OJAZIiHN-iO4Rhl82KyS0bDWf4uBwMbkNafr8,110 +dnspython-1.16.0.dist-info/metadata.json,sha256=tR-xBI8ymSFJzryXXPK8cQaAEdES4COhW5fSlxPtJHE,1469 +dnspython-1.16.0.dist-info/top_level.txt,sha256=pNgzNfVoNIdUseB5acMPCTmUyu6m6aH47olUCAzzWTo,4 diff --git a/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/WHEEL b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/WHEEL new file mode 100644 index 0000000..7332a41 --- /dev/null +++ b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.30.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/metadata.json b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/metadata.json new file mode 100644 index 0000000..893283d --- /dev/null +++ b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: System Administrators", "License :: Freeware", "Operating System :: Microsoft :: Windows :: Windows 95/98/2000", "Operating System :: POSIX", "Programming Language :: Python", "Topic :: Internet :: Name Service (DNS)", "Topic :: Software Development :: Libraries :: Python Modules", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7"], "description_content_type": "UNKNOWN", "download_url": "http://www.dnspython.org/kits/1.16.0/dnspython-1.16.0.tar.gz", "extensions": {"python.details": {"contacts": [{"email": "halley@dnspython.org", "name": "Bob Halley", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst", "license": "LICENSE.txt"}, "project_urls": {"Home": "http://www.dnspython.org"}}}, "extras": ["DNSSEC", "IDNA"], "generator": "bdist_wheel (0.30.0)", "license": "BSD-like", "metadata_version": "2.0", "name": "dnspython", "provides": "dns", "requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*", "run_requires": [{"extra": "DNSSEC", "requires": ["ecdsa (>=0.13)", "pycryptodome"]}, {"extra": "IDNA", "requires": ["idna (>=2.1)"]}], "summary": "DNS toolkit", "version": "1.16.0"} \ No newline at end of file diff --git a/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/top_level.txt b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/top_level.txt new file mode 100644 index 0000000..2e7065c --- /dev/null +++ b/env/lib/python3.7/site-packages/dnspython-1.16.0.dist-info/top_level.txt @@ -0,0 +1 @@ +dns diff --git a/env/lib/python3.7/site-packages/easy_install.py b/env/lib/python3.7/site-packages/easy_install.py new file mode 100644 index 0000000..d87e984 --- /dev/null +++ b/env/lib/python3.7/site-packages/easy_install.py @@ -0,0 +1,5 @@ +"""Run the EasyInstall command""" + +if __name__ == '__main__': + from setuptools.command.easy_install import main + main() diff --git a/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/DESCRIPTION.rst b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/DESCRIPTION.rst new file mode 100644 index 0000000..dcecae5 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/DESCRIPTION.rst @@ -0,0 +1,495 @@ +======= +ipwhois +======= + +.. image:: https://travis-ci.org/secynic/ipwhois.svg?branch=master + :target: https://travis-ci.org/secynic/ipwhois +.. image:: https://coveralls.io/repos/github/secynic/ipwhois/badge.svg?branch= + master + :target: https://coveralls.io/github/secynic/ipwhois?branch=master +.. image:: https://codeclimate.com/github/secynic/ipwhois/badges/issue_count.svg + :target: https://codeclimate.com/github/secynic/ipwhois +.. image:: https://img.shields.io/badge/license-BSD%202--Clause-blue.svg + :target: https://github.com/secynic/ipwhois/tree/master/LICENSE.txt +.. image:: https://img.shields.io/badge/python-2.6%2C%202.7%2C%203.3+-blue.svg + :target: https://docs.python.org +.. image:: https://img.shields.io/badge/docs-latest-green.svg?style=flat + :target: https://ipwhois.readthedocs.io/en/latest +.. image:: https://img.shields.io/badge/docs-dev-yellow.svg?style=flat + :target: https://ipwhois.readthedocs.io/en/dev + +Summary +======= + +ipwhois is a Python package focused on retrieving and parsing whois data +for IPv4 and IPv6 addresses. + +.. note:: + + If you are experiencing latency issues, it is likely related to rate + limiting. Rate limiting is based on your source IP, which may be a problem + with multiple users behind the same proxy. Additionally, LACNIC implements + aggressive rate limiting. Experimental bulk query support is new as of + v1.0.0. + +Features +======== + +* Parses a majority of whois fields in to a standard dictionary +* IPv4 and IPv6 support +* Supports RDAP queries (recommended method, see: + https://tools.ietf.org/html/rfc7483) +* Proxy support for RDAP queries +* Supports legacy whois protocol queries +* Referral whois support for legacy whois protocol +* Recursive network parsing for IPs with parent/children networks listed +* National Internet Registry support for JPNIC and KRNIC +* Supports IP to ASN and ASN origin queries +* Python 2.6+ and 3.3+ supported +* Useful set of utilities +* Experimental bulk query support +* BSD license +* 100% core code coverage (See '# pragma: no cover' for exclusions) +* Human readable field translations +* Full CLI for IPWhois with optional ANSI colored console output. + +Links +===== + +Documentation +------------- + +GitHub latest +^^^^^^^^^^^^^ + +https://ipwhois.readthedocs.io/en/latest + +GitHub dev +^^^^^^^^^^ + +https://ipwhois.readthedocs.io/en/dev + +Examples +-------- + +https://github.com/secynic/ipwhois/tree/master/ipwhois/examples + +Github +------ + +https://github.com/secynic/ipwhois + +Pypi +---- + +https://pypi.org/project/ipwhois + +Changes +------- + +https://ipwhois.readthedocs.io/en/latest/CHANGES.html + +Upgrade Notes +------------- + +https://ipwhois.readthedocs.io/en/latest/UPGRADING.html + +Dependencies +============ + +Python 2.6:: + + dnspython + ipaddr + argparse (required only for CLI) + +Python 2.7:: + + dnspython + ipaddr + +Python 3.3+:: + + dnspython + +Installing +========== + +Latest release from PyPi:: + + pip install --upgrade ipwhois + +GitHub - Stable:: + + pip install -e git+https://github.com/secynic/ipwhois@master#egg=ipwhois + +GitHub - Dev:: + + pip install -e git+https://github.com/secynic/ipwhois@dev#egg=ipwhois + +Firewall Ports +============== + +ipwhois needs some outbound firewall ports opened from your host/server. + +:ASN (DNS): 53/tcp +:ASN (Whois): 43/tcp +:ASN (HTTP): + 80/tcp + + 443/tcp (Pending) +:RDAP (HTTP): + 80/tcp + + 443/tcp (Pending) +:NIR (HTTP): + 80/tcp + + 443/tcp (KRNIC) +:Legacy Whois: 43/tcp +:Get Host: 43/tcp + +API +=== + +IPWhois (main class) +-------------------- + +ipwhois.IPWhois is the base class for wrapping RDAP and Legacy Whois lookups. +Instantiate this object, then call one of the lookup functions: + +`RDAP (HTTP) - IPWhois.lookup_rdap() <#rdap-http>`_ +OR +`Legacy Whois - IPWhois.lookup_whois() <#legacy-whois>`_ + +Input +^^^^^ + ++--------------------+--------+-----------------------------------------------+ +| **Key** |**Type**| **Description** | ++--------------------+--------+-----------------------------------------------+ +| address | str | An IPv4 or IPv6 address as a string, integer, | +| | | IPv4Address, or IPv6Address. | ++--------------------+--------+-----------------------------------------------+ +| timeout | int | The default timeout for socket connections | +| | | in seconds. Defaults to 5. | ++--------------------+--------+-----------------------------------------------+ +| proxy_opener | object | The urllib.request.OpenerDirector request for | +| | | proxy support or None. | ++--------------------+--------+-----------------------------------------------+ +| allow_permutations | bool | Allow net.Net() to use additional methods if | +| | | DNS lookups to Cymru fail. *WARNING* | +| | | deprecated in favor of new argument | +| | | asn_methods. Defaults to True. | ++--------------------+--------+-----------------------------------------------+ + +RDAP (HTTP) +----------- + +IPWhois.lookup_rdap() is the recommended lookup method. RDAP provides a +far better data structure than legacy whois and REST lookups (previous +implementation). RDAP queries allow for parsing of contact information and +details for users, organizations, and groups. RDAP also provides more detailed +network information. + +RDAP documentation: + +https://ipwhois.readthedocs.io/en/latest/RDAP.html + +Legacy Whois +------------ + +Legacy Whois documentation: + +https://ipwhois.readthedocs.io/en/latest/WHOIS.html + +National Internet Registries +---------------------------- + +This library now supports NIR lookups for JPNIC and KRNIC. Previously, Whois +and RDAP data for Japan and South Korea was restricted. NIR lookups scrape +these national registries directly for the data restricted from regional +internet registries. NIR queries are enabled by default via the inc_nir +argument in the IPWhois.lookup_*() functions. + +https://ipwhois.readthedocs.io/en/latest/NIR.html + +Autonomous System Numbers +------------------------- + +This library now supports ASN origin lookups via Whois and HTTP. + +IP ASN functionality was moved to its own parser API (IPASN). + +There is no CLI for these yet. + +https://ipwhois.readthedocs.io/en/latest/ASN.html + +Utilities +--------- + +Utilities documentation: + +https://ipwhois.readthedocs.io/en/latest/UTILS.html + +Scripts +------- + +CLI documentation: + +https://ipwhois.readthedocs.io/en/latest/CLI.html + +Experimental Functions +---------------------- + +.. caution:: + + Functions in experimental.py contain new functionality that has not yet + been widely tested. Bulk lookup support contained here can result in + significant system/network resource utilization. Additionally, abuse of + this functionality may get you banned by the various services queried by + this library. Use at your own discretion. + +Experimental functions documentation: + +https://ipwhois.readthedocs.io/en/latest/EXPERIMENTAL.html + +Contributing +============ + +https://ipwhois.readthedocs.io/en/latest/CONTRIBUTING.html + +IP Reputation Support +===================== + +This feature is under consideration. Take a look at TekDefense's Automater: + +`TekDefense-Automater `_ + +Domain Support +============== + +There are no plans for domain whois support in this project. + +Look at Sven Slootweg's +`python-whois `_ for a library with +domain support. + +Special Thanks +============== + +Thank you JetBrains for the `PyCharm `_ +open source support! + +Thank you Chris Wells (`@cdubz `_) for your +extensive testing on the experimental functions! + +Last but not least, thank you to all the issue submitters and contributors. + + +Changelog +========= + +1.0.0 (2017-07-30) +------------------ + +- Deprecated asn_alts, allow_permutations in favor of new asn_methods (#158) +- Added new exception ASNOriginLookupError (#158) +- KRNIC lookups changed to HTTPS (#166) +- Added experimental functions - get_bulk_asn_whois, bulk_lookup_rdap (#134) +- Fixed bug in NIR lookups that caused addresses with multi-line contacts to + error (#172 - kwheeles) +- Added IANA Reserved CIDR 198.97.38.0/24 to ipv4_is_defined (#174) +- Fixed bug in RDAP notices/remarks parsing that would omit partial entries + missing one or more of title, description, links (#176) +- Added new return key asn_description via verbose ASN DNS lookup support and + modified ASN whois lookups. New argument get_asn_description to disable + additional DNS lookup (#176) +- Fixed some test function naming errors +- Added new generators to utils.py: ipv4_generate_random and + ipv6_generate_random (#183) +- Moved upgrade notes to new UPGRADING.rst +- Deprecated unnecessary protected class functions, changed to public in + asn.py, nir.py, and whois.py (#184) +- net.Net.get_host(), utils.ipv4_is_defined(), and utils.ipv6_is_defined now + return namedtuple instead of tuple. +- Changed docstrings to Google standard for better napoleon parsing (#185) +- Removed deprecated IPWhois.lookup() - This was moved to + IPWhois.lookup_whois() +- Fixed 'nets'->'range' bug for legacy whois CIDR net_range values (#188) +- Fixed a bug in IPASN/Net that caused the ASN result to vary if Cymru has + more than one ASN listed for an IP (#190) +- Updated ElasticSearch example for ES v5.5.1 (#138) + +0.15.1 (2017-02-16) +------------------- + +- Fixed IPv6 parsing for ASN origin lookups and added tests (#162 - ti-mo) +- Fixed recursive role parsing at depths greater than 0 (#161 - cdubz) + +0.15.0 (2017-02-02) +------------------- + +- Python 3.3+ dnspython3 requirement changed to dnspython (#155) +- Added ASN origin lookup support (#149) +- Moved ASN parsing from net.Net.get_asn_*() to new class asn.IPASN. + The original functions now return the raw query (#157) +- net.Net.lookup_asn() is deprecated in favor of asn.IPASN.lookup() (#157) +- Added new exception ASNParseError (#157) +- Fixed rate-limiting exception handling for when HTTP errors are returned + rather than JSON errors (rikonor - #144) +- Fixed rate-limit infinite recursion bug for legacy whois (rikonor - #144) +- Fixed bug in net.Net.get_http_raw() that would pass the encoded form_data on + retry rather than the original argument. +- Removed nose requirements and fixed travis.yml for updated pip +- Documentation updates +- Code style tweaks +- Updated tests and version info for Python 3.6 +- Added basic stress tests (#144) +- Minor tweaks to existing tests + +0.14.0 (2016-08-29) +------------------- + +- Changed legacy whois emails output type to list (#133) +- Fixed retry count non-decrementing infinite loop in + ipwhois.net.Net.get_whois() (issue #125 - krader1961) +- Added new function ipwhois.net.Net.get_http_raw() and tests (#67) +- Added National Internet Registry (JPNIC, KRNIC) support (#67). Enabled by + default in IPWhois.lookup_*(). Disable by passing inc_nir=False. Optionally, + lower level code can call nir.NIRWhois(). This enhancement results in extra + network queries, but more detailed information for NIRs. +- Added utils CLI (ipwhois_utils_cli.py) - #121. Installed to your environments + Scripts dir. This is a wrapper for utils.py. +- Documentation improvements (#123) +- kw arg readability (#115) +- Replaced usage of args with script_args in ipwhois_cli.py +- Minor optimization in whois.py and online/test_whois.py +- Added coveralls integration and re-enabled online tests with Travis CI +- Added Read the Docs support (#132) +- Added documentation (Sphinx) requirements.txt (#132) +- Fixed test imports +- Added --json argument (output in JSON format) to ipwhois_cli.py (#135) + +0.13.0 (2016-04-18) +------------------- + +- Added events_actor parsing for RDAP results. +- Added example for caching data via Redis (#81) +- Added normalization (human-readable field information) in hr.py (#47) +- README word wrap fix (#102) +- Fixed bug in exception handling for ASN HTTP lookups. +- Fixed bug in IPWhois.lookup_rdap() that caused ASN HTTP lookup responses to + be used in place of RDAP responses. +- Added new function Net.get_asn_http() and migrated code from + Net.lookup_asn() + new tests. +- Fixed bug in ASN HTTP fallback lookups for DNIC (#108). +- Added new parameter extra_org_map in Net.get_asn_http(), Net.lookup_asn(), + and IPWhois.lookup*() (#108). +- Fixed _RDAPCommon.summarize_notices() None check - changed len() to all(). +- Added CLI (ipwhois_cli.py) - #46. Installed to your environments Scripts dir. + This is a wrapper for ipwhois.py (IPWhois). Utils CLI will be in a future + release (#121). +- Documentation split up and added more detail (#81). + +0.12.0 (2016-03-28) +------------------- + +- Added headers parameter to ipwhois.Net.get_http_json() (issue #98). +- Fixed ASN HTTP lookup (fallback) Accept headers (issue #98). +- Fixed HTTP decoding, set to utf-8 (italomaia - issue #97) +- IPWhois.lookup() deprecated (issue #96), and will be removed in a future + release (TBD). Use IPWhois.lookup_whois() instead. +- Added rate_limit_timeout parameter (issue #99) to Net.get_http_json(), + IPWhois.lookup_rdap(), and RDAP.lookup(). New exception HTTPRateLimitError. +- Added new parameter asn_alts to Net.lookup_asn(), IPWhois.lookup_rdap() and + IPWhois.lookup(). Takes a list of lookup types to attempt if the + ASN dns lookup fails. Allow permutations must be enabled. Defaults to all + ['whois', 'http'] (issue #93). +- Fixed socket exception handling in Net.get_http_json() for Python 2.6. +- Fixed assertIsInstance for Python 2.6 tests (issue #100). Implemented + unittest._formatMessage and unittest.util.safe_repr for Python 2.6. +- Moved TestCommon to tests\\__init__.py to avoid duplicate code. +- Replaced remaining % with str.format (issue #95). + +0.11.2 (2016-02-25) +------------------- + +- Added allow_permutations parameter (bool) to net.Net() and ipwhois.IPWhois() + to allow alternate ASN lookups if DNS lookups fail. (FirefighterBlu3) +- Fixed ASN DNS resolver timeout/retry_count support. Retry count is used as a + multiplier of timeout, to determine a limetime interval. (FirefighterBlu3) +- Fixed bug where remarks would return None if missing a title. +- Added CONTRIBUTING.rst +- Added tests + +0.11.1 (2015-12-17) +------------------- + +- Re-added CIDR calculation for RDAP lookups. +- Improved tests - core code coverage now 100%. See '# pragma: no cover' for + exclusions. A few bugs were identified in the process, detailed below. +- Moved IP zero stripping from rdap._RDAPNetwork.parse() to new helper function + utils.ipv4_lstrip_zeros(). +- Moved CIDR calculation from rdap._RDAPNetwork.parse() to new helper function + utils.calculate_cidr(). +- Fixed utils.ipv4_is_defined() if statement ordering for RFC 1918 conflict. +- Fixed utils.ipv6_is_defined() if statement ordering for Unspecified and + Loopback (conflict with Reserved). +- Added is_offline parameter to whois.Whois.lookup() primarily for testing. +- Fixed bug in whois.Whois._parse_fields() that attempted to parse 'val2' of + regex, which is no longer used. Also fixed the expected Exception to be + IndexError. +- Fixed bug in ipwhois.IPWhois.lookup() where the argument order was mixed up, + causing referral lookups to be skipped when get_referral=True. +- Fixed bug in rdap._RDAPCommon.summarize_notices() output for links. +- Fixed bug in root entity iteration exception handling in rdap.RDAP.lookup(). + +0.11.0 (2015-11-02) +------------------- + +- Support for REST lookups replaced with RDAP. +- Split code for a more structured system (net, whois, rdap, exceptions). +- Tests match the data new structure. +- Split tests for online and offline testing. +- Performance enhancements for parsing. +- Added an optional bootstrap parameter for RDAP lookups, in order to replace + ASN lookups or use both. Will default to False. Afrinic is currently not + supported, so I would not use this for now. ARIN acknowledged my issue + for this, and will be adding support back in for Afrinic bootstrap. +- Added field_list parameter (inclusion list) for WHOIS lookups. +- Added logging. +- Added examples directory. + +0.10.3 (2015-08-14) +------------------- + +- Fixed LACNIC lookup_rws() queries, since they switched to RDAP. This is + temporary to get it working until the major library transition to RDAP and + new parsed formatting is complete. + +0.10.2 (2015-05-19) +------------------- + +- Fixed APNIC parsing for updated field. +- Fixed datetime parsing and validation when Zulu (Z) is appended. +- Added RIPE parsing for created and updated fields (whois and RWS). +- Removed unnecessary parentheses in IPWhois class declaration. +- Some documentation and comment tweaking to work with Sphinx. +- Minor PEP 8 tweaks. + +0.10.1 (2015-02-09) +------------------- + +- Fixed setup.py bug. + +0.10.0 (2015-02-09) +------------------- + +- Added .csv support for country code source. You can no longer download + country code information from iso.org. +- Added support for IPv4Address or IPv6Address as the address arg in IPWhois. +- Fixed file open encoding bug. Moved from open to io.open. +- Fixed parameter in IPWhois ip defined checks. +- Fixed TestIPWhois.test_ip_invalid() assertions. + diff --git a/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/INSTALLER b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/METADATA b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/METADATA new file mode 100644 index 0000000..bdca066 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/METADATA @@ -0,0 +1,526 @@ +Metadata-Version: 2.0 +Name: ipwhois +Version: 1.0.0 +Summary: Retrieve and parse whois data for IPv4 and IPv6 addresses. +Home-page: https://github.com/secynic/ipwhois +Author: Philip Hane +Author-email: secynic@gmail.com +License: BSD +Download-URL: https://github.com/secynic/ipwhois/tarball/master +Keywords: Python WHOIS RWhois Referral Whois ASN IP Address IP IPv4 IPv6 IETF REST Arin Ripe Apnic Lacnic Afrinic NIC National Information Center RDAP RIR Regional Internet RegistryNIR National Internet Registry ASN origin Origin +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Intended Audience :: Information Technology +Classifier: Intended Audience :: Science/Research +Classifier: License :: OSI Approved :: BSD License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.6 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Topic :: Internet +Classifier: Topic :: Software Development +Requires-Dist: dnspython +Requires-Dist: ipaddr; python_version < "3.3" + +======= +ipwhois +======= + +.. image:: https://travis-ci.org/secynic/ipwhois.svg?branch=master + :target: https://travis-ci.org/secynic/ipwhois +.. image:: https://coveralls.io/repos/github/secynic/ipwhois/badge.svg?branch= + master + :target: https://coveralls.io/github/secynic/ipwhois?branch=master +.. image:: https://codeclimate.com/github/secynic/ipwhois/badges/issue_count.svg + :target: https://codeclimate.com/github/secynic/ipwhois +.. image:: https://img.shields.io/badge/license-BSD%202--Clause-blue.svg + :target: https://github.com/secynic/ipwhois/tree/master/LICENSE.txt +.. image:: https://img.shields.io/badge/python-2.6%2C%202.7%2C%203.3+-blue.svg + :target: https://docs.python.org +.. image:: https://img.shields.io/badge/docs-latest-green.svg?style=flat + :target: https://ipwhois.readthedocs.io/en/latest +.. image:: https://img.shields.io/badge/docs-dev-yellow.svg?style=flat + :target: https://ipwhois.readthedocs.io/en/dev + +Summary +======= + +ipwhois is a Python package focused on retrieving and parsing whois data +for IPv4 and IPv6 addresses. + +.. note:: + + If you are experiencing latency issues, it is likely related to rate + limiting. Rate limiting is based on your source IP, which may be a problem + with multiple users behind the same proxy. Additionally, LACNIC implements + aggressive rate limiting. Experimental bulk query support is new as of + v1.0.0. + +Features +======== + +* Parses a majority of whois fields in to a standard dictionary +* IPv4 and IPv6 support +* Supports RDAP queries (recommended method, see: + https://tools.ietf.org/html/rfc7483) +* Proxy support for RDAP queries +* Supports legacy whois protocol queries +* Referral whois support for legacy whois protocol +* Recursive network parsing for IPs with parent/children networks listed +* National Internet Registry support for JPNIC and KRNIC +* Supports IP to ASN and ASN origin queries +* Python 2.6+ and 3.3+ supported +* Useful set of utilities +* Experimental bulk query support +* BSD license +* 100% core code coverage (See '# pragma: no cover' for exclusions) +* Human readable field translations +* Full CLI for IPWhois with optional ANSI colored console output. + +Links +===== + +Documentation +------------- + +GitHub latest +^^^^^^^^^^^^^ + +https://ipwhois.readthedocs.io/en/latest + +GitHub dev +^^^^^^^^^^ + +https://ipwhois.readthedocs.io/en/dev + +Examples +-------- + +https://github.com/secynic/ipwhois/tree/master/ipwhois/examples + +Github +------ + +https://github.com/secynic/ipwhois + +Pypi +---- + +https://pypi.org/project/ipwhois + +Changes +------- + +https://ipwhois.readthedocs.io/en/latest/CHANGES.html + +Upgrade Notes +------------- + +https://ipwhois.readthedocs.io/en/latest/UPGRADING.html + +Dependencies +============ + +Python 2.6:: + + dnspython + ipaddr + argparse (required only for CLI) + +Python 2.7:: + + dnspython + ipaddr + +Python 3.3+:: + + dnspython + +Installing +========== + +Latest release from PyPi:: + + pip install --upgrade ipwhois + +GitHub - Stable:: + + pip install -e git+https://github.com/secynic/ipwhois@master#egg=ipwhois + +GitHub - Dev:: + + pip install -e git+https://github.com/secynic/ipwhois@dev#egg=ipwhois + +Firewall Ports +============== + +ipwhois needs some outbound firewall ports opened from your host/server. + +:ASN (DNS): 53/tcp +:ASN (Whois): 43/tcp +:ASN (HTTP): + 80/tcp + + 443/tcp (Pending) +:RDAP (HTTP): + 80/tcp + + 443/tcp (Pending) +:NIR (HTTP): + 80/tcp + + 443/tcp (KRNIC) +:Legacy Whois: 43/tcp +:Get Host: 43/tcp + +API +=== + +IPWhois (main class) +-------------------- + +ipwhois.IPWhois is the base class for wrapping RDAP and Legacy Whois lookups. +Instantiate this object, then call one of the lookup functions: + +`RDAP (HTTP) - IPWhois.lookup_rdap() <#rdap-http>`_ +OR +`Legacy Whois - IPWhois.lookup_whois() <#legacy-whois>`_ + +Input +^^^^^ + ++--------------------+--------+-----------------------------------------------+ +| **Key** |**Type**| **Description** | ++--------------------+--------+-----------------------------------------------+ +| address | str | An IPv4 or IPv6 address as a string, integer, | +| | | IPv4Address, or IPv6Address. | ++--------------------+--------+-----------------------------------------------+ +| timeout | int | The default timeout for socket connections | +| | | in seconds. Defaults to 5. | ++--------------------+--------+-----------------------------------------------+ +| proxy_opener | object | The urllib.request.OpenerDirector request for | +| | | proxy support or None. | ++--------------------+--------+-----------------------------------------------+ +| allow_permutations | bool | Allow net.Net() to use additional methods if | +| | | DNS lookups to Cymru fail. *WARNING* | +| | | deprecated in favor of new argument | +| | | asn_methods. Defaults to True. | ++--------------------+--------+-----------------------------------------------+ + +RDAP (HTTP) +----------- + +IPWhois.lookup_rdap() is the recommended lookup method. RDAP provides a +far better data structure than legacy whois and REST lookups (previous +implementation). RDAP queries allow for parsing of contact information and +details for users, organizations, and groups. RDAP also provides more detailed +network information. + +RDAP documentation: + +https://ipwhois.readthedocs.io/en/latest/RDAP.html + +Legacy Whois +------------ + +Legacy Whois documentation: + +https://ipwhois.readthedocs.io/en/latest/WHOIS.html + +National Internet Registries +---------------------------- + +This library now supports NIR lookups for JPNIC and KRNIC. Previously, Whois +and RDAP data for Japan and South Korea was restricted. NIR lookups scrape +these national registries directly for the data restricted from regional +internet registries. NIR queries are enabled by default via the inc_nir +argument in the IPWhois.lookup_*() functions. + +https://ipwhois.readthedocs.io/en/latest/NIR.html + +Autonomous System Numbers +------------------------- + +This library now supports ASN origin lookups via Whois and HTTP. + +IP ASN functionality was moved to its own parser API (IPASN). + +There is no CLI for these yet. + +https://ipwhois.readthedocs.io/en/latest/ASN.html + +Utilities +--------- + +Utilities documentation: + +https://ipwhois.readthedocs.io/en/latest/UTILS.html + +Scripts +------- + +CLI documentation: + +https://ipwhois.readthedocs.io/en/latest/CLI.html + +Experimental Functions +---------------------- + +.. caution:: + + Functions in experimental.py contain new functionality that has not yet + been widely tested. Bulk lookup support contained here can result in + significant system/network resource utilization. Additionally, abuse of + this functionality may get you banned by the various services queried by + this library. Use at your own discretion. + +Experimental functions documentation: + +https://ipwhois.readthedocs.io/en/latest/EXPERIMENTAL.html + +Contributing +============ + +https://ipwhois.readthedocs.io/en/latest/CONTRIBUTING.html + +IP Reputation Support +===================== + +This feature is under consideration. Take a look at TekDefense's Automater: + +`TekDefense-Automater `_ + +Domain Support +============== + +There are no plans for domain whois support in this project. + +Look at Sven Slootweg's +`python-whois `_ for a library with +domain support. + +Special Thanks +============== + +Thank you JetBrains for the `PyCharm `_ +open source support! + +Thank you Chris Wells (`@cdubz `_) for your +extensive testing on the experimental functions! + +Last but not least, thank you to all the issue submitters and contributors. + + +Changelog +========= + +1.0.0 (2017-07-30) +------------------ + +- Deprecated asn_alts, allow_permutations in favor of new asn_methods (#158) +- Added new exception ASNOriginLookupError (#158) +- KRNIC lookups changed to HTTPS (#166) +- Added experimental functions - get_bulk_asn_whois, bulk_lookup_rdap (#134) +- Fixed bug in NIR lookups that caused addresses with multi-line contacts to + error (#172 - kwheeles) +- Added IANA Reserved CIDR 198.97.38.0/24 to ipv4_is_defined (#174) +- Fixed bug in RDAP notices/remarks parsing that would omit partial entries + missing one or more of title, description, links (#176) +- Added new return key asn_description via verbose ASN DNS lookup support and + modified ASN whois lookups. New argument get_asn_description to disable + additional DNS lookup (#176) +- Fixed some test function naming errors +- Added new generators to utils.py: ipv4_generate_random and + ipv6_generate_random (#183) +- Moved upgrade notes to new UPGRADING.rst +- Deprecated unnecessary protected class functions, changed to public in + asn.py, nir.py, and whois.py (#184) +- net.Net.get_host(), utils.ipv4_is_defined(), and utils.ipv6_is_defined now + return namedtuple instead of tuple. +- Changed docstrings to Google standard for better napoleon parsing (#185) +- Removed deprecated IPWhois.lookup() - This was moved to + IPWhois.lookup_whois() +- Fixed 'nets'->'range' bug for legacy whois CIDR net_range values (#188) +- Fixed a bug in IPASN/Net that caused the ASN result to vary if Cymru has + more than one ASN listed for an IP (#190) +- Updated ElasticSearch example for ES v5.5.1 (#138) + +0.15.1 (2017-02-16) +------------------- + +- Fixed IPv6 parsing for ASN origin lookups and added tests (#162 - ti-mo) +- Fixed recursive role parsing at depths greater than 0 (#161 - cdubz) + +0.15.0 (2017-02-02) +------------------- + +- Python 3.3+ dnspython3 requirement changed to dnspython (#155) +- Added ASN origin lookup support (#149) +- Moved ASN parsing from net.Net.get_asn_*() to new class asn.IPASN. + The original functions now return the raw query (#157) +- net.Net.lookup_asn() is deprecated in favor of asn.IPASN.lookup() (#157) +- Added new exception ASNParseError (#157) +- Fixed rate-limiting exception handling for when HTTP errors are returned + rather than JSON errors (rikonor - #144) +- Fixed rate-limit infinite recursion bug for legacy whois (rikonor - #144) +- Fixed bug in net.Net.get_http_raw() that would pass the encoded form_data on + retry rather than the original argument. +- Removed nose requirements and fixed travis.yml for updated pip +- Documentation updates +- Code style tweaks +- Updated tests and version info for Python 3.6 +- Added basic stress tests (#144) +- Minor tweaks to existing tests + +0.14.0 (2016-08-29) +------------------- + +- Changed legacy whois emails output type to list (#133) +- Fixed retry count non-decrementing infinite loop in + ipwhois.net.Net.get_whois() (issue #125 - krader1961) +- Added new function ipwhois.net.Net.get_http_raw() and tests (#67) +- Added National Internet Registry (JPNIC, KRNIC) support (#67). Enabled by + default in IPWhois.lookup_*(). Disable by passing inc_nir=False. Optionally, + lower level code can call nir.NIRWhois(). This enhancement results in extra + network queries, but more detailed information for NIRs. +- Added utils CLI (ipwhois_utils_cli.py) - #121. Installed to your environments + Scripts dir. This is a wrapper for utils.py. +- Documentation improvements (#123) +- kw arg readability (#115) +- Replaced usage of args with script_args in ipwhois_cli.py +- Minor optimization in whois.py and online/test_whois.py +- Added coveralls integration and re-enabled online tests with Travis CI +- Added Read the Docs support (#132) +- Added documentation (Sphinx) requirements.txt (#132) +- Fixed test imports +- Added --json argument (output in JSON format) to ipwhois_cli.py (#135) + +0.13.0 (2016-04-18) +------------------- + +- Added events_actor parsing for RDAP results. +- Added example for caching data via Redis (#81) +- Added normalization (human-readable field information) in hr.py (#47) +- README word wrap fix (#102) +- Fixed bug in exception handling for ASN HTTP lookups. +- Fixed bug in IPWhois.lookup_rdap() that caused ASN HTTP lookup responses to + be used in place of RDAP responses. +- Added new function Net.get_asn_http() and migrated code from + Net.lookup_asn() + new tests. +- Fixed bug in ASN HTTP fallback lookups for DNIC (#108). +- Added new parameter extra_org_map in Net.get_asn_http(), Net.lookup_asn(), + and IPWhois.lookup*() (#108). +- Fixed _RDAPCommon.summarize_notices() None check - changed len() to all(). +- Added CLI (ipwhois_cli.py) - #46. Installed to your environments Scripts dir. + This is a wrapper for ipwhois.py (IPWhois). Utils CLI will be in a future + release (#121). +- Documentation split up and added more detail (#81). + +0.12.0 (2016-03-28) +------------------- + +- Added headers parameter to ipwhois.Net.get_http_json() (issue #98). +- Fixed ASN HTTP lookup (fallback) Accept headers (issue #98). +- Fixed HTTP decoding, set to utf-8 (italomaia - issue #97) +- IPWhois.lookup() deprecated (issue #96), and will be removed in a future + release (TBD). Use IPWhois.lookup_whois() instead. +- Added rate_limit_timeout parameter (issue #99) to Net.get_http_json(), + IPWhois.lookup_rdap(), and RDAP.lookup(). New exception HTTPRateLimitError. +- Added new parameter asn_alts to Net.lookup_asn(), IPWhois.lookup_rdap() and + IPWhois.lookup(). Takes a list of lookup types to attempt if the + ASN dns lookup fails. Allow permutations must be enabled. Defaults to all + ['whois', 'http'] (issue #93). +- Fixed socket exception handling in Net.get_http_json() for Python 2.6. +- Fixed assertIsInstance for Python 2.6 tests (issue #100). Implemented + unittest._formatMessage and unittest.util.safe_repr for Python 2.6. +- Moved TestCommon to tests\\__init__.py to avoid duplicate code. +- Replaced remaining % with str.format (issue #95). + +0.11.2 (2016-02-25) +------------------- + +- Added allow_permutations parameter (bool) to net.Net() and ipwhois.IPWhois() + to allow alternate ASN lookups if DNS lookups fail. (FirefighterBlu3) +- Fixed ASN DNS resolver timeout/retry_count support. Retry count is used as a + multiplier of timeout, to determine a limetime interval. (FirefighterBlu3) +- Fixed bug where remarks would return None if missing a title. +- Added CONTRIBUTING.rst +- Added tests + +0.11.1 (2015-12-17) +------------------- + +- Re-added CIDR calculation for RDAP lookups. +- Improved tests - core code coverage now 100%. See '# pragma: no cover' for + exclusions. A few bugs were identified in the process, detailed below. +- Moved IP zero stripping from rdap._RDAPNetwork.parse() to new helper function + utils.ipv4_lstrip_zeros(). +- Moved CIDR calculation from rdap._RDAPNetwork.parse() to new helper function + utils.calculate_cidr(). +- Fixed utils.ipv4_is_defined() if statement ordering for RFC 1918 conflict. +- Fixed utils.ipv6_is_defined() if statement ordering for Unspecified and + Loopback (conflict with Reserved). +- Added is_offline parameter to whois.Whois.lookup() primarily for testing. +- Fixed bug in whois.Whois._parse_fields() that attempted to parse 'val2' of + regex, which is no longer used. Also fixed the expected Exception to be + IndexError. +- Fixed bug in ipwhois.IPWhois.lookup() where the argument order was mixed up, + causing referral lookups to be skipped when get_referral=True. +- Fixed bug in rdap._RDAPCommon.summarize_notices() output for links. +- Fixed bug in root entity iteration exception handling in rdap.RDAP.lookup(). + +0.11.0 (2015-11-02) +------------------- + +- Support for REST lookups replaced with RDAP. +- Split code for a more structured system (net, whois, rdap, exceptions). +- Tests match the data new structure. +- Split tests for online and offline testing. +- Performance enhancements for parsing. +- Added an optional bootstrap parameter for RDAP lookups, in order to replace + ASN lookups or use both. Will default to False. Afrinic is currently not + supported, so I would not use this for now. ARIN acknowledged my issue + for this, and will be adding support back in for Afrinic bootstrap. +- Added field_list parameter (inclusion list) for WHOIS lookups. +- Added logging. +- Added examples directory. + +0.10.3 (2015-08-14) +------------------- + +- Fixed LACNIC lookup_rws() queries, since they switched to RDAP. This is + temporary to get it working until the major library transition to RDAP and + new parsed formatting is complete. + +0.10.2 (2015-05-19) +------------------- + +- Fixed APNIC parsing for updated field. +- Fixed datetime parsing and validation when Zulu (Z) is appended. +- Added RIPE parsing for created and updated fields (whois and RWS). +- Removed unnecessary parentheses in IPWhois class declaration. +- Some documentation and comment tweaking to work with Sphinx. +- Minor PEP 8 tweaks. + +0.10.1 (2015-02-09) +------------------- + +- Fixed setup.py bug. + +0.10.0 (2015-02-09) +------------------- + +- Added .csv support for country code source. You can no longer download + country code information from iso.org. +- Added support for IPv4Address or IPv6Address as the address arg in IPWhois. +- Fixed file open encoding bug. Moved from open to io.open. +- Fixed parameter in IPWhois ip defined checks. +- Fixed TestIPWhois.test_ip_invalid() assertions. + diff --git a/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/RECORD b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/RECORD new file mode 100644 index 0000000..5ef41e1 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/RECORD @@ -0,0 +1,35 @@ +../../../bin/__pycache__/ipwhois_cli.cpython-37.pyc,, +../../../bin/__pycache__/ipwhois_utils_cli.cpython-37.pyc,, +../../../bin/ipwhois_cli.py,sha256=a0lwRXpqOfLGfwh-nJz4DN6whYTuTsfMFCfEBHiHE-A,55038 +../../../bin/ipwhois_utils_cli.py,sha256=jslJNW3P7UTCICoXuYuQwT-54GUYmDVXQOWLthHmORI,8656 +ipwhois-1.0.0.dist-info/DESCRIPTION.rst,sha256=7o6HwNJv0917--N8hj5BvocWFjzJxUn4KO8g8fMQIjA,17221 +ipwhois-1.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +ipwhois-1.0.0.dist-info/METADATA,sha256=Pb9qUi-QPn0Gc-VxuLIjT07r9MAIXs_Z1aT0mw92G7I,18650 +ipwhois-1.0.0.dist-info/RECORD,, +ipwhois-1.0.0.dist-info/WHEEL,sha256=9Z5Xm-eel1bTS7e6ogYiKz0zmPEqDwIypurdHN1hR40,116 +ipwhois-1.0.0.dist-info/metadata.json,sha256=_KPnHen51YlAxxSUQBGdVU7qYwgIWonI0ghxm4R_GxU,1646 +ipwhois-1.0.0.dist-info/top_level.txt,sha256=Rk_3xKIClsg-roGROLi8TYR4zo_8K6grqAKvL_O9ad8,8 +ipwhois/__init__.py,sha256=jPf4qFf_oefS_IXNaBi-Sv4heAscRtzj2rspLTuMAKI,1473 +ipwhois/__pycache__/__init__.cpython-37.pyc,, +ipwhois/__pycache__/asn.cpython-37.pyc,, +ipwhois/__pycache__/exceptions.cpython-37.pyc,, +ipwhois/__pycache__/experimental.cpython-37.pyc,, +ipwhois/__pycache__/hr.cpython-37.pyc,, +ipwhois/__pycache__/ipwhois.cpython-37.pyc,, +ipwhois/__pycache__/net.cpython-37.pyc,, +ipwhois/__pycache__/nir.cpython-37.pyc,, +ipwhois/__pycache__/rdap.cpython-37.pyc,, +ipwhois/__pycache__/utils.cpython-37.pyc,, +ipwhois/__pycache__/whois.cpython-37.pyc,, +ipwhois/asn.py,sha256=-3O72RFaBEaqZEdS4raoKM9n08I2sfogP5_oVcnSLhw,32339 +ipwhois/data/iso_3166-1.csv,sha256=O_whGbkO5HNp_ziuV91LhRLG6tSr8QYppzjagx-i1kE,4264 +ipwhois/data/iso_3166-1_list_en.xml,sha256=eLlDUEmUp8rRSIfL-7lxy2PmNsMyH53ot972MtIH0Ss,48718 +ipwhois/exceptions.py,sha256=VyF7DIBWov81iapkkQMRVWuSq86u_Fvo_1SPR0wh5MA,3528 +ipwhois/experimental.py,sha256=iEvv8DeTwM8Nrk12ud1ZSUsHoz_5LZ0kMKTTdyWot0g,18218 +ipwhois/hr.py,sha256=lGV1CTcjB0SLALJQxC6cvZh1fRzIChUx3S8wDbZ5LRs,18692 +ipwhois/ipwhois.py,sha256=sAARLxVJ1eS2DdH295Y17v0tbh2XM25rofpkQbYUvy0,16403 +ipwhois/net.py,sha256=PMNDaLeEemO8SV573rg_OYqvpCK1SKkfFEHG1KqZPLM,33339 +ipwhois/nir.py,sha256=UTLmksBP0ofiwYBKdDvYVKOK10DBug4YwfIrggH23sc,23819 +ipwhois/rdap.py,sha256=MD8-6gFqiiKjpvUnsK4lOBcwRAowu7fMf_jL2nxGE3U,25179 +ipwhois/utils.py,sha256=qY9NzqSClrg9Pc12TlyR63Le6OIV_rLlGMD8hwKGkzI,19201 +ipwhois/whois.py,sha256=kQibhvHbforGDOk83GUpLHI5nz3_INXoYZHutXuJ-7k,27642 diff --git a/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/WHEEL b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/WHEEL new file mode 100644 index 0000000..ab4a09e --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.29.0) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/metadata.json b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/metadata.json new file mode 100644 index 0000000..9f77592 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/metadata.json @@ -0,0 +1 @@ +{"classifiers": ["Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Intended Audience :: Information Technology", "Intended Audience :: Science/Research", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Internet", "Topic :: Software Development"], "download_url": "https://github.com/secynic/ipwhois/tarball/master", "extensions": {"python.details": {"contacts": [{"email": "secynic@gmail.com", "name": "Philip Hane", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/secynic/ipwhois"}}}, "extras": [], "generator": "bdist_wheel (0.29.0)", "keywords": ["Python", "WHOIS", "RWhois", "Referral", "Whois", "ASN", "IP", "Address", "IP", "IPv4", "IPv6", "IETF", "REST", "Arin", "Ripe", "Apnic", "Lacnic", "Afrinic", "NIC", "National", "Information", "Center", "RDAP", "RIR", "Regional", "Internet", "RegistryNIR", "National", "Internet", "Registry", "ASN", "origin", "Origin"], "license": "BSD", "metadata_version": "2.0", "name": "ipwhois", "run_requires": [{"requires": ["dnspython"]}, {"environment": "python_version < \"3.3\"", "requires": ["ipaddr"]}], "summary": "Retrieve and parse whois data for IPv4 and IPv6 addresses.", "version": "1.0.0"} \ No newline at end of file diff --git a/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/top_level.txt b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/top_level.txt new file mode 100644 index 0000000..f2590b2 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois-1.0.0.dist-info/top_level.txt @@ -0,0 +1 @@ +ipwhois diff --git a/env/lib/python3.7/site-packages/ipwhois/__init__.py b/env/lib/python3.7/site-packages/ipwhois/__init__.py new file mode 100644 index 0000000..e9103f8 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/__init__.py @@ -0,0 +1,29 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from .exceptions import * +from .net import Net +from .ipwhois import IPWhois + +__version__ = '1.0.0' diff --git a/env/lib/python3.7/site-packages/ipwhois/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/ipwhois/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a547e950d077ad0d0e54327371a2c91583e0e6f0 GIT binary patch literal 263 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/ipwhois/__pycache__/exceptions.cpython-37.pyc b/env/lib/python3.7/site-packages/ipwhois/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a16e9161f5622ff89dea0b1a2cc4d760db280f8 GIT binary patch literal 3781 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 M0dmW)(xLqS0Ho}cZU6uP literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/ipwhois/__pycache__/hr.cpython-37.pyc b/env/lib/python3.7/site-packages/ipwhois/__pycache__/hr.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43ea5afea3c01eeccc6f952f85efe0950935c429 GIT binary patch literal 7387 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 WJMnbhCBp%6-F1M&>sGVes{9Xg8*Qop literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/ipwhois/__pycache__/net.cpython-37.pyc b/env/lib/python3.7/site-packages/ipwhois/__pycache__/net.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2e34614126761dfde5c1e831451ffdbe0e635414 GIT binary patch literal 19747 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 sr6;u>F-VIEQu}cfPMj>{xjzP1g?Lnd;kCd literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/ipwhois/__pycache__/nir.cpython-37.pyc b/env/lib/python3.7/site-packages/ipwhois/__pycache__/nir.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..590dfbbb2c3be15b93630108a6e2564613f5c8b1 GIT binary patch literal 14963 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/ipwhois/__pycache__/rdap.cpython-37.pyc b/env/lib/python3.7/site-packages/ipwhois/__pycache__/rdap.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..189bc4fc0ce3d51042454b17fff382ba2fd050e8 GIT binary patch literal 17420 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 Dz`n&y literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/ipwhois/__pycache__/utils.cpython-37.pyc b/env/lib/python3.7/site-packages/ipwhois/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3371b481e678c2f862d223e88a49316fb1a60282 GIT binary patch literal 12535 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/ipwhois/__pycache__/whois.cpython-37.pyc b/env/lib/python3.7/site-packages/ipwhois/__pycache__/whois.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..02387373b4bc59d6902e2f8924410f15fe21c4de GIT binary patch literal 16922 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 (3, 3): # pragma: no cover + from ipaddress import ip_network + +else: # pragma: no cover + from ipaddr import IPNetwork as ip_network + +log = logging.getLogger(__name__) + +BASE_NET = { + 'cidr': None, + 'description': None, + 'maintainer': None, + 'updated': None, + 'source': None +} + +ASN_ORIGIN_WHOIS = { + 'radb': { + 'server': 'whois.radb.net', + 'fields': { + 'description': r'(descr):[^\S\n]+(?P.+?)\n', + 'maintainer': r'(mnt-by):[^\S\n]+(?P.+?)\n', + 'updated': r'(changed):[^\S\n]+(?P.+?)\n', + 'source': r'(source):[^\S\n]+(?P.+?)\n', + } + }, +} + +ASN_ORIGIN_HTTP = { + 'radb': { + 'url': 'http://www.radb.net/query/', + 'form_data_asn_field': 'keywords', + 'form_data': { + 'advanced_query': '1', + 'query': 'Query', + '-T option': 'inet-rtr', + 'ip_option': '', + '-i': '1', + '-i option': 'origin' + }, + 'fields': { + 'description': r'(descr):[^\S\n]+(?P.+?)\', + 'maintainer': r'(mnt-by):[^\S\n]+(?P.+?)\', + 'updated': r'(changed):[^\S\n]+(?P.+?)\', + 'source': r'(source):[^\S\n]+(?P.+?)\', + } + }, +} + + +class IPASN: + """ + The class for parsing ASN data for an IP address. + + Args: + net (:obj:`ipwhois.net.Net`): A ipwhois.net.Net object. + + Raises: + NetError: The parameter provided is not an instance of + ipwhois.net.Net + """ + + def __init__(self, net): + + from .net import (Net, ORG_MAP) + from .whois import RIR_WHOIS + + # ipwhois.net.Net validation + if isinstance(net, Net): + + self._net = net + + else: + + raise NetError('The provided net parameter is not an instance of ' + 'ipwhois.net.Net') + + self.org_map = ORG_MAP + self.rir_whois = RIR_WHOIS + + def parse_fields_dns(self, response): + """ + The function for parsing ASN fields from a dns response. + + Args: + response (:obj:`str`): The response from the ASN dns server. + + Returns: + dict: The ASN lookup results + + :: + + { + 'asn' (str) - The Autonomous System Number + 'asn_date' (str) - The ASN Allocation date + 'asn_registry' (str) - The assigned ASN registry + 'asn_cidr' (str) - The assigned ASN CIDR + 'asn_country_code' (str) - The assigned ASN country code + 'asn_description' (None) - Cannot retrieve with this + method. + } + + Raises: + ASNRegistryError: The ASN registry is not known. + ASNParseError: ASN parsing failed. + """ + + try: + + temp = response.split('|') + + # Parse out the ASN information. + ret = {'asn_registry': temp[3].strip(' \n')} + + if ret['asn_registry'] not in self.rir_whois.keys(): + + raise ASNRegistryError( + 'ASN registry {0} is not known.'.format( + ret['asn_registry']) + ) + + ret['asn'] = temp[0].strip(' "\n') + ret['asn_cidr'] = temp[1].strip(' \n') + ret['asn_country_code'] = temp[2].strip(' \n').upper() + ret['asn_date'] = temp[4].strip(' "\n') + ret['asn_description'] = None + + except ASNRegistryError: + + raise + + except Exception as e: + + raise ASNParseError('Parsing failed for "{0}" with exception: {1}.' + ''.format(response, e)[:100]) + + return ret + + def _parse_fields_dns(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('IPASN._parse_fields_dns() has been deprecated and will be ' + 'removed. You should now use IPASN.parse_fields_dns().') + return self.parse_fields_dns(*args, **kwargs) + + def parse_fields_verbose_dns(self, response): + """ + The function for parsing ASN fields from a verbose dns response. + + Args: + response (:obj:`str`): The response from the ASN dns server. + + Returns: + dict: The ASN lookup results + + :: + + { + 'asn' (str) - The Autonomous System Number + 'asn_date' (str) - The ASN Allocation date + 'asn_registry' (str) - The assigned ASN registry + 'asn_cidr' (None) - Cannot retrieve with this method. + 'asn_country_code' (str) - The assigned ASN country code + 'asn_description' (str) - The ASN description + } + + Raises: + ASNRegistryError: The ASN registry is not known. + ASNParseError: ASN parsing failed. + """ + + try: + + temp = response.split('|') + + # Parse out the ASN information. + ret = {'asn_registry': temp[2].strip(' \n')} + + if ret['asn_registry'] not in self.rir_whois.keys(): + + raise ASNRegistryError( + 'ASN registry {0} is not known.'.format( + ret['asn_registry']) + ) + + ret['asn'] = temp[0].strip(' "\n') + ret['asn_cidr'] = None + ret['asn_country_code'] = temp[1].strip(' \n').upper() + ret['asn_date'] = temp[3].strip(' \n') + ret['asn_description'] = temp[4].strip(' "\n') + + except ASNRegistryError: + + raise + + except Exception as e: + + raise ASNParseError('Parsing failed for "{0}" with exception: {1}.' + ''.format(response, e)[:100]) + + return ret + + def parse_fields_whois(self, response): + """ + The function for parsing ASN fields from a whois response. + + Args: + response (:obj:`str`): The response from the ASN whois server. + + Returns: + dict: The ASN lookup results + + :: + + { + 'asn' (str) - The Autonomous System Number + 'asn_date' (str) - The ASN Allocation date + 'asn_registry' (str) - The assigned ASN registry + 'asn_cidr' (str) - The assigned ASN CIDR + 'asn_country_code' (str) - The assigned ASN country code + 'asn_description' (str) - The ASN description + } + + Raises: + ASNRegistryError: The ASN registry is not known. + ASNParseError: ASN parsing failed. + """ + + try: + + temp = response.split('|') + + # Parse out the ASN information. + ret = {'asn_registry': temp[4].strip(' \n')} + + if ret['asn_registry'] not in self.rir_whois.keys(): + + raise ASNRegistryError( + 'ASN registry {0} is not known.'.format( + ret['asn_registry']) + ) + + ret['asn'] = temp[0].strip(' \n') + ret['asn_cidr'] = temp[2].strip(' \n') + ret['asn_country_code'] = temp[3].strip(' \n').upper() + ret['asn_date'] = temp[5].strip(' \n') + ret['asn_description'] = temp[6].strip(' \n') + + except ASNRegistryError: + + raise + + except Exception as e: + + raise ASNParseError('Parsing failed for "{0}" with exception: {1}.' + ''.format(response, e)[:100]) + + return ret + + def _parse_fields_whois(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('IPASN._parse_fields_whois() has been deprecated and will be ' + 'removed. You should now use IPASN.parse_fields_whois().') + return self.parse_fields_whois(*args, **kwargs) + + def parse_fields_http(self, response, extra_org_map=None): + """ + The function for parsing ASN fields from a http response. + + Args: + response (:obj:`str`): The response from the ASN http server. + extra_org_map (:obj:`dict`): Dictionary mapping org handles to + RIRs. This is for limited cases where ARIN REST (ASN fallback + HTTP lookup) does not show an RIR as the org handle e.g., DNIC + (which is now the built in ORG_MAP) e.g., {'DNIC': 'arin'}. + Valid RIR values are (note the case-sensitive - this is meant + to match the REST result): 'ARIN', 'RIPE', 'apnic', 'lacnic', + 'afrinic'. Defaults to None. + + Returns: + dict: The ASN lookup results + + :: + + { + 'asn' (None) - Cannot retrieve with this method. + 'asn_date' (None) - Cannot retrieve with this method. + 'asn_registry' (str) - The assigned ASN registry + 'asn_cidr' (None) - Cannot retrieve with this method. + 'asn_country_code' (None) - Cannot retrieve with this + method. + 'asn_description' (None) - Cannot retrieve with this + method. + } + + Raises: + ASNRegistryError: The ASN registry is not known. + ASNParseError: ASN parsing failed. + """ + + # Set the org_map. Map the orgRef handle to an RIR. + org_map = self.org_map.copy() + try: + + org_map.update(extra_org_map) + + except (TypeError, ValueError, IndexError, KeyError): + + pass + + try: + + asn_data = { + 'asn_registry': None, + 'asn': None, + 'asn_cidr': None, + 'asn_country_code': None, + 'asn_date': None, + 'asn_description': None + } + + try: + + net_list = response['nets']['net'] + + if not isinstance(net_list, list): + net_list = [net_list] + + except (KeyError, TypeError): + + log.debug('No networks found') + net_list = [] + + for n in net_list: + + try: + + asn_data['asn_registry'] = ( + org_map[n['orgRef']['@handle'].upper()] + ) + + except KeyError as e: + + log.debug('Could not parse ASN registry via HTTP: ' + '{0}'.format(str(e))) + raise ASNRegistryError('ASN registry lookup failed.') + + break + + except ASNRegistryError: + + raise + + except Exception as e: # pragma: no cover + + raise ASNParseError('Parsing failed for "{0}" with exception: {1}.' + ''.format(response, e)[:100]) + + return asn_data + + def _parse_fields_http(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('IPASN._parse_fields_http() has been deprecated and will be ' + 'removed. You should now use IPASN.parse_fields_http().') + return self.parse_fields_http(*args, **kwargs) + + def lookup(self, inc_raw=False, retry_count=3, asn_alts=None, + extra_org_map=None, asn_methods=None, + get_asn_description=True): + """ + The wrapper function for retrieving and parsing ASN information for an + IP address. + + Args: + inc_raw (:obj:`bool`): Whether to include the raw results in the + returned dictionary. Defaults to False. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + asn_alts (:obj:`list`): Additional lookup types to attempt if the + ASN dns lookup fails. Allow permutations must be enabled. + Defaults to all ['whois', 'http']. *WARNING* deprecated in + favor of new argument asn_methods. Defaults to None. + extra_org_map (:obj:`dict`): Mapping org handles to RIRs. This is + for limited cases where ARIN REST (ASN fallback HTTP lookup) + does not show an RIR as the org handle e.g., DNIC (which is + now the built in ORG_MAP) e.g., {'DNIC': 'arin'}. Valid RIR + values are (note the case-sensitive - this is meant to match + the REST result): 'ARIN', 'RIPE', 'apnic', 'lacnic', 'afrinic' + Defaults to None. + asn_methods (:obj:`list`): ASN lookup types to attempt, in order. + If None, defaults to all: ['dns', 'whois', 'http']. + get_asn_description (:obj:`bool`): Whether to run an additional + query when pulling ASN information via dns, in order to get + the ASN description. Defaults to True. + + Returns: + dict: The ASN lookup results + + :: + + { + 'asn' (str) - The Autonomous System Number + 'asn_date' (str) - The ASN Allocation date + 'asn_registry' (str) - The assigned ASN registry + 'asn_cidr' (str) - The assigned ASN CIDR + 'asn_country_code' (str) - The assigned ASN country code + 'asn_description' (str) - The ASN description + 'raw' (str) - Raw ASN results if the inc_raw parameter is + True. + } + + Raises: + ValueError: methods argument requires one of dns, whois, http. + ASNRegistryError: ASN registry does not match. + """ + + if asn_methods is None: + + if asn_alts is None: + + lookups = ['dns', 'whois', 'http'] + + else: + + from warnings import warn + warn('IPASN.lookup() asn_alts argument has been deprecated ' + 'and will be removed. You should now use the asn_methods ' + 'argument.') + lookups = ['dns'] + asn_alts + + else: + + # Python 2.6 doesn't support set literal expressions, use explicit + # set() instead. + if set(['dns', 'whois', 'http']).isdisjoint(asn_methods): + + raise ValueError('methods argument requires at least one of ' + 'dns, whois, http.') + + lookups = asn_methods + + response = None + asn_data = None + dns_success = False + for index, lookup_method in enumerate(lookups): + + if index > 0 and not asn_methods and not ( + self._net.allow_permutations): + + raise ASNRegistryError('ASN registry lookup failed. ' + 'Permutations not allowed.') + + if lookup_method == 'dns': + + try: + + self._net.dns_resolver.lifetime = ( + self._net.dns_resolver.timeout * ( + retry_count and retry_count or 1 + ) + ) + response = self._net.get_asn_dns() + asn_data_list = [] + for asn_entry in response: + + asn_data_list.append(self._parse_fields_dns( + str(asn_entry))) + + # Iterate through the parsed ASN results to find the + # smallest CIDR + asn_data = asn_data_list.pop(0) + try: + + prefix_len = ip_network(asn_data['asn_cidr']).prefixlen + for asn_parsed in asn_data_list: + prefix_len_comp = ip_network( + asn_parsed['asn_cidr']).prefixlen + if prefix_len_comp > prefix_len: + asn_data = asn_parsed + prefix_len = prefix_len_comp + + except (KeyError, ValueError): # pragma: no cover + + pass + + dns_success = True + break + + except (ASNLookupError, ASNRegistryError) as e: + + log.debug('ASN DNS lookup failed: {0}'.format(e)) + pass + + elif lookup_method == 'whois': + + try: + + response = self._net.get_asn_whois(retry_count) + asn_data = self._parse_fields_whois( + response) # pragma: no cover + break + + except (ASNLookupError, ASNRegistryError) as e: + + log.debug('ASN WHOIS lookup failed: {0}'.format(e)) + pass + + elif lookup_method == 'http': + + try: + + response = self._net.get_asn_http( + retry_count=retry_count + ) + asn_data = self._parse_fields_http(response, + extra_org_map) + break + + except (ASNLookupError, ASNRegistryError) as e: + + log.debug('ASN HTTP lookup failed: {0}'.format(e)) + pass + + if asn_data is None: + + raise ASNRegistryError('ASN lookup failed with no more methods to ' + 'try.') + + if get_asn_description and dns_success: + + try: + + response = self._net.get_asn_verbose_dns('AS{0}'.format( + asn_data['asn'])) + asn_verbose_data = self.parse_fields_verbose_dns(response) + asn_data['asn_description'] = asn_verbose_data[ + 'asn_description'] + + except (ASNLookupError, ASNRegistryError) as e: # pragma: no cover + + log.debug('ASN DNS verbose lookup failed: {0}'.format(e)) + pass + + if inc_raw: + + asn_data['raw'] = response + + return asn_data + + +class ASNOrigin: + """ + The class for parsing ASN origin whois data + + Args: + net (:obj:`ipwhois.net.Net`): A ipwhois.net.Net object. + + Raises: + NetError: The parameter provided is not an instance of + ipwhois.net.Net + """ + + def __init__(self, net): + + from .net import Net + + # ipwhois.net.Net validation + if isinstance(net, Net): + + self._net = net + + else: + + raise NetError('The provided net parameter is not an instance of ' + 'ipwhois.net.Net') + + def parse_fields(self, response, fields_dict, net_start=None, + net_end=None, field_list=None): + """ + The function for parsing ASN whois fields from a data input. + + Args: + response (:obj:`str`): The response from the whois/rwhois server. + fields_dict (:obj:`dict`): Mapping of fields->regex search values. + net_start (:obj:`int`): The starting point of the network (if + parsing multiple networks). Defaults to None. + net_end (:obj:`int`): The ending point of the network (if parsing + multiple networks). Defaults to None. + field_list (:obj:`list`): If provided, a list of fields to parse: + ['description', 'maintainer', 'updated', 'source'] + If None, defaults to all fields. + + Returns: + dict: A dictionary of fields provided in fields_dict. + """ + + ret = {} + + if not field_list: + + field_list = ['description', 'maintainer', 'updated', 'source'] + + generate = ((field, pattern) for (field, pattern) in + fields_dict.items() if field in field_list) + + for field, pattern in generate: + + pattern = re.compile( + str(pattern), + re.DOTALL + ) + + if net_start is not None: + + match = pattern.finditer(response, net_end, net_start) + + elif net_end is not None: + + match = pattern.finditer(response, net_end) + + else: + + match = pattern.finditer(response) + + values = [] + sub_section_end = None + for m in match: + + if sub_section_end: + + if sub_section_end != (m.start() - 1): + break + + try: + + values.append(m.group('val').strip()) + + except IndexError: # pragma: no cover + + pass + + sub_section_end = m.end() + + if len(values) > 0: + + value = None + try: + + value = values[0] + + except ValueError as e: # pragma: no cover + + log.debug('ASN origin Whois field parsing failed for {0}: ' + '{1}'.format(field, e)) + pass + + ret[field] = value + + return ret + + def _parse_fields(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('ASNOrigin._parse_fields() has been deprecated and will be ' + 'removed. You should now use ASNOrigin.parse_fields().') + return self.parse_fields(*args, **kwargs) + + def get_nets_radb(self, response, is_http=False): + """ + The function for parsing network blocks from ASN origin data. + + Args: + response (:obj:`str`): The response from the RADB whois/http + server. + is_http (:obj:`bool`): If the query is RADB HTTP instead of whois, + set to True. Defaults to False. + + Returns: + list: A list of network block dictionaries + + :: + + [{ + 'cidr' (str) - The assigned CIDR + 'start' (int) - The index for the start of the parsed + network block + 'end' (int) - The index for the end of the parsed network + block + }] + """ + + nets = [] + + if is_http: + regex = r'route(?:6)?:[^\S\n]+(?P.+?)
    ' + else: + regex = r'^route(?:6)?:[^\S\n]+(?P.+|.+)$' + + # Iterate through all of the networks found, storing the CIDR value + # and the start and end positions. + for match in re.finditer( + regex, + response, + re.MULTILINE + ): + + try: + + net = copy.deepcopy(BASE_NET) + net['cidr'] = match.group(1).strip() + net['start'] = match.start() + net['end'] = match.end() + nets.append(net) + + except ValueError: # pragma: no cover + + pass + + return nets + + def _get_nets_radb(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('ASNOrigin._get_nets_radb() has been deprecated and will be ' + 'removed. You should now use ASNOrigin.get_nets_radb().') + return self.get_nets_radb(*args, **kwargs) + + def lookup(self, asn=None, inc_raw=False, retry_count=3, response=None, + field_list=None, asn_alts=None, asn_methods=None): + """ + The function for retrieving and parsing ASN origin whois information + via port 43/tcp (WHOIS). + + Args: + asn (:obj:`str`): The ASN (required). + inc_raw (:obj:`bool`): Whether to include the raw results in the + returned dictionary. Defaults to False. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + response (:obj:`str`): Optional response object, this bypasses the + Whois lookup. Defaults to None. + field_list (:obj:`list`): If provided, fields to parse: + ['description', 'maintainer', 'updated', 'source'] + If None, defaults to all. + asn_alts (:obj:`list`): Additional lookup types to attempt if the + ASN whois lookup fails. If None, defaults to all ['http']. + *WARNING* deprecated in favor of new argument asn_methods. + asn_methods (:obj:`list`): ASN lookup types to attempt, in order. + If None, defaults to all ['whois', 'http']. + + Returns: + dict: The ASN origin lookup results + + :: + + { + 'query' (str) - The Autonomous System Number + 'nets' (list) - Dictionaries containing network + information which consists of the fields listed in the + ASN_ORIGIN_WHOIS dictionary. + 'raw' (str) - Raw ASN origin whois results if the inc_raw + parameter is True. + } + + Raises: + ValueError: methods argument requires one of whois, http. + ASNOriginLookupError: ASN origin lookup failed. + """ + + if asn[0:2] != 'AS': + + asn = 'AS{0}'.format(asn) + + if asn_methods is None: + + if asn_alts is None: + + lookups = ['whois', 'http'] + + else: + + from warnings import warn + warn('ASNOrigin.lookup() asn_alts argument has been deprecated' + ' and will be removed. You should now use the asn_methods' + ' argument.') + lookups = ['whois'] + asn_alts + + else: + + # Python 2.6 doesn't support set literal expressions, use explicit + # set() instead. + if set(['whois', 'http']).isdisjoint(asn_methods): + + raise ValueError('methods argument requires at least one of ' + 'whois, http.') + + lookups = asn_methods + + # Create the return dictionary. + results = { + 'query': asn, + 'nets': [], + 'raw': None + } + + is_http = False + + # Only fetch the response if we haven't already. + if response is None: + + for index, lookup_method in enumerate(lookups): + + if lookup_method == 'whois': + + try: + + log.debug('Response not given, perform ASN origin ' + 'WHOIS lookup for {0}'.format(asn)) + + # Retrieve the whois data. + response = self._net.get_asn_origin_whois( + asn=asn, retry_count=retry_count + ) + + except (WhoisLookupError, WhoisRateLimitError) as e: + + log.debug('ASN origin WHOIS lookup failed: {0}' + ''.format(e)) + pass + + elif lookup_method == 'http': + + try: + + log.debug('Response not given, perform ASN origin ' + 'HTTP lookup for: {0}'.format(asn)) + + tmp = ASN_ORIGIN_HTTP['radb']['form_data'] + tmp[str(ASN_ORIGIN_HTTP['radb']['form_data_asn_field'] + )] = asn + response = self._net.get_http_raw( + url=ASN_ORIGIN_HTTP['radb']['url'], + retry_count=retry_count, + request_type='POST', + form_data=tmp + ) + is_http = True # pragma: no cover + + except HTTPLookupError as e: + + log.debug('ASN origin HTTP lookup failed: {0}' + ''.format(e)) + pass + + if response is None: + + raise ASNOriginLookupError('ASN origin lookup failed with no ' + 'more methods to try.') + + # If inc_raw parameter is True, add the response to return dictionary. + if inc_raw: + + results['raw'] = response + + nets = [] + nets_response = self._get_nets_radb(response, is_http) + + nets.extend(nets_response) + + if is_http: # pragma: no cover + fields = ASN_ORIGIN_HTTP + else: + fields = ASN_ORIGIN_WHOIS + + # Iterate through all of the network sections and parse out the + # appropriate fields for each. + log.debug('Parsing ASN origin data') + + for index, net in enumerate(nets): + + section_end = None + if index + 1 < len(nets): + + section_end = nets[index + 1]['start'] + + temp_net = self._parse_fields( + response, + fields['radb']['fields'], + section_end, + net['end'], + field_list + ) + + # Merge the net dictionaries. + net.update(temp_net) + + # The start and end values are no longer needed. + del net['start'], net['end'] + + # Add the networks to the return dictionary. + results['nets'] = nets + + return results diff --git a/env/lib/python3.7/site-packages/ipwhois/data/iso_3166-1.csv b/env/lib/python3.7/site-packages/ipwhois/data/iso_3166-1.csv new file mode 100644 index 0000000..d9ba3ff --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/data/iso_3166-1.csv @@ -0,0 +1,252 @@ +AD,Andorra, +AE,United Arab Emirates, +AF,Afghanistan, +AG,Antigua and Barbuda, +AI,Anguilla, +AL,Albania, +AM,Armenia, +AN,Netherlands Antilles, +AO,Angola, +AP,"Asia/Pacific Region", +AQ,Antarctica, +AR,Argentina, +AS,American Samoa, +AT,Austria, +AU,Australia, +AW,Aruba, +AX,Aland Islands, +AZ,Azerbaijan, +BA,Bosnia and Herzegovina, +BB,Barbados, +BD,Bangladesh, +BE,Belgium, +BF,Burkina Faso, +BG,Bulgaria, +BH,Bahrain, +BI,Burundi, +BJ,Benin, +BL,Saint Bartelemey, +BM,Bermuda, +BN,Brunei Darussalam, +BO,Bolivia, +BQ,"Bonaire, Saint Eustatius and Saba", +BR,Brazil, +BS,Bahamas, +BT,Bhutan, +BV,Bouvet Island, +BW,Botswana, +BY,Belarus, +BZ,Belize, +CA,Canada, +CC,Cocos (Keeling) Islands, +CD,"Congo, The Democratic Republic of the", +CF,Central African Republic, +CG,Congo, +CH,Switzerland, +CI,Cote d'Ivoire, +CK,Cook Islands, +CL,Chile, +CM,Cameroon, +CN,China, +CO,Colombia, +CR,Costa Rica, +CU,Cuba, +CV,Cape Verde, +CW,Curacao, +CX,Christmas Island, +CY,Cyprus, +CZ,Czech Republic, +DE,Germany, +DJ,Djibouti, +DK,Denmark, +DM,Dominica, +DO,Dominican Republic, +DZ,Algeria, +EC,Ecuador, +EE,Estonia, +EG,Egypt, +EH,Western Sahara, +ER,Eritrea, +ES,Spain, +ET,Ethiopia, +EU,Europe, +FI,Finland, +FJ,Fiji, +FK,Falkland Islands (Malvinas), +FM,"Micronesia, Federated States of", +FO,Faroe Islands, +FR,France, +GA,Gabon, +GB,United Kingdom, +GD,Grenada, +GE,Georgia, +GF,French Guiana, +GG,Guernsey, +GH,Ghana, +GI,Gibraltar, +GL,Greenland, +GM,Gambia, +GN,Guinea, +GP,Guadeloupe, +GQ,Equatorial Guinea, +GR,Greece, +GS,South Georgia and the South Sandwich Islands, +GT,Guatemala, +GU,Guam, +GW,Guinea-Bissau, +GY,Guyana, +HK,Hong Kong, +HM,Heard Island and McDonald Islands, +HN,Honduras, +HR,Croatia, +HT,Haiti, +HU,Hungary, +ID,Indonesia, +IE,Ireland, +IL,Israel, +IM,Isle of Man, +IN,India, +IO,British Indian Ocean Territory, +IQ,Iraq, +IR,"Iran, Islamic Republic of", +IS,Iceland, +IT,Italy, +JE,Jersey, +JM,Jamaica, +JO,Jordan, +JP,Japan, +KE,Kenya, +KG,Kyrgyzstan, +KH,Cambodia, +KI,Kiribati, +KM,Comoros, +KN,Saint Kitts and Nevis, +KP,"Korea, Democratic People's Republic of", +KR,"Korea, Republic of", +KW,Kuwait, +KY,Cayman Islands, +KZ,Kazakhstan, +LA,Lao People's Democratic Republic, +LB,Lebanon, +LC,Saint Lucia, +LI,Liechtenstein, +LK,Sri Lanka, +LR,Liberia, +LS,Lesotho, +LT,Lithuania, +LU,Luxembourg, +LV,Latvia, +LY,Libyan Arab Jamahiriya, +MA,Morocco, +MC,Monaco, +MD,"Moldova, Republic of", +ME,Montenegro, +MF,Saint Martin, +MG,Madagascar, +MH,Marshall Islands, +MK,Macedonia, +ML,Mali, +MM,Myanmar, +MN,Mongolia, +MO,Macao, +MP,Northern Mariana Islands, +MQ,Martinique, +MR,Mauritania, +MS,Montserrat, +MT,Malta, +MU,Mauritius, +MV,Maldives, +MW,Malawi, +MX,Mexico, +MY,Malaysia, +MZ,Mozambique, +NA,Namibia, +NC,New Caledonia, +NE,Niger, +NF,Norfolk Island, +NG,Nigeria, +NI,Nicaragua, +NL,Netherlands, +NO,Norway, +NP,Nepal, +NR,Nauru, +NU,Niue, +NZ,New Zealand, +OM,Oman, +PA,Panama, +PE,Peru, +PF,French Polynesia, +PG,Papua New Guinea, +PH,Philippines, +PK,Pakistan, +PL,Poland, +PM,Saint Pierre and Miquelon, +PN,Pitcairn, +PR,Puerto Rico, +PS,Palestinian Territory, +PT,Portugal, +PW,Palau, +PY,Paraguay, +QA,Qatar, +RE,Reunion, +RO,Romania, +RS,Serbia, +RU,Russian Federation, +RW,Rwanda, +SA,Saudi Arabia, +SB,Solomon Islands, +SC,Seychelles, +SD,Sudan, +SE,Sweden, +SG,Singapore, +SH,Saint Helena, +SI,Slovenia, +SJ,Svalbard and Jan Mayen, +SK,Slovakia, +SL,Sierra Leone, +SM,San Marino, +SN,Senegal, +SO,Somalia, +SR,Suriname, +SS,South Sudan, +ST,Sao Tome and Principe, +SV,El Salvador, +SX,Sint Maarten, +SY,Syrian Arab Republic, +SZ,Swaziland, +TC,Turks and Caicos Islands, +TD,Chad, +TF,French Southern Territories, +TG,Togo, +TH,Thailand, +TJ,Tajikistan, +TK,Tokelau, +TL,Timor-Leste, +TM,Turkmenistan, +TN,Tunisia, +TO,Tonga, +TR,Turkey, +TT,Trinidad and Tobago, +TV,Tuvalu, +TW,Taiwan, +TZ,"Tanzania, United Republic of", +UA,Ukraine, +UG,Uganda, +UM,United States Minor Outlying Islands, +US,United States, +UY,Uruguay, +UZ,Uzbekistan, +VA,Holy See (Vatican City State), +VC,Saint Vincent and the Grenadines, +VE,Venezuela, +VG,"Virgin Islands, British", +VI,"Virgin Islands, U.S.", +VN,Vietnam, +VU,Vanuatu, +WF,Wallis and Futuna, +WS,Samoa, +YE,Yemen, +YT,Mayotte, +ZA,South Africa, +ZM,Zambia, +ZW,Zimbabwe, \ No newline at end of file diff --git a/env/lib/python3.7/site-packages/ipwhois/data/iso_3166-1_list_en.xml b/env/lib/python3.7/site-packages/ipwhois/data/iso_3166-1_list_en.xml new file mode 100644 index 0000000..31d5e02 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/data/iso_3166-1_list_en.xml @@ -0,0 +1,1003 @@ + + + + AFGHANISTAN + AF + + + ALAND ISLANDS + AX + + + ALBANIA + AL + + + ALGERIA + DZ + + + AMERICAN SAMOA + AS + + + ANDORRA + AD + + + ANGOLA + AO + + + ANGUILLA + AI + + + ANTARCTICA + AQ + + + ANTIGUA AND BARBUDA + AG + + + NETHERLANDS ANTILLES + AN + + + ARGENTINA + AR + + + ARMENIA + AM + + + ARUBA + AW + + + AUSTRALIA + AU + + + AUSTRIA + AT + + + AZERBAIJAN + AZ + + + BAHAMAS + BS + + + BAHRAIN + BH + + + BANGLADESH + BD + + + BARBADOS + BB + + + BELARUS + BY + + + BELGIUM + BE + + + BELIZE + BZ + + + BENIN + BJ + + + BERMUDA + BM + + + BHUTAN + BT + + + BOLIVIA, PLURINATIONAL STATE OF + BO + + + BONAIRE, SINT EUSTATIUS AND SABA + BQ + + + BOSNIA AND HERZEGOVINA + BA + + + BOTSWANA + BW + + + BOUVET ISLAND + BV + + + BRAZIL + BR + + + BRITISH INDIAN OCEAN TERRITORY + IO + + + BRUNEI DARUSSALAM + BN + + + BULGARIA + BG + + + BURKINA FASO + BF + + + BURUNDI + BI + + + CAMBODIA + KH + + + CAMEROON + CM + + + CANADA + CA + + + CAPE VERDE + CV + + + CAYMAN ISLANDS + KY + + + CENTRAL AFRICAN REPUBLIC + CF + + + CHAD + TD + + + CHILE + CL + + + CHINA + CN + + + CHRISTMAS ISLAND + CX + + + COCOS (KEELING) ISLANDS + CC + + + COLOMBIA + CO + + + COMOROS + KM + + + CONGO + CG + + + CONGO, THE DEMOCRATIC REPUBLIC OF THE + CD + + + COOK ISLANDS + CK + + + COSTA RICA + CR + + + COTE D'IVOIRE + CI + + + CROATIA + HR + + + CURACAO + CW + + + CUBA + CU + + + CYPRUS + CY + + + CZECH REPUBLIC + CZ + + + DENMARK + DK + + + DJIBOUTI + DJ + + + DOMINICA + DM + + + DOMINICAN REPUBLIC + DO + + + ECUADOR + EC + + + EGYPT + EG + + + EL SALVADOR + SV + + + EQUATORIAL GUINEA + GQ + + + ERITREA + ER + + + ESTONIA + EE + + + ETHIOPIA + ET + + + FALKLAND ISLANDS (MALVINAS) + FK + + + FAROE ISLANDS + FO + + + FIJI + FJ + + + FINLAND + FI + + + FRANCE + FR + + + FRENCH GUIANA + GF + + + FRENCH POLYNESIA + PF + + + FRENCH SOUTHERN TERRITORIES + TF + + + GABON + GA + + + GAMBIA + GM + + + GEORGIA + GE + + + GERMANY + DE + + + GHANA + GH + + + GIBRALTAR + GI + + + GREECE + GR + + + GREENLAND + GL + + + GRENADA + GD + + + GUADELOUPE + GP + + + GUAM + GU + + + GUATEMALA + GT + + + GUERNSEY + GG + + + GUINEA + GN + + + GUINEA-BISSAU + GW + + + GUYANA + GY + + + HAITI + HT + + + HEARD ISLAND AND MCDONALD ISLANDS + HM + + + HOLY SEE (VATICAN CITY STATE) + VA + + + HONDURAS + HN + + + HONG KONG + HK + + + HUNGARY + HU + + + ICELAND + IS + + + INDIA + IN + + + INDONESIA + ID + + + IRAN, ISLAMIC REPUBLIC OF + IR + + + IRAQ + IQ + + + IRELAND + IE + + + ISLE OF MAN + IM + + + ISRAEL + IL + + + ITALY + IT + + + JAMAICA + JM + + + JAPAN + JP + + + JERSEY + JE + + + JORDAN + JO + + + KAZAKHSTAN + KZ + + + KENYA + KE + + + KIRIBATI + KI + + + KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF + KP + + + KOREA, REPUBLIC OF + KR + + + KUWAIT + KW + + + KYRGYZSTAN + KG + + + LAO PEOPLE'S DEMOCRATIC REPUBLIC + LA + + + LATVIA + LV + + + LEBANON + LB + + + LESOTHO + LS + + + LIBERIA + LR + + + LIBYA + LY + + + LIECHTENSTEIN + LI + + + LITHUANIA + LT + + + LUXEMBOURG + LU + + + MACAO + MO + + + MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF + MK + + + MADAGASCAR + MG + + + MALAWI + MW + + + MALAYSIA + MY + + + MALDIVES + MV + + + MALI + ML + + + MALTA + MT + + + MARSHALL ISLANDS + MH + + + MARTINIQUE + MQ + + + MAURITANIA + MR + + + MAURITIUS + MU + + + MAYOTTE + YT + + + MEXICO + MX + + + MICRONESIA, FEDERATED STATES OF + FM + + + MOLDOVA, REPUBLIC OF + MD + + + MONACO + MC + + + MONGOLIA + MN + + + MONTENEGRO + ME + + + MONTSERRAT + MS + + + MOROCCO + MA + + + MOZAMBIQUE + MZ + + + MYANMAR + MM + + + NAMIBIA + NA + + + NAURU + NR + + + NEPAL + NP + + + NETHERLANDS + NL + + + NEW CALEDONIA + NC + + + NEW ZEALAND + NZ + + + NICARAGUA + NI + + + NIGER + NE + + + NIGERIA + NG + + + NIUE + NU + + + NORFOLK ISLAND + NF + + + NORTHERN MARIANA ISLANDS + MP + + + NORWAY + NO + + + OMAN + OM + + + PAKISTAN + PK + + + PALAU + PW + + + PALESTINIAN TERRITORY, OCCUPIED + PS + + + PANAMA + PA + + + PAPUA NEW GUINEA + PG + + + PARAGUAY + PY + + + PERU + PE + + + PHILIPPINES + PH + + + PITCAIRN + PN + + + POLAND + PL + + + PORTUGAL + PT + + + PUERTO RICO + PR + + + QATAR + QA + + + REUNION + RE + + + ROMANIA + RO + + + RUSSIAN FEDERATION + RU + + + RWANDA + RW + + + SAINT BARTHELEMY + BL + + + SAINT HELENA, ASCENSION AND TRISTAN DA CUNHA + SH + + + SAINT KITTS AND NEVIS + KN + + + SAINT LUCIA + LC + + + SAINT MARTIN (FRENCH PART) + MF + + + SAINT PIERRE AND MIQUELON + PM + + + SAINT VINCENT AND THE GRENADINES + VC + + + SAMOA + WS + + + SAN MARINO + SM + + + SAO TOME AND PRINCIPE + ST + + + SAUDI ARABIA + SA + + + SENEGAL + SN + + + SERBIA + RS + + + SEYCHELLES + SC + + + SIERRA LEONE + SL + + + SINGAPORE + SG + + + SINT MAARTEN (DUTCH PART) + SX + + + SLOVAKIA + SK + + + SLOVENIA + SI + + + SOLOMON ISLANDS + SB + + + SOMALIA + SO + + + SOUTH AFRICA + ZA + + + SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS + GS + + + SOUTH SUDAN + SS + + + SPAIN + ES + + + SRI LANKA + LK + + + SUDAN + SD + + + SURINAME + SR + + + SVALBARD AND JAN MAYEN + SJ + + + SWAZILAND + SZ + + + SWEDEN + SE + + + SWITZERLAND + CH + + + SYRIAN ARAB REPUBLIC + SY + + + TAIWAN, PROVINCE OF CHINA + TW + + + TAJIKISTAN + TJ + + + TANZANIA, UNITED REPUBLIC OF + TZ + + + THAILAND + TH + + + TIMOR-LESTE + TL + + + TOGO + TG + + + TOKELAU + TK + + + TONGA + TO + + + TRINIDAD AND TOBAGO + TT + + + TUNISIA + TN + + + TURKEY + TR + + + TURKMENISTAN + TM + + + TURKS AND CAICOS ISLANDS + TC + + + TUVALU + TV + + + UGANDA + UG + + + UKRAINE + UA + + + UNITED ARAB EMIRATES + AE + + + UNITED KINGDOM + GB + + + UNITED STATES + US + + + UNITED STATES MINOR OUTLYING ISLANDS + UM + + + URUGUAY + UY + + + UZBEKISTAN + UZ + + + VANUATU + VU + + + VENEZUELA, BOLIVARIAN REPUBLIC OF + VE + + + VIET NAM + VN + + + VIRGIN ISLANDS, BRITISH + VG + + + VIRGIN ISLANDS, U.S. + VI + + + WALLIS AND FUTUNA + WF + + + WESTERN SAHARA + EH + + + YEMEN + YE + + + ZAMBIA + ZM + + + ZIMBABWE + ZW + + diff --git a/env/lib/python3.7/site-packages/ipwhois/exceptions.py b/env/lib/python3.7/site-packages/ipwhois/exceptions.py new file mode 100644 index 0000000..5e2f78a --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/exceptions.py @@ -0,0 +1,121 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +class NetError(Exception): + """ + An Exception for when a parameter provided is not an instance of + ipwhois.net.Net. + """ + + +class IPDefinedError(Exception): + """ + An Exception for when the IP is defined (does not need to be resolved). + """ + + +class ASNLookupError(Exception): + """ + An Exception for when the ASN lookup failed. + """ + + +class ASNRegistryError(Exception): + """ + An Exception for when the ASN registry does not match one of the five + expected values (arin, ripencc, apnic, lacnic, afrinic). + """ + + +class ASNParseError(Exception): + """ + An Exception for when the ASN parsing failed. + """ + + +class ASNOriginLookupError(Exception): + """ + An Exception for when the ASN origin lookup failed. + """ + + +class HostLookupError(Exception): + """ + An Exception for when the host lookup failed. + """ + + +class BlacklistError(Exception): + """ + An Exception for when the server is in a blacklist. + """ + + +class WhoisLookupError(Exception): + """ + An Exception for when the whois lookup failed. + """ + + +class WhoisRateLimitError(Exception): + """ + An Exception for when Whois queries exceed the NIC's request limit and have + exhausted all retries. + """ + + +class HTTPLookupError(Exception): + """ + An Exception for when the RDAP lookup failed. + """ + + +class HTTPRateLimitError(Exception): + """ + An Exception for when HTTP queries exceed the NIC's request limit and have + exhausted all retries. + """ + + +class InvalidEntityContactObject(Exception): + """ + An Exception for when JSON output is not an RDAP entity contact information + object: + https://tools.ietf.org/html/rfc7483#section-5.4 + """ + + +class InvalidNetworkObject(Exception): + """ + An Exception for when JSON output is not an RDAP network object: + https://tools.ietf.org/html/rfc7483#section-5.4 + """ + + +class InvalidEntityObject(Exception): + """ + An Exception for when JSON output is not an RDAP entity object: + https://tools.ietf.org/html/rfc7483#section-5.1 + """ diff --git a/env/lib/python3.7/site-packages/ipwhois/experimental.py b/env/lib/python3.7/site-packages/ipwhois/experimental.py new file mode 100644 index 0000000..23261a3 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/experimental.py @@ -0,0 +1,457 @@ +# Copyright (c) 2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import socket +import logging +import time +from collections import namedtuple + +from .exceptions import (ASNLookupError, HTTPLookupError, HTTPRateLimitError, + ASNRegistryError) +from .asn import IPASN +from .net import (CYMRU_WHOIS, Net) +from .rdap import RDAP +from .utils import unique_everseen + +log = logging.getLogger(__name__) + + +def get_bulk_asn_whois(addresses=None, retry_count=3, timeout=120): + """ + The function for retrieving ASN information for multiple IP addresses from + Cymru via port 43/tcp (WHOIS). + + Args: + addresses (:obj:`list` of :obj:`str`): IP addresses to lookup. + retry_count (:obj:`int`): The number of times to retry in case socket + errors, timeouts, connection resets, etc. are encountered. + Defaults to 3. + timeout (:obj:`int`): The default timeout for socket connections in + seconds. Defaults to 120. + + Returns: + str: The raw ASN bulk data, new line separated. + + Raises: + ValueError: addresses argument must be a list of IPv4/v6 address + strings. + ASNLookupError: The ASN bulk lookup failed. + """ + + if not isinstance(addresses, list): + + raise ValueError('addresses argument must be a list of IPv4/v6 ' + 'address strings.') + + try: + + # Create the connection for the Cymru whois query. + conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + conn.settimeout(timeout) + log.debug('ASN bulk query initiated.') + conn.connect((CYMRU_WHOIS, 43)) + + # Query the Cymru whois server, and store the results. + conn.sendall(( + ' -r -a -c -p -f begin\n{0}\nend'.format( + '\n'.join(addresses)) + ).encode()) + + data = '' + while True: + + d = conn.recv(4096).decode() + data += d + + if not d: + + break + + conn.close() + + return str(data) + + except (socket.timeout, socket.error) as e: # pragma: no cover + + log.debug('ASN bulk query socket error: {0}'.format(e)) + if retry_count > 0: + + log.debug('ASN bulk query retrying (count: {0})'.format( + str(retry_count))) + return get_bulk_asn_whois(addresses, retry_count - 1, timeout) + + else: + + raise ASNLookupError('ASN bulk lookup failed.') + + except: # pragma: no cover + + raise ASNLookupError('ASN bulk lookup failed.') + + +def bulk_lookup_rdap(addresses=None, inc_raw=False, retry_count=3, depth=0, + excluded_entities=None, rate_limit_timeout=60, + socket_timeout=10, asn_timeout=240, proxy_openers=None): + """ + The function for bulk retrieving and parsing whois information for a list + of IP addresses via HTTP (RDAP). This bulk lookup method uses bulk + ASN Whois lookups first to retrieve the ASN for each IP. It then optimizes + RDAP queries to achieve the fastest overall time, accounting for + rate-limiting RIRs. + + Args: + addresses (:obj:`list` of :obj:`str`): IP addresses to lookup. + inc_raw (:obj:`bool`, optional): Whether to include the raw whois + results in the returned dictionary. Defaults to False. + retry_count (:obj:`int`): The number of times to retry in case socket + errors, timeouts, connection resets, etc. are encountered. + Defaults to 3. + depth (:obj:`int`): How many levels deep to run queries when additional + referenced objects are found. Defaults to 0. + excluded_entities (:obj:`list` of :obj:`str`): Entity handles to not + perform lookups. Defaults to None. + rate_limit_timeout (:obj:`int`): The number of seconds to wait before + retrying when a rate limit notice is returned via rdap+json. + Defaults to 60. + socket_timeout (:obj:`int`): The default timeout for socket + connections in seconds. Defaults to 10. + asn_timeout (:obj:`int`): The default timeout for bulk ASN lookups in + seconds. Defaults to 240. + proxy_openers (:obj:`list` of :obj:`OpenerDirector`): Proxy openers + for single/rotating proxy support. Defaults to None. + + Returns: + namedtuple: + + :results (dict): IP address keys with the values as dictionaries + returned by IPWhois.lookup_rdap(). + :stats (dict): Stats for the lookups: + + :: + + { + 'ip_input_total' (int) - The total number of addresses + originally provided for lookup via the addresses argument. + 'ip_unique_total' (int) - The total number of unique addresses + found in the addresses argument. + 'ip_lookup_total' (int) - The total number of addresses that + lookups were attempted for, excluding any that failed ASN + registry checks. + 'lacnic' (dict) - + { + 'failed' (list) - The addresses that failed to lookup. + Excludes any that failed initially, but succeeded after + futher retries. + 'rate_limited' (list) - The addresses that encountered + rate-limiting. Unless an address is also in 'failed', + it eventually succeeded. + 'total' (int) - The total number of addresses belonging to + this RIR that lookups were attempted for. + } + 'ripencc' (dict) - Same as 'lacnic' above. + 'apnic' (dict) - Same as 'lacnic' above. + 'afrinic' (dict) - Same as 'lacnic' above. + 'arin' (dict) - Same as 'lacnic' above. + 'unallocated_addresses' (list) - The addresses that are + unallocated/failed ASN lookups. These can be addresses that + are not listed for one of the 5 RIRs (other). No attempt + was made to perform an RDAP lookup for these. + } + + Raises: + ASNLookupError: The ASN bulk lookup failed, cannot proceed with bulk + RDAP lookup. + """ + + if not isinstance(addresses, list): + + raise ValueError('addresses must be a list of IP address strings') + + # Initialize the dicts/lists + results = {} + failed_lookups_dict = {} + rated_lookups = [] + stats = { + 'ip_input_total': len(addresses), + 'ip_unique_total': 0, + 'ip_lookup_total': 0, + 'lacnic': {'failed': [], 'rate_limited': [], 'total': 0}, + 'ripencc': {'failed': [], 'rate_limited': [], 'total': 0}, + 'apnic': {'failed': [], 'rate_limited': [], 'total': 0}, + 'afrinic': {'failed': [], 'rate_limited': [], 'total': 0}, + 'arin': {'failed': [], 'rate_limited': [], 'total': 0}, + 'unallocated_addresses': [] + } + asn_parsed_results = {} + + if proxy_openers is None: + + proxy_openers = [None] + + proxy_openers_copy = iter(proxy_openers) + + # Make sure addresses is unique + unique_ip_list = list(unique_everseen(addresses)) + + # Get the unique count to return + stats['ip_unique_total'] = len(unique_ip_list) + + # This is needed for iteration order + rir_keys_ordered = ['lacnic', 'ripencc', 'apnic', 'afrinic', 'arin'] + + # First query the ASN data for all IPs, can raise ASNLookupError, no catch + bulk_asn = get_bulk_asn_whois(unique_ip_list, timeout=asn_timeout) + + # ASN results are returned as string, parse lines to list and remove first + asn_result_list = bulk_asn.split('\n') + del asn_result_list[0] + + # We need to instantiate IPASN, which currently needs a Net object, + # IP doesn't matter here + net = Net('1.2.3.4') + ipasn = IPASN(net) + + # Iterate each IP ASN result, and add valid RIR results to + # asn_parsed_results for RDAP lookups + for asn_result in asn_result_list: + + temp = asn_result.split('|') + + # Not a valid entry, move on to next + if len(temp) == 1: + + continue + + ip = temp[1].strip() + + # We need this since ASN bulk lookup is returning duplicates + # This is an issue on the Cymru end + if ip in asn_parsed_results.keys(): # pragma: no cover + + continue + + try: + + results = ipasn.parse_fields_whois(asn_result) + + except ASNRegistryError: # pragma: no cover + + continue + + # Add valid IP ASN result to asn_parsed_results for RDAP lookup + asn_parsed_results[ip] = results + stats[results['asn_registry']]['total'] += 1 + + # Set the list of IPs that are not allocated/failed ASN lookup + stats['unallocated_addresses'] = list(k for k in addresses if k not in + asn_parsed_results) + + # Set the total lookup count after unique IP and ASN result filtering + stats['ip_lookup_total'] = len(asn_parsed_results) + + # Track the total number of LACNIC queries left. This is tracked in order + # to ensure the 9 priority LACNIC queries/min don't go into infinite loop + lacnic_total_left = stats['lacnic']['total'] + + # Set the start time, this value is updated when the rate limit is reset + old_time = time.time() + + # Rate limit tracking dict for all RIRs + rate_tracker = { + 'lacnic': {'time': old_time, 'count': 0}, + 'ripencc': {'time': old_time, 'count': 0}, + 'apnic': {'time': old_time, 'count': 0}, + 'afrinic': {'time': old_time, 'count': 0}, + 'arin': {'time': old_time, 'count': 0} + } + + # Iterate all of the IPs to perform RDAP lookups until none are left + while len(asn_parsed_results) > 0: + + # Sequentially run through each RIR to minimize lookups in a row to + # the same RIR. + for rir in rir_keys_ordered: + + # If there are still LACNIC IPs left to lookup and the rate limit + # hasn't been reached, skip to find a LACNIC IP to lookup + if ( + rir != 'lacnic' and lacnic_total_left > 0 and + (rate_tracker['lacnic']['count'] != 9 or + (time.time() - rate_tracker['lacnic']['time'] + ) >= rate_limit_timeout + ) + ): # pragma: no cover + + continue + + # If the RIR rate limit has been reached and hasn't expired, + # move on to the next RIR + if ( + rate_tracker[rir]['count'] == 9 and ( + (time.time() - rate_tracker[rir]['time'] + ) < rate_limit_timeout) + ): # pragma: no cover + + continue + + # If the RIR rate limit has expired, reset the count/timer + # and perform the lookup + elif ((time.time() - rate_tracker[rir]['time'] + ) >= rate_limit_timeout): # pragma: no cover + + rate_tracker[rir]['count'] = 0 + rate_tracker[rir]['time'] = time.time() + + # Create a copy of the lookup IP dict so we can modify on + # successful/failed queries. Loop each IP until it matches the + # correct RIR in the parent loop, and attempt lookup + tmp_dict = asn_parsed_results.copy() + + for ip, asn_data in tmp_dict.items(): + + # Check to see if IP matches parent loop RIR for lookup + if asn_data['asn_registry'] == rir: + + log.debug('Starting lookup for IP: {0} ' + 'RIR: {1}'.format(ip, rir)) + + # Add to count for rate-limit tracking only for LACNIC, + # since we have not seen aggressive rate-limiting from the + # other RIRs yet + if rir == 'lacnic': + + rate_tracker[rir]['count'] += 1 + + # Get the next proxy opener to use, or None + try: + + opener = next(proxy_openers_copy) + + # Start at the beginning if all have been used + except StopIteration: + + proxy_openers_copy = iter(proxy_openers) + opener = next(proxy_openers_copy) + + # Instantiate the objects needed for the RDAP lookup + net = Net(ip, timeout=socket_timeout, proxy_opener=opener) + rdap = RDAP(net) + + try: + + # Perform the RDAP lookup. retry_count is set to 0 + # here since we handle that in this function + results = rdap.lookup( + inc_raw=inc_raw, retry_count=0, asn_data=asn_data, + depth=depth, excluded_entities=excluded_entities + ) + + log.debug('Successful lookup for IP: {0} ' + 'RIR: {1}'.format(ip, rir)) + + # Lookup was successful, add to result. Set the nir + # key to None as this is not supported + # (yet - requires more queries) + results[ip] = results + results[ip]['nir'] = None + + # Remove the IP from the lookup queue + del asn_parsed_results[ip] + + # If this was LACNIC IP, reduce the total left count + if rir == 'lacnic': + + lacnic_total_left -= 1 + + log.debug( + '{0} total lookups left, {1} LACNIC lookups left' + ''.format(str(len(asn_parsed_results)), + str(lacnic_total_left)) + ) + + # If this IP failed previously, remove it from the + # failed return dict + if ( + ip in failed_lookups_dict.keys() + ): # pragma: no cover + + del failed_lookups_dict[ip] + + # Break out of the IP list loop, we need to change to + # the next RIR + break + + except HTTPLookupError: # pragma: no cover + + log.debug('Failed lookup for IP: {0} ' + 'RIR: {1}'.format(ip, rir)) + + # Add the IP to the failed lookups dict if not there + if ip not in failed_lookups_dict.keys(): + + failed_lookups_dict[ip] = 1 + + # This IP has already failed at least once, increment + # the failure count until retry_count reached, then + # stop trying + else: + + failed_lookups_dict[ip] += 1 + + if failed_lookups_dict[ip] == retry_count: + + del asn_parsed_results[ip] + stats[rir]['failed'].append(ip) + + if rir == 'lacnic': + + lacnic_total_left -= 1 + + # Since this IP failed, we don't break to move to next + # RIR, we check the next IP for this RIR + continue + + except HTTPRateLimitError: # pragma: no cover + + # Add the IP to the rate-limited lookups dict if not + # there + if ip not in rated_lookups: + + rated_lookups.append(ip) + stats[rir]['rate_limited'].append(ip) + + log.debug('Rate limiting triggered for IP: {0} ' + 'RIR: {1}'.format(ip, rir)) + + # Since rate-limit was reached, reset the timer and + # max out the count + rate_tracker[rir]['time'] = time.time() + rate_tracker[rir]['count'] = 9 + + # Break out of the IP list loop, we need to change to + # the next RIR + break + + return_tuple = namedtuple('return_tuple', ['results', 'stats']) + return return_tuple(results, stats) diff --git a/env/lib/python3.7/site-packages/ipwhois/hr.py b/env/lib/python3.7/site-packages/ipwhois/hr.py new file mode 100644 index 0000000..43ba82f --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/hr.py @@ -0,0 +1,509 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# TODO: Add '_links' for RFC/other references + +HR_ASN = { + 'asn': { + '_short': 'ASN', + '_name': 'Autonomous System Number', + '_description': 'Globally unique identifier used for routing ' + 'information exchange with Autonomous Systems.' + }, + 'asn_cidr': { + '_short': 'ASN CIDR Block', + '_name': 'ASN Classless Inter-Domain Routing Block', + '_description': 'Network routing block assigned to an ASN.' + }, + 'asn_country_code': { + '_short': 'ASN Country Code', + '_name': 'ASN Assigned Country Code', + '_description': 'ASN assigned country code in ISO 3166-1 format.' + }, + 'asn_date': { + '_short': 'ASN Date', + '_name': 'ASN Allocation Date', + '_description': 'ASN allocation date in ISO 8601 format.' + }, + 'asn_registry': { + '_short': 'ASN Registry', + '_name': 'ASN Assigned Registry', + '_description': 'ASN assigned regional internet registry.' + }, + 'asn_description': { + '_short': 'ASN Description', + '_name': 'ASN Description', + '_description': 'A brief description for the assigned ASN.' + } +} + +HR_ASN_ORIGIN = { + 'nets': { + '_short': 'Network', + '_name': 'ASN Network', + '_description': 'A network associated with an Autonomous System Number' + ' (ASN)', + 'cidr': { + '_short': 'CIDR', + '_name': 'Classless Inter-Domain Routing Block', + '_description': 'The network routing block.' + }, + 'description': { + '_short': 'Description', + '_name': 'Description', + '_description': 'Description for the registered network.' + }, + 'maintainer': { + '_short': 'Maintainer', + '_name': 'Maintainer', + '_description': 'The entity that maintains the network.' + }, + 'updated': { + '_short': 'Updated', + '_name': 'Updated Timestamp', + '_description': 'Network registration updated information.' + }, + 'source': { + '_short': 'Source', + '_name': 'ASN Network Information Source', + '_description': 'The source of the network information.' + } + } +} + +HR_RDAP_COMMON = { + 'entities': { + '_short': 'Entities', + '_name': 'RIR Object Entities', + '_description': 'List of object names referenced by an RIR object.' + }, + 'events': { + '_short': 'Events', + '_name': 'Events', + '_description': 'Events for an RIR object.', + 'action': { + '_short': 'Action', + '_name': 'Event Action (Reason)', + '_description': 'The reason for an event.' + }, + 'timestamp': { + '_short': 'Timestamp', + '_name': 'Event Timestamp', + '_description': 'The date an event occured in ISO 8601 ' + 'format.' + }, + 'actor': { + '_short': 'Actor', + '_name': 'Event Actor', + '_description': 'The identifier for an event initiator.' + } + }, + 'handle': { + '_short': 'Handle', + '_name': 'RIR Handle', + '_description': 'Unique identifier for a registered object.' + }, + 'links': { + '_short': 'Links', + '_name': 'Links', + '_description': 'HTTP/HTTPS links provided for an RIR object.' + }, + 'notices': { + '_short': 'Notices', + '_name': 'Notices', + '_description': 'Notices for an RIR object.', + 'description': { + '_short': 'Description', + '_name': 'Notice Description', + '_description': 'The description/body of a notice.' + }, + 'title': { + '_short': 'Title', + '_name': 'Notice Title', + '_description': 'The title/header for a notice.' + }, + 'links': { + '_short': 'Links', + '_name': 'Notice Links', + '_description': 'HTTP/HTTPS links provided for a notice.' + } + }, + 'remarks': { + '_short': 'Remarks', + '_name': 'Remarks', + '_description': 'Remarks for an RIR object.', + 'description': { + '_short': 'Description', + '_name': 'Remark Description', + '_description': 'The description/body of a remark.' + }, + 'title': { + '_short': 'Title', + '_name': 'Remark Title', + '_description': 'The title/header for a remark.' + }, + 'links': { + '_short': 'Links', + '_name': 'Remark Links', + '_description': 'HTTP/HTTPS links provided for a remark.' + } + }, + 'status': { + '_short': 'Status', + '_name': 'Object Status', + '_description': 'List indicating the state of a registered object.' + } +} + +HR_RDAP = { + 'network': { + '_short': 'Network', + '_name': 'RIR Network', + '_description': 'The assigned network for an IP address.', + 'cidr': { + '_short': 'CIDR Block', + '_name': 'Classless Inter-Domain Routing Block', + '_description': 'Network routing block an IP address belongs to.' + }, + 'country': { + '_short': 'Country Code', + '_name': 'Country Code', + '_description': 'Country code registered with the RIR in ' + 'ISO 3166-1 format.' + }, + 'end_address': { + '_short': 'End Address', + '_name': 'Ending IP Address', + '_description': 'The last IP address in a network block.' + }, + 'events': HR_RDAP_COMMON['events'], + 'handle': HR_RDAP_COMMON['handle'], + 'ip_version': { + '_short': 'IP Version', + '_name': 'IP Protocol Version', + '_description': 'The IP protocol version (v4 or v6) of an IP ' + 'address.' + }, + 'links': HR_RDAP_COMMON['links'], + 'name': { + '_short': 'Name', + '_name': 'RIR Network Name', + '_description': 'The identifier assigned to the network ' + 'registration for an IP address.' + }, + 'notices': HR_RDAP_COMMON['notices'], + 'parent_handle': { + '_short': 'Parent Handle', + '_name': 'RIR Parent Handle', + '_description': 'Unique identifier for the parent network of ' + 'a registered network.' + }, + 'remarks': HR_RDAP_COMMON['remarks'], + 'start_address': { + '_short': 'Start Address', + '_name': 'Starting IP Address', + '_description': 'The first IP address in a network block.' + }, + 'status': HR_RDAP_COMMON['status'], + 'type': { + '_short': 'Type', + '_name': 'RIR Network Type', + '_description': 'The RIR classification of a registered network.' + } + }, + 'entities': HR_RDAP_COMMON['entities'], + 'objects': { + '_short': 'Objects', + '_name': 'RIR Objects', + '_description': 'The objects (entities) referenced by an RIR network.', + 'contact': { + '_short': 'Contact', + '_name': 'Contact Information', + '_description': 'Contact information registered with an RIR ' + 'object.', + 'address': { + '_short': 'Address', + '_name': 'Postal Address', + '_description': 'The contact postal address.' + }, + 'email': { + '_short': 'Email', + '_name': 'Email Address', + '_description': 'The contact email address.' + }, + 'kind': { + '_short': 'Kind', + '_name': 'Kind', + '_description': 'The contact information kind (individual, ' + 'group, org, etc).' + }, + 'name': { + '_short': 'Name', + '_name': 'Name', + '_description': 'The contact name.' + }, + 'phone': { + '_short': 'Phone', + '_name': 'Phone Number', + '_description': 'The contact phone number.' + }, + 'role': { + '_short': 'Role', + '_name': 'Role', + '_description': 'The contact\'s role.' + }, + 'title': { + '_short': 'Title', + '_name': 'Title', + '_description': 'The contact\'s position or job title.' + } + }, + 'entities': HR_RDAP_COMMON['entities'], + 'events': HR_RDAP_COMMON['events'], + 'events_actor': { + '_short': 'Events Misc', + '_name': 'Events w/o Actor', + '_description': 'An event for an RIR object with no event actor.', + 'action': { + '_short': 'Action', + '_name': 'Event Action (Reason)', + '_description': 'The reason for an event.' + }, + 'timestamp': { + '_short': 'Timestamp', + '_name': 'Event Timestamp', + '_description': 'The date an event occured in ISO 8601 ' + 'format.' + } + }, + 'handle': HR_RDAP_COMMON['handle'], + 'links': HR_RDAP_COMMON['links'], + 'notices': HR_RDAP_COMMON['notices'], + 'remarks': HR_RDAP_COMMON['remarks'], + 'roles': { + '_short': 'Roles', + '_name': 'Roles', + '_description': 'List of roles assigned to a registered object.' + }, + 'status': HR_RDAP_COMMON['status'], + } +} + +HR_WHOIS = { + 'nets': { + '_short': 'Network', + '_name': 'RIR Network', + '_description': 'The assigned network for an IP address. May be a ' + 'parent or child network.', + 'address': { + '_short': 'Address', + '_name': 'Postal Address', + '_description': 'The contact postal address.' + }, + 'cidr': { + '_short': 'CIDR Blocks', + '_name': 'Classless Inter-Domain Routing Blocks', + '_description': 'Network routing blocks an IP address belongs to.' + }, + 'city': { + '_short': 'City', + '_name': 'City', + '_description': 'The city registered with a whois network.' + }, + 'country': { + '_short': 'Country Code', + '_name': 'Country Code', + '_description': 'Country code registered for the network in ' + 'ISO 3166-1 format.' + }, + 'created': { + '_short': 'Created', + '_name': 'Created Timestamp', + '_description': 'The date the network was created in ISO 8601 ' + 'format.' + }, + 'description': { + '_short': 'Description', + '_name': 'Description', + '_description': 'The description for the network.' + }, + 'emails': { + '_short': 'Emails', + '_name': 'Email Addresses', + '_description': 'The contact email addresses.' + }, + 'handle': { + '_short': 'Handle', + '_name': 'RIR Network Handle', + '_description': 'Unique identifier for a registered network.' + }, + 'name': { + '_short': 'Name', + '_name': 'RIR Network Name', + '_description': 'The identifier assigned to the network ' + 'registration for an IP address.' + }, + 'postal_code': { + '_short': 'Postal', + '_name': 'Postal Code', + '_description': 'The postal code registered with a whois network.' + }, + 'range': { + '_short': 'Ranges', + '_name': 'CIDR Block Ranges', + '_description': 'Network routing blocks an IP address belongs to.' + }, + 'state': { + '_short': 'State', + '_name': 'State', + '_description': 'The state registered with a whois network.' + }, + 'updated': { + '_short': 'Updated', + '_name': 'Updated Timestamp', + '_description': 'The date the network was updated in ISO 8601 ' + 'format.' + } + }, + 'referral': { + '_short': 'Referral', + '_name': 'Referral Whois', + '_description': 'The referral whois data if referenced and enabled.', + } +} + +HR_WHOIS_NIR = { + 'nets': { + '_short': 'NIR Network', + '_name': 'National Internet Registry Network', + '_description': 'The assigned NIR (JPNIC, KRNIC) network for an IP ' + 'address. May be a parent or child network.', + 'address': { + '_short': 'Address', + '_name': 'Postal Address', + '_description': 'The network contact postal address.' + }, + 'cidr': { + '_short': 'CIDR Blocks', + '_name': 'Classless Inter-Domain Routing Blocks', + '_description': 'Network routing blocks an IP address belongs to.' + }, + 'country': { + '_short': 'Country Code', + '_name': 'Country Code', + '_description': 'Country code registered for the network in ' + 'ISO 3166-1 format.' + }, + 'handle': { + '_short': 'Handle', + '_name': 'NIR Network Handle', + '_description': 'Unique identifier for a registered NIR network.' + }, + 'name': { + '_short': 'Name', + '_name': 'NIR Network Name', + '_description': 'The identifier assigned to the network ' + 'registration for an IP address.' + }, + 'postal_code': { + '_short': 'Postal', + '_name': 'Postal Code', + '_description': 'The postal code registered with a NIR network.' + }, + 'range': { + '_short': 'Ranges', + '_name': 'CIDR Block Ranges', + '_description': 'Network routing blocks an IP address belongs to.' + }, + 'nameservers': { + '_short': 'NS', + '_name': 'Nameservers', + '_description': 'Nameservers associated with a NIR network.' + }, + 'created': { + '_short': 'Created', + '_name': 'Created Timestamp', + '_description': 'The date the network was created in ISO 8601 ' + 'format.' + }, + 'updated': { + '_short': 'Updated', + '_name': 'Updated Timestamp', + '_description': 'The date the network was updated in ISO 8601 ' + 'format.' + }, + 'contacts': { + '_short': 'Contacts', + '_name': 'NIR Contacts', + '_description': 'The contacts (admin, tech) registered with a NIR ' + 'network.', + 'organization': { + '_short': 'Org', + '_name': 'Organization', + '_description': 'The contact organization.' + }, + 'division': { + '_short': 'Div', + '_name': 'Division', + '_description': 'The contact division of the organization.' + }, + 'name': { + '_short': 'Name', + '_name': 'Name', + '_description': 'The contact name.' + }, + 'title': { + '_short': 'Title', + '_name': 'Title', + '_description': 'The contact position or job title.' + }, + 'phone': { + '_short': 'Phone', + '_name': 'Phone Number', + '_description': 'The contact phone number.' + }, + 'fax': { + '_short': 'Fax', + '_name': 'Fax Number', + '_description': 'The contact fax number.' + }, + 'email': { + '_short': 'Email', + '_name': 'Email Address', + '_description': 'The contact email address.' + }, + 'reply_email': { + '_short': 'Reply Email', + '_name': 'Reply Email Address', + '_description': 'The contact reply email address.' + }, + 'updated': { + '_short': 'Updated', + '_name': 'Updated Timestamp', + '_description': 'The date the contact was updated in ISO 8601 ' + 'format.' + } + } + } +} diff --git a/env/lib/python3.7/site-packages/ipwhois/ipwhois.py b/env/lib/python3.7/site-packages/ipwhois/ipwhois.py new file mode 100644 index 0000000..0839143 --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/ipwhois.py @@ -0,0 +1,346 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from . import Net +from .asn import IPASN +from .nir import NIRWhois +import logging + +log = logging.getLogger(__name__) + + +class IPWhois: + """ + The wrapper class for performing whois/RDAP lookups and parsing for + IPv4 and IPv6 addresses. + + Args: + address (:obj:`str`/:obj:`int`/:obj:`IPv4Address`/:obj:`IPv6Address`): + An IPv4 or IPv6 address + timeout (:obj:`int`): The default timeout for socket connections in + seconds. Defaults to 5. + proxy_opener (:obj:`urllib.request.OpenerDirector`): The request for + proxy support. Defaults to None. + allow_permutations (:obj:`bool`): Allow net.Net() to use additional + methods if DNS lookups to Cymru fail. *WARNING* deprecated in + favor of new argument asn_methods. Defaults to True. + """ + + def __init__(self, address, timeout=5, proxy_opener=None, + allow_permutations=True): + + self.net = Net( + address=address, timeout=timeout, proxy_opener=proxy_opener, + allow_permutations=allow_permutations + ) + self.ipasn = IPASN(self.net) + + self.address = self.net.address + self.timeout = self.net.timeout + self.address_str = self.net.address_str + self.version = self.net.version + self.reversed = self.net.reversed + self.dns_zone = self.net.dns_zone + + def __repr__(self): + + return 'IPWhois({0}, {1}, {2})'.format( + self.address_str, str(self.timeout), repr(self.net.opener) + ) + + def lookup_whois(self, inc_raw=False, retry_count=3, get_referral=False, + extra_blacklist=None, ignore_referral_errors=False, + field_list=None, asn_alts=None, extra_org_map=None, + inc_nir=True, nir_field_list=None, asn_methods=None, + get_asn_description=True): + """ + The function for retrieving and parsing whois information for an IP + address via port 43 (WHOIS). + + Args: + inc_raw (:obj:`bool`): Whether to include the raw whois results in + the returned dictionary. Defaults to False. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + get_referral (:obj:`bool`): Whether to retrieve referral whois + information, if available. Defaults to False. + extra_blacklist (:obj:`list`): Blacklisted whois servers in + addition to the global BLACKLIST. Defaults to None. + ignore_referral_errors (:obj:`bool`): Whether to ignore and + continue when an exception is encountered on referral whois + lookups. Defaults to False. + field_list (:obj:`list`): If provided, a list of fields to parse: + ['name', 'handle', 'description', 'country', 'state', 'city', + 'address', 'postal_code', 'emails', 'created', 'updated'] + If None, defaults to all. + asn_alts (:obj:`list`): Additional lookup types to attempt if the + ASN dns lookup fails. Allow permutations must be enabled. + If None, defaults to all ['whois', 'http']. *WARNING* + deprecated in favor of new argument asn_methods. + extra_org_map (:obj:`dict`): Dictionary mapping org handles to + RIRs. This is for limited cases where ARIN REST (ASN fallback + HTTP lookup) does not show an RIR as the org handle e.g., DNIC + (which is now the built in ORG_MAP) e.g., {'DNIC': 'arin'}. + Valid RIR values are (note the case-sensitive - this is meant + to match the REST result): + 'ARIN', 'RIPE', 'apnic', 'lacnic', 'afrinic' + Defaults to None. + inc_nir (:obj:`bool`): Whether to retrieve NIR (National Internet + Registry) information, if registry is JPNIC (Japan) or KRNIC + (Korea). If True, extra network requests will be required. + If False, the information returned for JP or KR IPs is + severely restricted. Defaults to True. + nir_field_list (:obj:`list`): If provided and inc_nir, a list of + fields to parse: + ['name', 'handle', 'country', 'address', 'postal_code', + 'nameservers', 'created', 'updated', 'contacts'] + If None, defaults to all. + asn_methods (:obj:`list`): ASN lookup types to attempt, in order. + If None, defaults to all ['dns', 'whois', 'http']. + get_asn_description (:obj:`bool`): Whether to run an additional + query when pulling ASN information via dns, in order to get + the ASN description. Defaults to True. + + Returns: + dict: The IP whois lookup results + + :: + + { + 'query' (str) - The IP address + 'asn' (str) - The Autonomous System Number + 'asn_date' (str) - The ASN Allocation date + 'asn_registry' (str) - The assigned ASN registry + 'asn_cidr' (str) - The assigned ASN CIDR + 'asn_country_code' (str) - The assigned ASN country code + 'asn_description' (str) - The ASN description + 'nets' (list) - Dictionaries containing network + information which consists of the fields listed in the + ipwhois.whois.RIR_WHOIS dictionary. + 'raw' (str) - Raw whois results if the inc_raw parameter + is True. + 'referral' (dict) - Referral whois information if + get_referral is True and the server is not blacklisted. + Consists of fields listed in the ipwhois.whois.RWHOIS + dictionary. + 'raw_referral' (str) - Raw referral whois results if the + inc_raw parameter is True. + 'nir' (dict) - ipwhois.nir.NIRWhois() results if inc_nir + is True. + } + """ + + from .whois import Whois + + # Create the return dictionary. + results = {'nir': None} + + # Retrieve the ASN information. + log.debug('ASN lookup for {0}'.format(self.address_str)) + + asn_data = self.ipasn.lookup( + inc_raw=inc_raw, retry_count=retry_count, asn_alts=asn_alts, + extra_org_map=extra_org_map, asn_methods=asn_methods, + get_asn_description=get_asn_description + ) + + # Add the ASN information to the return dictionary. + results.update(asn_data) + + # Retrieve the whois data and parse. + whois = Whois(self.net) + log.debug('WHOIS lookup for {0}'.format(self.address_str)) + whois_data = whois.lookup( + inc_raw=inc_raw, retry_count=retry_count, response=None, + get_referral=get_referral, extra_blacklist=extra_blacklist, + ignore_referral_errors=ignore_referral_errors, asn_data=asn_data, + field_list=field_list + ) + + # Add the WHOIS information to the return dictionary. + results.update(whois_data) + + if inc_nir: + + nir = None + if 'JP' == asn_data['asn_country_code']: + nir = 'jpnic' + elif 'KR' == asn_data['asn_country_code']: + nir = 'krnic' + + if nir: + + nir_whois = NIRWhois(self.net) + nir_data = nir_whois.lookup( + nir=nir, inc_raw=inc_raw, retry_count=retry_count, + response=None, + field_list=nir_field_list, is_offline=False + ) + + # Add the NIR information to the return dictionary. + results['nir'] = nir_data + + return results + + def lookup_rdap(self, inc_raw=False, retry_count=3, depth=0, + excluded_entities=None, bootstrap=False, + rate_limit_timeout=120, asn_alts=None, extra_org_map=None, + inc_nir=True, nir_field_list=None, asn_methods=None, + get_asn_description=True): + """ + The function for retrieving and parsing whois information for an IP + address via HTTP (RDAP). + + **This is now the recommended method, as RDAP contains much better + information to parse.** + + Args: + inc_raw (:obj:`bool`): Whether to include the raw whois results in + the returned dictionary. Defaults to False. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + depth (:obj:`int`): How many levels deep to run queries when + additional referenced objects are found. Defaults to 0. + excluded_entities (:obj:`list`): Entity handles to not perform + lookups. Defaults to None. + bootstrap (:obj:`bool`): If True, performs lookups via ARIN + bootstrap rather than lookups based on ASN data. ASN lookups + are not performed and no output for any of the asn* fields is + provided. Defaults to False. + rate_limit_timeout (:obj:`int`): The number of seconds to wait + before retrying when a rate limit notice is returned via + rdap+json. Defaults to 120. + asn_alts (:obj:`list`): Additional lookup types to attempt if the + ASN dns lookup fails. Allow permutations must be enabled. + If None, defaults to all ['whois', 'http']. *WARNING* + deprecated in favor of new argument asn_methods. + extra_org_map (:obj:`dict`): Dictionary mapping org handles to + RIRs. This is for limited cases where ARIN REST (ASN fallback + HTTP lookup) does not show an RIR as the org handle e.g., DNIC + (which is now the built in ORG_MAP) e.g., {'DNIC': 'arin'}. + Valid RIR values are (note the case-sensitive - this is meant + to match the REST result): + 'ARIN', 'RIPE', 'apnic', 'lacnic', 'afrinic' + Defaults to None. + inc_nir (:obj:`bool`): Whether to retrieve NIR (National Internet + Registry) information, if registry is JPNIC (Japan) or KRNIC + (Korea). If True, extra network requests will be required. + If False, the information returned for JP or KR IPs is + severely restricted. Defaults to True. + nir_field_list (:obj:`list`): If provided and inc_nir, a list of + fields to parse: + ['name', 'handle', 'country', 'address', 'postal_code', + 'nameservers', 'created', 'updated', 'contacts'] + If None, defaults to all. + asn_methods (:obj:`list`): ASN lookup types to attempt, in order. + If None, defaults to all ['dns', 'whois', 'http']. + get_asn_description (:obj:`bool`): Whether to run an additional + query when pulling ASN information via dns, in order to get + the ASN description. Defaults to True. + + Returns: + dict: The IP RDAP lookup results + + :: + + { + 'query' (str) - The IP address + 'asn' (str) - The Autonomous System Number + 'asn_date' (str) - The ASN Allocation date + 'asn_registry' (str) - The assigned ASN registry + 'asn_cidr' (str) - The assigned ASN CIDR + 'asn_country_code' (str) - The assigned ASN country code + 'asn_description' (str) - The ASN description + 'entities' (list) - Entity handles referred by the top + level query. + 'network' (dict) - Network information which consists of + the fields listed in the ipwhois.rdap._RDAPNetwork + dict. + 'objects' (dict) - Mapping of entity handle->entity dict + which consists of the fields listed in the + ipwhois.rdap._RDAPEntity dict. The raw result is + included for each object if the inc_raw parameter + is True. + 'raw' (dict) - Whois results in json format if the inc_raw + parameter is True. + 'nir' (dict) - ipwhois.nir.NIRWhois results if inc_nir is + True. + } + """ + + from .rdap import RDAP + + # Create the return dictionary. + results = {'nir': None} + + asn_data = None + response = None + if not bootstrap: + + # Retrieve the ASN information. + log.debug('ASN lookup for {0}'.format(self.address_str)) + asn_data = self.ipasn.lookup( + inc_raw=inc_raw, retry_count=retry_count, asn_alts=asn_alts, + extra_org_map=extra_org_map, asn_methods=asn_methods, + get_asn_description=get_asn_description + ) + + # Add the ASN information to the return dictionary. + results.update(asn_data) + + # Retrieve the RDAP data and parse. + rdap = RDAP(self.net) + log.debug('RDAP lookup for {0}'.format(self.address_str)) + rdap_data = rdap.lookup( + inc_raw=inc_raw, retry_count=retry_count, asn_data=asn_data, + depth=depth, excluded_entities=excluded_entities, + response=response, bootstrap=bootstrap, + rate_limit_timeout=rate_limit_timeout + ) + + # Add the RDAP information to the return dictionary. + results.update(rdap_data) + + if inc_nir: + + nir = None + if 'JP' == asn_data['asn_country_code']: + nir = 'jpnic' + elif 'KR' == asn_data['asn_country_code']: + nir = 'krnic' + + if nir: + nir_whois = NIRWhois(self.net) + nir_data = nir_whois.lookup( + nir=nir, inc_raw=inc_raw, retry_count=retry_count, + response=None, + field_list=nir_field_list, is_offline=False + ) + + # Add the NIR information to the return dictionary. + results['nir'] = nir_data + + return results diff --git a/env/lib/python3.7/site-packages/ipwhois/net.py b/env/lib/python3.7/site-packages/ipwhois/net.py new file mode 100644 index 0000000..01cbe3d --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/net.py @@ -0,0 +1,954 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import sys +import socket +import dns.resolver +import json +from collections import namedtuple +import logging +from time import sleep + +# Import the dnspython rdtypes to fix the dynamic import problem when frozen. +import dns.rdtypes.ANY.TXT # @UnusedImport + +from .exceptions import (IPDefinedError, ASNLookupError, BlacklistError, + WhoisLookupError, HTTPLookupError, HostLookupError, + HTTPRateLimitError, WhoisRateLimitError) +from .whois import RIR_WHOIS +from .asn import ASN_ORIGIN_WHOIS +from .utils import ipv4_is_defined, ipv6_is_defined + +if sys.version_info >= (3, 3): # pragma: no cover + from ipaddress import (ip_address, + IPv4Address, + IPv6Address) +else: # pragma: no cover + from ipaddr import (IPAddress as ip_address, + IPv4Address, + IPv6Address) + +try: # pragma: no cover + from urllib.request import (OpenerDirector, + ProxyHandler, + build_opener, + Request, + URLError, + HTTPError) + from urllib.parse import urlencode +except ImportError: # pragma: no cover + from urllib2 import (OpenerDirector, + ProxyHandler, + build_opener, + Request, + URLError, + HTTPError) + from urllib import urlencode + +log = logging.getLogger(__name__) + +# POSSIBLY UPDATE TO USE RDAP +ARIN = 'http://whois.arin.net/rest/nets;q={0}?showDetails=true&showARIN=true' + +CYMRU_WHOIS = 'whois.cymru.com' + +IPV4_DNS_ZONE = '{0}.origin.asn.cymru.com' + +IPV6_DNS_ZONE = '{0}.origin6.asn.cymru.com' + +BLACKLIST = [ + 'root.rwhois.net' +] + +ORG_MAP = { + 'ARIN': 'arin', + 'VR-ARIN': 'arin', + 'RIPE': 'ripencc', + 'APNIC': 'apnic', + 'LACNIC': 'lacnic', + 'AFRINIC': 'afrinic', + 'DNIC': 'arin' +} + + +class Net: + """ + The class for performing network queries. + + Args: + address (:obj:`str`/:obj:`int`/:obj:`IPv4Address`/:obj:`IPv6Address`): + An IPv4 or IPv6 address + timeout (:obj:`int`): The default timeout for socket connections in + seconds. Defaults to 5. + proxy_opener (:obj:`urllib.request.OpenerDirector`): The request for + proxy support. Defaults to None. + allow_permutations (:obj:`bool`): Allow net.Net() to use additional + methods if DNS lookups to Cymru fail. *WARNING* deprecated in + favor of new argument asn_methods. Defaults to True. + + Raises: + IPDefinedError: The address provided is defined (does not need to be + resolved). + """ + + def __init__(self, address, timeout=5, proxy_opener=None, + allow_permutations=True): + + # IPv4Address or IPv6Address + if isinstance(address, IPv4Address) or isinstance( + address, IPv6Address): + + self.address = address + + else: + + # Use ipaddress package exception handling. + self.address = ip_address(address) + + # Default timeout for socket connections. + self.timeout = timeout + + # Allow other than DNS lookups for ASNs. + self.allow_permutations = allow_permutations + + if self.allow_permutations: + + from warnings import warn + warn('allow_permutations has been deprecated and will be removed. ' + 'It is no longer needed, due to the deprecation of asn_alts, ' + 'and the addition of the asn_methods argument.') + + self.dns_resolver = dns.resolver.Resolver() + self.dns_resolver.timeout = timeout + self.dns_resolver.lifetime = timeout + + # Proxy opener. + if isinstance(proxy_opener, OpenerDirector): + + self.opener = proxy_opener + + else: + + handler = ProxyHandler() + self.opener = build_opener(handler) + + # IP address in string format for use in queries. + self.address_str = self.address.__str__() + + # Determine the IP version, 4 or 6 + self.version = self.address.version + + if self.version == 4: + + # Check if no ASN/whois resolution needs to occur. + is_defined = ipv4_is_defined(self.address_str) + + if is_defined[0]: + + raise IPDefinedError( + 'IPv4 address {0} is already defined as {1} via ' + '{2}.'.format( + self.address_str, is_defined[1], is_defined[2] + ) + ) + + # Reverse the IPv4Address for the DNS ASN query. + split = self.address_str.split('.') + split.reverse() + self.reversed = '.'.join(split) + + self.dns_zone = IPV4_DNS_ZONE.format(self.reversed) + + else: + + # Check if no ASN/whois resolution needs to occur. + is_defined = ipv6_is_defined(self.address_str) + + if is_defined[0]: + + raise IPDefinedError( + 'IPv6 address {0} is already defined as {1} via ' + '{2}.'.format( + self.address_str, is_defined[1], is_defined[2] + ) + ) + + # Explode the IPv6Address to fill in any missing 0's. + exploded = self.address.exploded + + # Cymru seems to timeout when the IPv6 address has trailing '0000' + # groups. Remove these groups. + groups = exploded.split(':') + for index, value in reversed(list(enumerate(groups))): + + if value == '0000': + + del groups[index] + + else: + + break + + exploded = ':'.join(groups) + + # Reverse the IPv6Address for the DNS ASN query. + val = str(exploded).replace(':', '') + val = val[::-1] + self.reversed = '.'.join(val) + + self.dns_zone = IPV6_DNS_ZONE.format(self.reversed) + + def lookup_asn(self, *args, **kwargs): + """ + Temporary wrapper for IP ASN lookups (moved to + asn.IPASN.lookup()). This will be removed in a future + release (1.0.0). + """ + + from warnings import warn + warn('Net.lookup_asn() has been deprecated and will be removed. ' + 'You should now use asn.IPASN.lookup() for IP ASN lookups.') + from .asn import IPASN + response = None + ipasn = IPASN(self) + return ipasn.lookup(*args, **kwargs), response + + def get_asn_dns(self): + """ + The function for retrieving ASN information for an IP address from + Cymru via port 53 (DNS). + + Returns: + list: The raw ASN data. + + Raises: + ASNLookupError: The ASN lookup failed. + """ + + try: + + log.debug('ASN query for {0}'.format(self.dns_zone)) + data = self.dns_resolver.query(self.dns_zone, 'TXT') + return list(data) + + except (dns.resolver.NXDOMAIN, dns.resolver.NoNameservers, + dns.resolver.NoAnswer, dns.exception.Timeout) as e: + + raise ASNLookupError( + 'ASN lookup failed (DNS {0}) for {1}.'.format( + e.__class__.__name__, self.address_str) + ) + + except: # pragma: no cover + + raise ASNLookupError( + 'ASN lookup failed for {0}.'.format(self.address_str) + ) + + def get_asn_verbose_dns(self, asn=None): + """ + The function for retrieving the information for an ASN from + Cymru via port 53 (DNS). This is needed since IP to ASN mapping via + Cymru DNS does not return the ASN Description like Cymru Whois does. + + Args: + asn (:obj:`str`): The AS number (required). + + Returns: + str: The raw ASN data. + + Raises: + ASNLookupError: The ASN lookup failed. + """ + + if asn[0:2] != 'AS': + + asn = 'AS{0}'.format(asn) + + zone = '{0}.asn.cymru.com'.format(asn) + + try: + + log.debug('ASN verbose query for {0}'.format(zone)) + data = self.dns_resolver.query(zone, 'TXT') + return str(data[0]) + + except (dns.resolver.NXDOMAIN, dns.resolver.NoNameservers, + dns.resolver.NoAnswer, dns.exception.Timeout) as e: + + raise ASNLookupError( + 'ASN lookup failed (DNS {0}) for {1}.'.format( + e.__class__.__name__, asn) + ) + + except: # pragma: no cover + + raise ASNLookupError( + 'ASN lookup failed for {0}.'.format(asn) + ) + + def get_asn_whois(self, retry_count=3): + """ + The function for retrieving ASN information for an IP address from + Cymru via port 43/tcp (WHOIS). + + Args: + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + + Returns: + str: The raw ASN data. + + Raises: + ASNLookupError: The ASN lookup failed. + """ + + try: + + # Create the connection for the Cymru whois query. + conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + conn.settimeout(self.timeout) + log.debug('ASN query for {0}'.format(self.address_str)) + conn.connect((CYMRU_WHOIS, 43)) + + # Query the Cymru whois server, and store the results. + conn.send(( + ' -r -a -c -p -f {0}{1}'.format( + self.address_str, '\r\n') + ).encode()) + + data = '' + while True: + + d = conn.recv(4096).decode() + data += d + + if not d: + + break + + conn.close() + + return str(data) + + except (socket.timeout, socket.error) as e: # pragma: no cover + + log.debug('ASN query socket error: {0}'.format(e)) + if retry_count > 0: + + log.debug('ASN query retrying (count: {0})'.format( + str(retry_count))) + return self.get_asn_whois(retry_count - 1) + + else: + + raise ASNLookupError( + 'ASN lookup failed for {0}.'.format(self.address_str) + ) + + except: # pragma: no cover + + raise ASNLookupError( + 'ASN lookup failed for {0}.'.format(self.address_str) + ) + + def get_asn_http(self, retry_count=3): + """ + The function for retrieving ASN information for an IP address from + Arin via port 80 (HTTP). Currently limited to fetching asn_registry + through a Arin whois (REST) lookup. The other values are returned as + None to keep a consistent dict output. This should be used as a last + chance fallback call behind ASN DNS & ASN Whois lookups. + + Args: + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + + Returns: + dict: The ASN data in json format. + + Raises: + ASNLookupError: The ASN lookup failed. + """ + + try: + + # Lets attempt to get the ASN registry information from + # ARIN. + log.debug('ASN query for {0}'.format(self.address_str)) + response = self.get_http_json( + url=str(ARIN).format(self.address_str), + retry_count=retry_count, + headers={'Accept': 'application/json'} + ) + + return response + + except (socket.timeout, socket.error) as e: # pragma: no cover + + log.debug('ASN query socket error: {0}'.format(e)) + if retry_count > 0: + + log.debug('ASN query retrying (count: {0})'.format( + str(retry_count))) + return self.get_asn_http(retry_count=retry_count-1) + + else: + + raise ASNLookupError( + 'ASN lookup failed for {0}.'.format(self.address_str) + ) + + except: + + raise ASNLookupError( + 'ASN lookup failed for {0}.'.format(self.address_str) + ) + + def get_asn_origin_whois(self, asn_registry='radb', asn=None, + retry_count=3, server=None, port=43): + """ + The function for retrieving CIDR info for an ASN via whois. + + Args: + asn_registry (:obj:`str`): The source to run the query against + (asn.ASN_ORIGIN_WHOIS). + asn (:obj:`str`): The AS number (required). + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + server (:obj:`str`): An optional server to connect to. + port (:obj:`int`): The network port to connect on. Defaults to 43. + + Returns: + str: The raw ASN origin whois data. + + Raises: + WhoisLookupError: The ASN origin whois lookup failed. + WhoisRateLimitError: The ASN origin Whois request rate limited and + retries were exhausted. + """ + + try: + + if server is None: + server = ASN_ORIGIN_WHOIS[asn_registry]['server'] + + # Create the connection for the whois query. + conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + conn.settimeout(self.timeout) + log.debug('ASN origin WHOIS query for {0} at {1}:{2}'.format( + asn, server, port)) + conn.connect((server, port)) + + # Prep the query. + query = ' -i origin {0}{1}'.format(asn, '\r\n') + + # Query the whois server, and store the results. + conn.send(query.encode()) + + response = '' + while True: + + d = conn.recv(4096).decode() + + response += d + + if not d: + + break + + conn.close() + + # TODO: this was taken from get_whois(). Need to test rate limiting + if 'Query rate limit exceeded' in response: # pragma: no cover + + if retry_count > 0: + + log.debug('ASN origin WHOIS query rate limit exceeded. ' + 'Waiting...') + sleep(1) + return self.get_asn_origin_whois( + asn_registry=asn_registry, asn=asn, + retry_count=retry_count-1, + server=server, port=port + ) + + else: + + raise WhoisRateLimitError( + 'ASN origin Whois lookup failed for {0}. Rate limit ' + 'exceeded, wait and try again (possibly a ' + 'temporary block).'.format(asn)) + + elif ('error 501' in response or 'error 230' in response + ): # pragma: no cover + + log.debug('ASN origin WHOIS query error: {0}'.format(response)) + raise ValueError + + return str(response) + + except (socket.timeout, socket.error) as e: + + log.debug('ASN origin WHOIS query socket error: {0}'.format(e)) + if retry_count > 0: + + log.debug('ASN origin WHOIS query retrying (count: {0})' + ''.format(str(retry_count))) + return self.get_asn_origin_whois( + asn_registry=asn_registry, asn=asn, + retry_count=retry_count-1, server=server, port=port + ) + + else: + + raise WhoisLookupError( + 'ASN origin WHOIS lookup failed for {0}.'.format(asn) + ) + + except WhoisRateLimitError: # pragma: no cover + + raise + + except: # pragma: no cover + + raise WhoisLookupError( + 'ASN origin WHOIS lookup failed for {0}.'.format(asn) + ) + + def get_whois(self, asn_registry='arin', retry_count=3, server=None, + port=43, extra_blacklist=None): + """ + The function for retrieving whois or rwhois information for an IP + address via any port. Defaults to port 43/tcp (WHOIS). + + Args: + asn_registry (:obj:`str`): The NIC to run the query against. + Defaults to 'arin'. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + server (:obj:`str`): An optional server to connect to. If + provided, asn_registry will be ignored. + port (:obj:`int`): The network port to connect on. Defaults to 43. + extra_blacklist (:obj:`list` of :obj:`str`): Blacklisted whois + servers in addition to the global BLACKLIST. Defaults to None. + + Returns: + str: The raw whois data. + + Raises: + BlacklistError: Raised if the whois server provided is in the + global BLACKLIST or extra_blacklist. + WhoisLookupError: The whois lookup failed. + WhoisRateLimitError: The Whois request rate limited and retries + were exhausted. + """ + + try: + + extra_bl = extra_blacklist if extra_blacklist else [] + + if any(server in srv for srv in (BLACKLIST, extra_bl)): + raise BlacklistError( + 'The server {0} is blacklisted.'.format(server) + ) + + if server is None: + server = RIR_WHOIS[asn_registry]['server'] + + # Create the connection for the whois query. + conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + conn.settimeout(self.timeout) + log.debug('WHOIS query for {0} at {1}:{2}'.format( + self.address_str, server, port)) + conn.connect((server, port)) + + # Prep the query. + query = self.address_str + '\r\n' + if asn_registry == 'arin': + + query = 'n + {0}'.format(query) + + # Query the whois server, and store the results. + conn.send(query.encode()) + + response = '' + while True: + + d = conn.recv(4096).decode('ascii', 'ignore') + + response += d + + if not d: + + break + + conn.close() + + if 'Query rate limit exceeded' in response: # pragma: no cover + + if retry_count > 0: + + log.debug('WHOIS query rate limit exceeded. Waiting...') + sleep(1) + return self.get_whois( + asn_registry=asn_registry, retry_count=retry_count-1, + server=server, port=port, + extra_blacklist=extra_blacklist + ) + + else: + + raise WhoisRateLimitError( + 'Whois lookup failed for {0}. Rate limit ' + 'exceeded, wait and try again (possibly a ' + 'temporary block).'.format(self.address_str)) + + elif ('error 501' in response or 'error 230' in response + ): # pragma: no cover + + log.debug('WHOIS query error: {0}'.format(response)) + raise ValueError + + return str(response) + + except (socket.timeout, socket.error) as e: + + log.debug('WHOIS query socket error: {0}'.format(e)) + if retry_count > 0: + + log.debug('WHOIS query retrying (count: {0})'.format( + str(retry_count))) + return self.get_whois( + asn_registry=asn_registry, retry_count=retry_count-1, + server=server, port=port, extra_blacklist=extra_blacklist + ) + + else: + + raise WhoisLookupError( + 'WHOIS lookup failed for {0}.'.format(self.address_str) + ) + + except WhoisRateLimitError: # pragma: no cover + + raise + + except BlacklistError: + + raise + + except: # pragma: no cover + + raise WhoisLookupError( + 'WHOIS lookup failed for {0}.'.format(self.address_str) + ) + + def get_http_json(self, url=None, retry_count=3, rate_limit_timeout=120, + headers=None): + """ + The function for retrieving a json result via HTTP. + + Args: + url (:obj:`str`): The URL to retrieve (required). + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + rate_limit_timeout (:obj:`int`): The number of seconds to wait + before retrying when a rate limit notice is returned via + rdap+json or HTTP error 429. Defaults to 60. + headers (:obj:`dict`): The HTTP headers. The Accept header + defaults to 'application/rdap+json'. + + Returns: + dict: The data in json format. + + Raises: + HTTPLookupError: The HTTP lookup failed. + HTTPRateLimitError: The HTTP request rate limited and retries + were exhausted. + """ + + if headers is None: + headers = {'Accept': 'application/rdap+json'} + + try: + + # Create the connection for the whois query. + log.debug('HTTP query for {0} at {1}'.format( + self.address_str, url)) + conn = Request(url, headers=headers) + data = self.opener.open(conn, timeout=self.timeout) + try: + d = json.loads(data.readall().decode('utf-8', 'ignore')) + except AttributeError: # pragma: no cover + d = json.loads(data.read().decode('utf-8', 'ignore')) + + try: + # Tests written but commented out. I do not want to send a + # flood of requests on every test. + for tmp in d['notices']: # pragma: no cover + if tmp['title'] == 'Rate Limit Notice': + log.debug('RDAP query rate limit exceeded.') + + if retry_count > 0: + log.debug('Waiting {0} seconds...'.format( + str(rate_limit_timeout))) + + sleep(rate_limit_timeout) + return self.get_http_json( + url=url, retry_count=retry_count-1, + rate_limit_timeout=rate_limit_timeout, + headers=headers + ) + else: + raise HTTPRateLimitError( + 'HTTP lookup failed for {0}. Rate limit ' + 'exceeded, wait and try again (possibly a ' + 'temporary block).'.format(url)) + + except (KeyError, IndexError): # pragma: no cover + + pass + + return d + + except HTTPError as e: # pragma: no cover + + # RIPE is producing this HTTP error rather than a JSON error. + if e.code == 429: + + log.debug('HTTP query rate limit exceeded.') + + if retry_count > 0: + log.debug('Waiting {0} seconds...'.format( + str(rate_limit_timeout))) + + sleep(rate_limit_timeout) + return self.get_http_json( + url=url, retry_count=retry_count - 1, + rate_limit_timeout=rate_limit_timeout, + headers=headers + ) + else: + raise HTTPRateLimitError( + 'HTTP lookup failed for {0}. Rate limit ' + 'exceeded, wait and try again (possibly a ' + 'temporary block).'.format(url)) + + else: + + raise HTTPLookupError('HTTP lookup failed for {0} with error ' + 'code {1}.'.format(url, str(e.code))) + + except (URLError, socket.timeout, socket.error) as e: + + # Check needed for Python 2.6, also why URLError is caught. + try: # pragma: no cover + if not isinstance(e.reason, (socket.timeout, socket.error)): + raise HTTPLookupError('HTTP lookup failed for {0}.' + ''.format(url)) + except AttributeError: # pragma: no cover + + pass + + log.debug('HTTP query socket error: {0}'.format(e)) + if retry_count > 0: + + log.debug('HTTP query retrying (count: {0})'.format( + str(retry_count))) + + return self.get_http_json( + url=url, retry_count=retry_count-1, + rate_limit_timeout=rate_limit_timeout, headers=headers + ) + + else: + + raise HTTPLookupError('HTTP lookup failed for {0}.'.format( + url)) + + except (HTTPLookupError, HTTPRateLimitError) as e: # pragma: no cover + + raise e + + except: # pragma: no cover + + raise HTTPLookupError('HTTP lookup failed for {0}.'.format(url)) + + def get_host(self, retry_count=3): + """ + The function for retrieving host information for an IP address. + + Args: + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + + Returns: + namedtuple: + + :hostname (str): The hostname returned mapped to the given IP + address. + :aliaslist (list): Alternate names for the given IP address. + :ipaddrlist (list): IPv4/v6 addresses mapped to the same hostname. + + Raises: + HostLookupError: The host lookup failed. + """ + + try: + + default_timeout_set = False + if not socket.getdefaulttimeout(): + + socket.setdefaulttimeout(self.timeout) + default_timeout_set = True + + log.debug('Host query for {0}'.format(self.address_str)) + ret = socket.gethostbyaddr(self.address_str) + + if default_timeout_set: # pragma: no cover + + socket.setdefaulttimeout(None) + + results = namedtuple('get_host_results', 'hostname, aliaslist, ' + 'ipaddrlist') + return results(ret) + + except (socket.timeout, socket.error) as e: + + log.debug('Host query socket error: {0}'.format(e)) + if retry_count > 0: + + log.debug('Host query retrying (count: {0})'.format( + str(retry_count))) + + return self.get_host(retry_count - 1) + + else: + + raise HostLookupError( + 'Host lookup failed for {0}.'.format(self.address_str) + ) + + except: # pragma: no cover + + raise HostLookupError( + 'Host lookup failed for {0}.'.format(self.address_str) + ) + + def get_http_raw(self, url=None, retry_count=3, headers=None, + request_type='GET', form_data=None): + """ + The function for retrieving a raw HTML result via HTTP. + + Args: + url (:obj:`str`): The URL to retrieve (required). + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + headers (:obj:`dict`): The HTTP headers. The Accept header + defaults to 'text/html'. + request_type (:obj:`str`): Request type 'GET' or 'POST'. Defaults + to 'GET'. + form_data (:obj:`dict`): Optional form POST data. + + Returns: + str: The raw data. + + Raises: + HTTPLookupError: The HTTP lookup failed. + """ + + if headers is None: + headers = {'Accept': 'text/html'} + + enc_form_data = None + if form_data: + enc_form_data = urlencode(form_data) + try: + # Py 2 inspection will alert on the encoding arg, no harm done. + enc_form_data = bytes(enc_form_data, encoding='ascii') + except TypeError: # pragma: no cover + pass + + try: + + # Create the connection for the HTTP query. + log.debug('HTTP query for {0} at {1}'.format( + self.address_str, url)) + try: + # Py 2 inspection alert bypassed by using kwargs dict. + conn = Request(url=url, data=enc_form_data, headers=headers, + **{'method': request_type}) + except TypeError: # pragma: no cover + conn = Request(url=url, data=enc_form_data, headers=headers) + data = self.opener.open(conn, timeout=self.timeout) + + try: + d = data.readall().decode('ascii', 'ignore') + except AttributeError: # pragma: no cover + d = data.read().decode('ascii', 'ignore') + + return str(d) + + except (URLError, socket.timeout, socket.error) as e: + + # Check needed for Python 2.6, also why URLError is caught. + try: # pragma: no cover + if not isinstance(e.reason, (socket.timeout, socket.error)): + raise HTTPLookupError('HTTP lookup failed for {0}.' + ''.format(url)) + except AttributeError: # pragma: no cover + + pass + + log.debug('HTTP query socket error: {0}'.format(e)) + if retry_count > 0: + + log.debug('HTTP query retrying (count: {0})'.format( + str(retry_count))) + + return self.get_http_raw( + url=url, retry_count=retry_count - 1, headers=headers, + request_type=request_type, form_data=form_data + ) + + else: + + raise HTTPLookupError('HTTP lookup failed for {0}.'.format( + url)) + + except HTTPLookupError as e: # pragma: no cover + + raise e + + except Exception: # pragma: no cover + + raise HTTPLookupError('HTTP lookup failed for {0}.'.format(url)) diff --git a/env/lib/python3.7/site-packages/ipwhois/nir.py b/env/lib/python3.7/site-packages/ipwhois/nir.py new file mode 100644 index 0000000..e04fcde --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/nir.py @@ -0,0 +1,682 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from . import NetError +from .utils import unique_everseen +import logging +import sys +import re +import copy +from datetime import (datetime, timedelta) + +if sys.version_info >= (3, 3): # pragma: no cover + from ipaddress import (ip_address, + ip_network, + summarize_address_range, + collapse_addresses) +else: # pragma: no cover + from ipaddr import (IPAddress as ip_address, + IPNetwork as ip_network, + summarize_address_range, + collapse_address_list as collapse_addresses) + +log = logging.getLogger(__name__) + +# Base NIR whois output dictionary. +BASE_NET = { + 'cidr': None, + 'name': None, + 'handle': None, + 'range': None, + 'country': None, + 'address': None, + 'postal_code': None, + 'nameservers': None, + 'created': None, + 'updated': None, + 'contacts': None +} + +# Base NIR whois contact output dictionary. +BASE_CONTACT = { + 'name': None, + 'email': None, + 'reply_email': None, + 'organization': None, + 'division': None, + 'title': None, + 'phone': None, + 'fax': None, + 'updated': None +} + +# National Internet Registry +NIR_WHOIS = { + 'jpnic': { + 'country_code': 'JP', + 'url': ('http://whois.nic.ad.jp/cgi-bin/whois_gw?lang=%2Fe&key={0}' + '&submit=query'), + 'request_type': 'GET', + 'request_headers': {'Accept': 'text/html'}, + 'form_data_ip_field': None, + 'fields': { + 'name': r'(\[Organization\])[^\S\n]+(?P.*?)\n', + 'handle': r'(\[Network Name\])[^\S\n]+(?P.*?)\n', + 'created': r'(\[Assigned Date\])[^\S\n]+(?P.*?)\n', + 'updated': r'(\[Last Update\])[^\S\n]+(?P.*?)\n', + 'nameservers': r'(\[Nameserver\])[^\S\n]+(?P.*?)\n', + 'contact_admin': r'(\[Administrative Contact\])[^\S\n]+.+?\>' + '(?P.+?)\<\/A\>\n', + 'contact_tech': r'(\[Technical Contact\])[^\S\n]+.+?\>' + '(?P.+?)\<\/A\>\n' + }, + 'contact_fields': { + 'name': r'(\[Last, First\])[^\S\n]+(?P.*?)\n', + 'email': r'(\[E-Mail\])[^\S\n]+(?P.*?)\n', + 'reply_email': r'(\[Reply Mail\])[^\S\n]+(?P.*?)\n', + 'organization': r'(\[Organization\])[^\S\n]+(?P.*?)\n', + 'division': r'(\[Division\])[^\S\n]+(?P.*?)\n', + 'title': r'(\[Title\])[^\S\n]+(?P.*?)\n', + 'phone': r'(\[TEL\])[^\S\n]+(?P.*?)\n', + 'fax': r'(\[FAX\])[^\S\n]+(?P.*?)\n', + 'updated': r'(\[Last Update\])[^\S\n]+(?P.*?)\n' + }, + 'dt_format': '%Y/%m/%d %H:%M:%S(JST)', + 'dt_hourdelta': 9, + 'multi_net': False + }, + 'krnic': { + 'country_code': 'KR', + 'url': 'https://whois.kisa.or.kr/eng/whois.jsc', + 'request_type': 'POST', + 'request_headers': {'Accept': 'text/html'}, + 'form_data_ip_field': 'query', + 'fields': { + 'name': r'(Organization Name)[\s]+\:[^\S\n]+(?P.+?)\n', + 'handle': r'(Service Name|Network Type)[\s]+\:[^\S\n]+(?P.+?)' + '\n', + 'address': r'(Address)[\s]+\:[^\S\n]+(?P.+?)\n', + 'postal_code': r'(Zip Code)[\s]+\:[^\S\n]+(?P.+?)\n', + 'created': r'(Registration Date)[\s]+\:[^\S\n]+(?P.+?)\n', + 'contact_admin': r'(id="eng_isp_contact").+?\>(?P.*?)\<' + '\/div\>\n', + 'contact_tech': r'(id="eng_user_contact").+?\>(?P.*?)\<' + '\/div\>\n' + }, + 'contact_fields': { + 'name': r'(Name)[^\S\n]+?:[^\S\n]+?(?P.*?)\n', + 'email': r'(E-Mail)[^\S\n]+?:[^\S\n]+?(?P.*?)\n', + 'phone': r'(Phone)[^\S\n]+?:[^\S\n]+?(?P.*?)\n' + }, + 'dt_format': '%Y%m%d', + 'dt_hourdelta': 0, + 'multi_net': True + } +} + + +class NIRWhois: + """ + The class for parsing whois data for NIRs (National Internet Registry). + JPNIC and KRNIC are currently the only NIRs supported. Output varies + based on NIR specific whois formatting. + + Args: + net (:obj:`ipwhois.net.Net`): The network object. + + Raises: + NetError: The parameter provided is not an instance of + ipwhois.net.Net + IPDefinedError: The address provided is defined (does not need to be + resolved). + """ + + def __init__(self, net): + + from .net import Net + + # ipwhois.net.Net validation + if isinstance(net, Net): + + self._net = net + + else: + + raise NetError('The provided net parameter is not an instance of ' + 'ipwhois.net.Net') + + def parse_fields(self, response, fields_dict, net_start=None, + net_end=None, dt_format=None, field_list=None, + hourdelta=0, is_contact=False): + """ + The function for parsing whois fields from a data input. + + Args: + response (:obj:`str`): The response from the whois/rwhois server. + fields_dict (:obj:`dict`): The mapping of fields to regex search + values (required). + net_start (:obj:`int`): The starting point of the network (if + parsing multiple networks). Defaults to None. + net_end (:obj:`int`): The ending point of the network (if parsing + multiple networks). Defaults to None. + dt_format (:obj:`str`): The format of datetime fields if known. + Defaults to None. + field_list (:obj:`list` of :obj:`str`): If provided, fields to + parse. Defaults to :obj:`ipwhois.nir.BASE_NET` if is_contact + is False. Otherwise, defaults to + :obj:`ipwhois.nir.BASE_CONTACT`. + hourdelta (:obj:`int`): The timezone delta for created/updated + fields. Defaults to 0. + is_contact (:obj:`bool`): If True, uses contact information + field parsing. Defaults to False. + + Returns: + dict: A dictionary of fields provided in fields_dict, mapping to + the results of the regex searches. + """ + + response = '{0}\n'.format(response) + if is_contact: + + ret = {} + + if not field_list: + + field_list = list(BASE_CONTACT.keys()) + + else: + + ret = { + 'contacts': {'admin': None, 'tech': None}, + 'contact_admin': {}, + 'contact_tech': {} + } + + if not field_list: + + field_list = list(BASE_NET.keys()) + field_list.remove('contacts') + field_list.append('contact_admin') + field_list.append('contact_tech') + + generate = ((field, pattern) for (field, pattern) in + fields_dict.items() if field in field_list) + + for field, pattern in generate: + + pattern = re.compile( + str(pattern), + re.DOTALL + ) + + if net_start is not None: + + match = pattern.finditer(response, net_end, net_start) + + elif net_end is not None: + + match = pattern.finditer(response, net_end) + + else: + + match = pattern.finditer(response) + + values = [] + for m in match: + + try: + + values.append(m.group('val').strip()) + + except IndexError: + + pass + + if len(values) > 0: + + value = None + try: + + if field in ['created', 'updated'] and dt_format: + + value = ( + datetime.strptime( + values[0], + str(dt_format) + ) - timedelta(hours=hourdelta) + ).isoformat('T') + + elif field in ['nameservers']: + + value = list(unique_everseen(values)) + + else: + + values = unique_everseen(values) + value = '\n'.join(values) + + except ValueError as e: + + log.debug('NIR whois field parsing failed for {0}: {1}' + ''.format(field, e)) + pass + + ret[field] = value + + return ret + + def _parse_fields(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('NIRWhois._parse_fields() has been deprecated and will be ' + 'removed. You should now use NIRWhois.parse_fields().') + return self.parse_fields(*args, **kwargs) + + def get_nets_jpnic(self, response): + """ + The function for parsing network blocks from jpnic whois data. + + Args: + response (:obj:`str`): The response from the jpnic server. + + Returns: + list of dict: Mapping of networks with start and end positions. + + :: + + [{ + 'cidr' (str) - The network routing block + 'start' (int) - The starting point of the network + 'end' (int) - The endpoint point of the network + }] + """ + + nets = [] + + # Iterate through all of the networks found, storing the CIDR value + # and the start and end positions. + for match in re.finditer( + r'^.*?(\[Network Number\])[^\S\n]+.+?>(?P.+?)
    $', + response, + re.MULTILINE + ): + + try: + + net = copy.deepcopy(BASE_NET) + tmp = ip_network(match.group(2)) + + try: # pragma: no cover + network_address = tmp.network_address + except AttributeError: # pragma: no cover + network_address = tmp.ip + pass + + try: # pragma: no cover + broadcast_address = tmp.broadcast_address + except AttributeError: # pragma: no cover + broadcast_address = tmp.broadcast + pass + + net['range'] = '{0} - {1}'.format( + network_address + 1, broadcast_address + ) + + cidr = ip_network(match.group(2).strip()).__str__() + + net['cidr'] = cidr + net['start'] = match.start() + net['end'] = match.end() + nets.append(net) + + except (ValueError, TypeError): + + pass + + return nets + + def _get_nets_jpnic(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('NIRWhois._get_nets_jpnic() has been deprecated and will be ' + 'removed. You should now use NIRWhois.get_nets_jpnic().') + return self.get_nets_jpnic(*args, **kwargs) + + def get_nets_krnic(self, response): + """ + The function for parsing network blocks from krnic whois data. + + Args: + response (:obj:`str`): The response from the krnic server. + + Returns: + list of dict: Mapping of networks with start and end positions. + + :: + + [{ + 'cidr' (str) - The network routing block + 'start' (int) - The starting point of the network + 'end' (int) - The endpoint point of the network + }] + """ + + nets = [] + + # Iterate through all of the networks found, storing the CIDR value + # and the start and end positions. + for match in re.finditer( + r'^(IPv4 Address)[\s]+:[^\S\n]+((.+?)[^\S\n]-[^\S\n](.+?)' + '[^\S\n]\((.+?)\)|.+)$', + response, + re.MULTILINE + ): + + try: + + net = copy.deepcopy(BASE_NET) + net['range'] = match.group(2) + + if match.group(3) and match.group(4): + + addrs = [] + addrs.extend(summarize_address_range( + ip_address(match.group(3).strip()), + ip_address(match.group(4).strip()))) + + cidr = ', '.join( + [i.__str__() for i in collapse_addresses(addrs)] + ) + + net['range'] = '{0} - {1}'.format( + match.group(3), match.group(4) + ) + + else: + + cidr = ip_network(match.group(2).strip()).__str__() + + net['cidr'] = cidr + net['start'] = match.start() + net['end'] = match.end() + nets.append(net) + + except (ValueError, TypeError): + + pass + + return nets + + def _get_nets_krnic(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('NIRWhois._get_nets_krnic() has been deprecated and will be ' + 'removed. You should now use NIRWhois.get_nets_krnic().') + return self.get_nets_krnic(*args, **kwargs) + + def get_contact(self, response=None, nir=None, handle=None, + retry_count=3, dt_format=None): + """ + The function for retrieving and parsing NIR whois data based on + NIR_WHOIS contact_fields. + + Args: + response (:obj:`str`): Optional response object, this bypasses the + lookup. + nir (:obj:`str`): The NIR to query ('jpnic' or 'krnic'). Required + if response is None. + handle (:obj:`str`): For NIRs that have separate contact queries + (JPNIC), this is the contact handle to use in the query. + Defaults to None. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + dt_format (:obj:`str`): The format of datetime fields if known. + Defaults to None. + + Returns: + dict: Mapping of the fields provided in contact_fields, to their + parsed results. + """ + + if response or nir == 'krnic': + + contact_response = response + + else: + + # Retrieve the whois data. + contact_response = self._net.get_http_raw( + url=str(NIR_WHOIS[nir]['url']).format(handle), + retry_count=retry_count, + headers=NIR_WHOIS[nir]['request_headers'], + request_type=NIR_WHOIS[nir]['request_type'] + ) + + return self._parse_fields( + response=contact_response, + fields_dict=NIR_WHOIS[nir]['contact_fields'], + dt_format=dt_format, + hourdelta=int(NIR_WHOIS[nir]['dt_hourdelta']), + is_contact=True + ) + + def _get_contact(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('NIRWhois._get_contact() has been deprecated and will be ' + 'removed. You should now use NIRWhois.get_contact().') + return self.get_contact(*args, **kwargs) + + def lookup(self, nir=None, inc_raw=False, retry_count=3, response=None, + field_list=None, is_offline=False): + """ + The function for retrieving and parsing NIR whois information for an IP + address via HTTP (HTML scraping). + + Args: + nir (:obj:`str`): The NIR to query ('jpnic' or 'krnic'). Required + if response is None. + inc_raw (:obj:`bool`, optional): Whether to include the raw + results in the returned dictionary. Defaults to False. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + response (:obj:`str`): Optional response object, this bypasses the + NIR lookup. Required when is_offline=True. + field_list (:obj:`list` of :obj:`str`): If provided, fields to + parse. Defaults to :obj:`ipwhois.nir.BASE_NET`. + is_offline (:obj:`bool`): Whether to perform lookups offline. If + True, response and asn_data must be provided. Primarily used + for testing. + + Returns: + dict: The NIR whois results: + + :: + + { + 'query' (str) - The IP address. + 'nets' (list of dict) - Network information which consists + of the fields listed in the ipwhois.nir.NIR_WHOIS + dictionary. + 'raw' (str) - Raw NIR whois results if the inc_raw + parameter is True. + } + """ + + if nir not in NIR_WHOIS.keys(): + + raise KeyError('Invalid arg for nir (National Internet Registry') + + # Create the return dictionary. + results = { + 'query': self._net.address_str, + 'raw': None + } + + # Only fetch the response if we haven't already. + if response is None: + + if is_offline: + + raise KeyError('response argument required when ' + 'is_offline=True') + + log.debug('Response not given, perform WHOIS lookup for {0}' + .format(self._net.address_str)) + + form_data = None + if NIR_WHOIS[nir]['form_data_ip_field']: + form_data = {NIR_WHOIS[nir]['form_data_ip_field']: + self._net.address_str} + + # Retrieve the whois data. + response = self._net.get_http_raw( + url=str(NIR_WHOIS[nir]['url']).format(self._net.address_str), + retry_count=retry_count, + headers=NIR_WHOIS[nir]['request_headers'], + request_type=NIR_WHOIS[nir]['request_type'], + form_data=form_data + ) + + # If inc_raw parameter is True, add the response to return dictionary. + if inc_raw: + + results['raw'] = response + + nets = [] + nets_response = None + if nir == 'jpnic': + + nets_response = self._get_nets_jpnic(response) + + elif nir == 'krnic': + + nets_response = self._get_nets_krnic(response) + + nets.extend(nets_response) + + global_contacts = {} + + # Iterate through all of the network sections and parse out the + # appropriate fields for each. + log.debug('Parsing NIR WHOIS data') + for index, net in enumerate(nets): + + section_end = None + if index + 1 < len(nets): + section_end = nets[index + 1]['start'] + + try: + + dt_format = NIR_WHOIS[nir]['dt_format'] + + except KeyError: # pragma: no cover + + dt_format = None + + temp_net = self._parse_fields( + response=response, + fields_dict=NIR_WHOIS[nir]['fields'], + net_start=section_end, + net_end=net['end'], + dt_format=dt_format, + field_list=field_list, + hourdelta=int(NIR_WHOIS[nir]['dt_hourdelta']) + ) + temp_net['country'] = NIR_WHOIS[nir]['country_code'] + contacts = { + 'admin': temp_net['contact_admin'], + 'tech': temp_net['contact_tech'] + } + + del ( + temp_net['contact_admin'], + temp_net['contact_tech'] + ) + + if not is_offline: + + for key, val in contacts.items(): + + if len(val) > 0: + + if isinstance(val, str): + + val = val.splitlines() + + for contact in val: + + if contact in global_contacts.keys(): + + temp_net['contacts'][key] = ( + global_contacts[contact] + ) + + else: + + if nir == 'krnic': + + tmp_response = contact + tmp_handle = None + + else: + + tmp_response = None + tmp_handle = contact + + temp_net['contacts'][key] = self._get_contact( + response=tmp_response, + handle=tmp_handle, + nir=nir, + retry_count=retry_count, + dt_format=dt_format + ) + global_contacts[contact] = ( + temp_net['contacts'][key] + ) + + # Merge the net dictionaries. + net.update(temp_net) + + # The start and end values are no longer needed. + del net['start'], net['end'] + + # Add the networks to the return dictionary. + results['nets'] = nets + + return results diff --git a/env/lib/python3.7/site-packages/ipwhois/rdap.py b/env/lib/python3.7/site-packages/ipwhois/rdap.py new file mode 100644 index 0000000..4b16dca --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/rdap.py @@ -0,0 +1,898 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +from . import (Net, NetError, InvalidEntityContactObject, InvalidNetworkObject, + InvalidEntityObject, HTTPLookupError) +from .utils import ipv4_lstrip_zeros, calculate_cidr, unique_everseen +from .net import ip_address +import logging +import json + +log = logging.getLogger(__name__) + +BOOTSTRAP_URL = 'http://rdap.arin.net/bootstrap' + +RIR_RDAP = { + 'arin': { + 'ip_url': 'http://rdap.arin.net/registry/ip/{0}', + 'entity_url': 'http://rdap.arin.net/registry/entity/{0}' + }, + 'ripencc': { + 'ip_url': 'http://rdap.db.ripe.net/ip/{0}', + 'entity_url': 'http://rdap.db.ripe.net/entity/{0}' + }, + 'apnic': { + 'ip_url': 'http://rdap.apnic.net/ip/{0}', + 'entity_url': 'http://rdap.apnic.net/entity/{0}' + }, + 'lacnic': { + 'ip_url': 'http://rdap.lacnic.net/rdap/ip/{0}', + 'entity_url': 'http://rdap.lacnic.net/rdap/entity/{0}' + }, + 'afrinic': { + 'ip_url': 'http://rdap.afrinic.net/rdap/ip/{0}', + 'entity_url': 'http://rdap.afrinic.net/rdap/entity/{0}' + } +} + + +class _RDAPContact: + """ + The class for parsing RDAP entity contact information objects: + https://tools.ietf.org/html/rfc7483#section-5.1 + https://tools.ietf.org/html/rfc7095 + + Args: + vcard (:obj:`list` of :obj:`list`): The vcard list from an RDAP IP + address query. + + Raises: + InvalidEntityContactObject: vcard is not an RDAP entity contact + information object. + """ + + def __init__(self, vcard): + + if not isinstance(vcard, list): + + raise InvalidEntityContactObject('JSON result must be a list.') + + self.vcard = vcard + self.vars = { + 'name': None, + 'kind': None, + 'address': None, + 'phone': None, + 'email': None, + 'role': None, + 'title': None + } + + def _parse_name(self, val): + """ + The function for parsing the vcard name. + + Args: + val (:obj:`list`): The value to parse. + """ + + self.vars['name'] = val[3].strip() + + def _parse_kind(self, val): + """ + The function for parsing the vcard kind. + + Args: + val (:obj:`list`): The value to parse. + """ + + self.vars['kind'] = val[3].strip() + + def _parse_address(self, val): + """ + The function for parsing the vcard address. + + Args: + val (:obj:`list`): The value to parse. + """ + + ret = { + 'type': None, + 'value': None + } + + try: + + ret['type'] = val[1]['type'] + + except (KeyError, ValueError, TypeError): + + pass + + try: + + ret['value'] = val[1]['label'] + + except (KeyError, ValueError, TypeError): + + ret['value'] = '\n'.join(val[3]).strip() + + try: + + self.vars['address'].append(ret) + + except AttributeError: + + self.vars['address'] = [] + self.vars['address'].append(ret) + + def _parse_phone(self, val): + """ + The function for parsing the vcard phone numbers. + + Args: + val (:obj:`list`): The value to parse. + """ + + ret = { + 'type': None, + 'value': None + } + + try: + + ret['type'] = val[1]['type'] + + except (IndexError, KeyError, ValueError, TypeError): + + pass + + ret['value'] = val[3].strip() + + try: + + self.vars['phone'].append(ret) + + except AttributeError: + + self.vars['phone'] = [] + self.vars['phone'].append(ret) + + def _parse_email(self, val): + """ + The function for parsing the vcard email addresses. + + Args: + val (:obj:`list`): The value to parse. + """ + + ret = { + 'type': None, + 'value': None + } + + try: + + ret['type'] = val[1]['type'] + + except (KeyError, ValueError, TypeError): + + pass + + ret['value'] = val[3].strip() + + try: + + self.vars['email'].append(ret) + + except AttributeError: + + self.vars['email'] = [] + self.vars['email'].append(ret) + + def _parse_role(self, val): + """ + The function for parsing the vcard role. + + Args: + val (:obj:`list`): The value to parse. + """ + + self.vars['role'] = val[3].strip() + + def _parse_title(self, val): + """ + The function for parsing the vcard title. + + Args: + val (:obj:`list`): The value to parse. + """ + + self.vars['title'] = val[3].strip() + + def parse(self): + """ + The function for parsing the vcard to the vars dictionary. + """ + + keys = { + 'fn': self._parse_name, + 'kind': self._parse_kind, + 'adr': self._parse_address, + 'tel': self._parse_phone, + 'email': self._parse_email, + 'role': self._parse_role, + 'title': self._parse_title + } + + for val in self.vcard: + + try: + + parser = keys.get(val[0]) + parser(val) + + except (KeyError, ValueError, TypeError): + + pass + + +class _RDAPCommon: + """ + The common class for parsing RDAP objects: + https://tools.ietf.org/html/rfc7483#section-5 + + Args: + json_result (:obj:`dict`): The JSON response from an RDAP query. + + Raises: + ValueError: vcard is not a known RDAP object. + """ + + def __init__(self, json_result): + + if not isinstance(json_result, dict): + + raise ValueError + + self.json = json_result + self.vars = { + 'handle': None, + 'status': None, + 'remarks': None, + 'notices': None, + 'links': None, + 'events': None, + 'raw': None + } + + def summarize_links(self, links_json): + """ + The function for summarizing RDAP links in to a unique list. + https://tools.ietf.org/html/rfc7483#section-4.2 + + Args: + links_json (:obj:`dict`): A json mapping of links from RDAP + results. + + Returns: + list of str: Unique RDAP links. + """ + + ret = [] + + for link_dict in links_json: + + ret.append(link_dict['href']) + + ret = list(unique_everseen(ret)) + + return ret + + def summarize_notices(self, notices_json): + """ + The function for summarizing RDAP notices in to a unique list. + https://tools.ietf.org/html/rfc7483#section-4.3 + + Args: + notices_json (:obj:`dict`): A json mapping of notices from RDAP + results. + + Returns: + list of dict: Unique RDAP notices information: + + :: + + [{ + 'title' (str) - The title/header of the notice. + 'description' (str) - The description/body of the notice. + 'links' (list) - Unique links returned by + :obj:`ipwhois.rdap._RDAPCommon.summarize_links()`. + }] + """ + + ret = [] + + for notices_dict in notices_json: + + tmp = { + 'title': None, + 'description': None, + 'links': None + } + + try: + + tmp['title'] = notices_dict['title'] + + except (KeyError, ValueError, TypeError): + + pass + + try: + + tmp['description'] = '\n'.join(notices_dict['description']) + + except (KeyError, ValueError, TypeError): + + pass + + try: + + tmp['links'] = self.summarize_links(notices_dict['links']) + + except (KeyError, ValueError, TypeError): + + pass + + if any(tmp.values()): + + ret.append(tmp) + + return ret + + def summarize_events(self, events_json): + """ + The function for summarizing RDAP events in to a unique list. + https://tools.ietf.org/html/rfc7483#section-4.5 + + Args: + events_json (:obj:`dict`): A json mapping of events from RDAP + results. + + Returns: + list of dict: Unique RDAP events information: + + :: + + [{ + 'action' (str) - The reason for an event. + 'timestamp' (str) - The timestamp for when an event + occured. + 'actor' (str) - The identifier for an event initiator. + }] + """ + + ret = [] + + for event in events_json: + + event_dict = { + 'action': event['eventAction'], + 'timestamp': event['eventDate'], + 'actor': None + } + + try: + + event_dict['actor'] = event['eventActor'] + + except (KeyError, ValueError, TypeError): + + pass + + ret.append(event_dict) + + return ret + + def _parse(self): + """ + The function for parsing the JSON response to the vars dictionary. + """ + + try: + + self.vars['status'] = self.json['status'] + + except (KeyError, ValueError, TypeError): + + pass + + for v in ['remarks', 'notices']: + + try: + + self.vars[v] = self.summarize_notices(self.json[v]) + + except (KeyError, ValueError, TypeError): + + pass + + try: + + self.vars['links'] = self.summarize_links(self.json['links']) + + except (KeyError, ValueError, TypeError): + + pass + + try: + + self.vars['events'] = self.summarize_events(self.json['events']) + + except (KeyError, ValueError, TypeError): + + pass + + +class _RDAPNetwork(_RDAPCommon): + """ + The class for parsing RDAP network objects: + https://tools.ietf.org/html/rfc7483#section-5.4 + + Args: + json_result (:obj:`dict`): The JSON response from an RDAP IP address + query. + + Raises: + InvalidNetworkObject: json_result is not an RDAP network object. + """ + + def __init__(self, json_result): + + try: + + _RDAPCommon.__init__(self, json_result) + + except ValueError: + + raise InvalidNetworkObject('JSON result must be a dict.') + + self.vars.update({ + 'start_address': None, + 'end_address': None, + 'cidr': None, + 'ip_version': None, + 'type': None, + 'name': None, + 'country': None, + 'parent_handle': None + }) + + def parse(self): + """ + The function for parsing the JSON response to the vars dictionary. + """ + + try: + + self.vars['handle'] = self.json['handle'].strip() + + except (KeyError, ValueError): + + log.debug('Handle missing, json_output: {0}'.format(json.dumps( + self.json))) + raise InvalidNetworkObject('Handle is missing for RDAP network ' + 'object') + + try: + + self.vars['ip_version'] = self.json['ipVersion'].strip() + + # RDAP IPv4 addresses are padded to 3 digits per octet, remove + # the leading 0's. + if self.vars['ip_version'] == 'v4': + + self.vars['start_address'] = ip_address( + ipv4_lstrip_zeros(self.json['startAddress']) + ).__str__() + + self.vars['end_address'] = ip_address( + ipv4_lstrip_zeros(self.json['endAddress']) + ).__str__() + + # No bugs found for IPv6 yet, proceed as normal. + else: + + self.vars['start_address'] = self.json['startAddress'].strip() + self.vars['end_address'] = self.json['endAddress'].strip() + + except (KeyError, ValueError, TypeError): + + log.debug('IP address data incomplete. Data parsed prior to ' + 'exception: {0}'.format(json.dumps(self.vars))) + raise InvalidNetworkObject('IP address data is missing for RDAP ' + 'network object.') + + try: + + self.vars['cidr'] = ', '.join(calculate_cidr( + self.vars['start_address'], self.vars['end_address'] + )) + + except (KeyError, ValueError, TypeError, AttributeError) as \ + e: # pragma: no cover + + log.debug('CIDR calculation failed: {0}'.format(e)) + pass + + for v in ['name', 'type', 'country']: + + try: + + self.vars[v] = self.json[v].strip() + + except (KeyError, ValueError): + + pass + + try: + + self.vars['parent_handle'] = self.json['parentHandle'].strip() + + except (KeyError, ValueError): + + pass + + self._parse() + + +class _RDAPEntity(_RDAPCommon): + """ + The class for parsing RDAP entity objects: + https://tools.ietf.org/html/rfc7483#section-5.1 + + Args: + json_result (:obj:`dict`): The JSON response from an RDAP query. + + Raises: + InvalidEntityObject: json_result is not an RDAP entity object. + """ + + def __init__(self, json_result): + + try: + + _RDAPCommon.__init__(self, json_result) + + except ValueError: + + raise InvalidEntityObject('JSON result must be a dict.') + + self.vars.update({ + 'roles': None, + 'contact': None, + 'events_actor': None, + 'entities': [] + }) + + def parse(self): + """ + The function for parsing the JSON response to the vars dictionary. + """ + + try: + + self.vars['handle'] = self.json['handle'].strip() + + except (KeyError, ValueError, TypeError): + + raise InvalidEntityObject('Handle is missing for RDAP entity') + + for v in ['roles', 'country']: + + try: + + self.vars[v] = self.json[v] + + except (KeyError, ValueError): + + pass + + try: + + vcard = self.json['vcardArray'][1] + c = _RDAPContact(vcard) + c.parse() + + self.vars['contact'] = c.vars + + except (KeyError, ValueError, TypeError): + + pass + + try: + + self.vars['events_actor'] = self.summarize_events( + self.json['asEventActor']) + + except (KeyError, ValueError, TypeError): + + pass + + self.vars['entities'] = [] + try: + + for ent in self.json['entities']: + + if ent['handle'] not in self.vars['entities']: + + self.vars['entities'].append(ent['handle']) + + except (KeyError, ValueError, TypeError): + + pass + + if not self.vars['entities']: + + self.vars['entities'] = None + + self._parse() + + +class RDAP: + """ + The class for parsing IP address whois information via RDAP: + https://tools.ietf.org/html/rfc7483 + https://www.arin.net/resources/rdap.html + + Args: + net (:obj:`ipwhois.net.Net`): The network object. + + Raises: + NetError: The parameter provided is not an instance of + ipwhois.net.Net + IPDefinedError: The address provided is defined (does not need to be + resolved). + """ + + def __init__(self, net): + + if isinstance(net, Net): + + self._net = net + + else: + + raise NetError('The provided net parameter is not an instance of ' + 'ipwhois.net.Net') + + def lookup(self, inc_raw=False, retry_count=3, asn_data=None, depth=0, + excluded_entities=None, response=None, bootstrap=False, + rate_limit_timeout=120): + """ + The function for retrieving and parsing information for an IP + address via RDAP (HTTP). + + Args: + inc_raw (:obj:`bool`, optional): Whether to include the raw + results in the returned dictionary. Defaults to False. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + asn_data (:obj:`dict`): Result from + :obj:`ipwhois.asn.IPASN.lookup`. Optional if the bootstrap + parameter is True. + depth (:obj:`int`): How many levels deep to run queries when + additional referenced objects are found. Defaults to 0. + excluded_entities (:obj:`list`): Entity handles to not perform + lookups. Defaults to None. + response (:obj:`str`): Optional response object, this bypasses the + RDAP lookup. + bootstrap (:obj:`bool`): If True, performs lookups via ARIN + bootstrap rather than lookups based on ASN data. Defaults to + False. + rate_limit_timeout (:obj:`int`): The number of seconds to wait + before retrying when a rate limit notice is returned via + rdap+json. Defaults to 120. + + Returns: + dict: The IP RDAP lookup results + + :: + + { + 'query' (str) - The IP address + 'entities' (list) - Entity handles referred by the top + level query. + 'network' (dict) - Network information which consists of + the fields listed in the ipwhois.rdap._RDAPNetwork + dict. + 'objects' (dict) - Mapping of entity handle->entity dict + which consists of the fields listed in the + ipwhois.rdap._RDAPEntity dict. The raw result is + included for each object if the inc_raw parameter + is True. + } + """ + + if not excluded_entities: + + excluded_entities = [] + + # Create the return dictionary. + results = { + 'query': self._net.address_str, + 'network': None, + 'entities': None, + 'objects': None, + 'raw': None + } + + if bootstrap: + + ip_url = '{0}/ip/{1}'.format(BOOTSTRAP_URL, self._net.address_str) + + else: + + ip_url = str(RIR_RDAP[asn_data['asn_registry']]['ip_url']).format( + self._net.address_str) + + # Only fetch the response if we haven't already. + if response is None: + + log.debug('Response not given, perform RDAP lookup for {0}'.format( + ip_url)) + + # Retrieve the whois data. + response = self._net.get_http_json( + url=ip_url, retry_count=retry_count, + rate_limit_timeout=rate_limit_timeout + ) + + if inc_raw: + + results['raw'] = response + + log.debug('Parsing RDAP network object') + result_net = _RDAPNetwork(response) + result_net.parse() + results['network'] = result_net.vars + results['entities'] = [] + results['objects'] = {} + roles = {} + + # Iterate through and parse the root level entities. + log.debug('Parsing RDAP root level entities') + try: + + for ent in response['entities']: + + if ent['handle'] not in [results['entities'], + excluded_entities]: + + result_ent = _RDAPEntity(ent) + result_ent.parse() + + results['objects'][ent['handle']] = result_ent.vars + + results['entities'].append(ent['handle']) + + try: + + for tmp in ent['entities']: + + roles[tmp['handle']] = tmp['roles'] + + except KeyError: + + pass + + except KeyError: + + pass + + # Iterate through to the defined depth, retrieving and parsing all + # unique entities. + temp_objects = results['objects'] + + if depth > 0 and len(temp_objects) > 0: + + log.debug('Parsing RDAP sub-entities to depth: {0}'.format(str( + depth))) + + while depth > 0 and len(temp_objects) > 0: + + new_objects = {} + for obj in temp_objects.values(): + + try: + + for ent in obj['entities']: + + if ent not in (list(results['objects'].keys()) + + list(new_objects.keys()) + + excluded_entities): + + if bootstrap: + entity_url = '{0}/entity/{1}'.format( + BOOTSTRAP_URL, ent) + else: + tmp_reg = asn_data['asn_registry'] + entity_url = RIR_RDAP[tmp_reg]['entity_url'] + entity_url = str(entity_url).format(ent) + + try: + + # RDAP entity query + response = self._net.get_http_json( + url=entity_url, retry_count=retry_count, + rate_limit_timeout=rate_limit_timeout + ) + + # Parse the entity + result_ent = _RDAPEntity(response) + result_ent.parse() + new_objects[ent] = result_ent.vars + + new_objects[ent]['roles'] = None + try: + + new_objects[ent]['roles'] = roles[ent] + + except KeyError: # pragma: no cover + + pass + + try: + + for tmp in response['entities']: + + if tmp['handle'] not in roles: + + roles[tmp['handle']] = tmp['roles'] + + except (IndexError, KeyError): + + pass + + if inc_raw: + + new_objects[ent]['raw'] = response + + except (HTTPLookupError, InvalidEntityObject): + + pass + + except TypeError: + + pass + + # Update the result objects, and set the new temp object list to + # iterate for the next depth of entities. + results['objects'].update(new_objects) + temp_objects = new_objects + depth -= 1 + + return results diff --git a/env/lib/python3.7/site-packages/ipwhois/utils.py b/env/lib/python3.7/site-packages/ipwhois/utils.py new file mode 100644 index 0000000..98da43d --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/utils.py @@ -0,0 +1,631 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import sys +from xml.dom.minidom import parseString +from os import path +import re +import copy +import io +import csv +import random +from collections import namedtuple +import logging + +if sys.version_info >= (3, 3): # pragma: no cover + from ipaddress import (ip_address, + ip_network, + IPv4Address, + IPv4Network, + IPv6Address, + summarize_address_range, + collapse_addresses) +else: # pragma: no cover + from ipaddr import (IPAddress as ip_address, + IPNetwork as ip_network, + IPv4Address, + IPv4Network, + IPv6Address, + summarize_address_range, + collapse_address_list as collapse_addresses) + +try: # pragma: no cover + from itertools import filterfalse + +except ImportError: # pragma: no cover + from itertools import ifilterfalse as filterfalse + +log = logging.getLogger(__name__) + +IETF_RFC_REFERENCES = { + # IPv4 + 'RFC 1122, Section 3.2.1.3': + 'http://tools.ietf.org/html/rfc1122#section-3.2.1.3', + 'RFC 1918': 'http://tools.ietf.org/html/rfc1918', + 'RFC 3927': 'http://tools.ietf.org/html/rfc3927', + 'RFC 5736': 'http://tools.ietf.org/html/rfc5736', + 'RFC 5737': 'http://tools.ietf.org/html/rfc5737', + 'RFC 3068': 'http://tools.ietf.org/html/rfc3068', + 'RFC 2544': 'http://tools.ietf.org/html/rfc2544', + 'RFC 3171': 'http://tools.ietf.org/html/rfc3171', + 'RFC 919, Section 7': 'http://tools.ietf.org/html/rfc919#section-7', + # IPv6 + 'RFC 4291, Section 2.7': 'http://tools.ietf.org/html/rfc4291#section-2.7', + 'RFC 4291': 'http://tools.ietf.org/html/rfc4291', + 'RFC 4291, Section 2.5.2': + 'http://tools.ietf.org/html/rfc4291#section-2.5.2', + 'RFC 4291, Section 2.5.3': + 'http://tools.ietf.org/html/rfc4291#section-2.5.3', + 'RFC 4291, Section 2.5.6': + 'http://tools.ietf.org/html/rfc4291#section-2.5.6', + 'RFC 4291, Section 2.5.7': + 'http://tools.ietf.org/html/rfc4291#section-2.5.7', + 'RFC 4193': 'https://tools.ietf.org/html/rfc4193' +} + +IP_REGEX = ( + r'(?P' + # IPv4 + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.)){3}' + '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' + # IPv6 + '|\[?(((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:)' + '{6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|' + '2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]' + '{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d' + '\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|' + '((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|' + '2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]' + '{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)' + '(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}((' + '(:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1' + '\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|((' + '[0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4})' + '{0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]' + '?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((' + '25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})' + ')|:)))(%.+)?))\]?' + # Optional IPv4 Port + '((:(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|[1-9]\d{0,3}' + # Optional CIDR block + '))|(\/(?:[012]\d?|3[012]?|[4-9])))?' + ')' +) + + +def ipv4_lstrip_zeros(address): + """ + The function to strip leading zeros in each octet of an IPv4 address. + + Args: + address (:obj:`str`): An IPv4 address. + + Returns: + str: The modified IPv4 address. + """ + + # Split the octets. + obj = address.strip().split('.') + + for x, y in enumerate(obj): + + # Strip leading zeros. Split / here in case CIDR is attached. + obj[x] = y.split('/')[0].lstrip('0') + if obj[x] in ['', None]: + obj[x] = '0' + + return '.'.join(obj) + + +def calculate_cidr(start_address, end_address): + """ + The function to calculate a CIDR range(s) from a start and end IP address. + + Args: + start_address (:obj:`str`): The starting IP address. + end_address (:obj:`str`): The ending IP address. + + Returns: + list of str: The calculated CIDR ranges. + """ + + tmp_addrs = [] + + try: + + tmp_addrs.extend(summarize_address_range( + ip_address(start_address), + ip_address(end_address))) + + except (KeyError, ValueError, TypeError): # pragma: no cover + + try: + + tmp_addrs.extend(summarize_address_range( + ip_network(start_address).network_address, + ip_network(end_address).network_address)) + + except AttributeError: # pragma: no cover + + tmp_addrs.extend(summarize_address_range( + ip_network(start_address).ip, + ip_network(end_address).ip)) + + return [i.__str__() for i in collapse_addresses(tmp_addrs)] + + +def get_countries(is_legacy_xml=False): + """ + The function to generate a dictionary containing ISO_3166-1 country codes + to names. + + Args: + is_legacy_xml (:obj:`bool`): Whether to use the older country code + list (iso_3166-1_list_en.xml). + + Returns: + dict: A mapping of country codes as the keys to the country names as + the values. + """ + + # Initialize the countries dictionary. + countries = {} + + # Set the data directory based on if the script is a frozen executable. + if sys.platform == 'win32' and getattr(sys, 'frozen', False): + + data_dir = path.dirname(sys.executable) # pragma: no cover + + else: + + data_dir = path.dirname(__file__) + + if is_legacy_xml: + + log.debug('Opening country code legacy XML: {0}'.format( + str(data_dir) + '/data/iso_3166-1_list_en.xml')) + + # Create the country codes file object. + f = io.open(str(data_dir) + '/data/iso_3166-1_list_en.xml', 'r', + encoding='ISO-8859-1') + + # Read the file. + data = f.read() + + # Check if there is data. + if not data: # pragma: no cover + + return {} + + # Parse the data to get the DOM. + dom = parseString(data) + + # Retrieve the country entries. + entries = dom.getElementsByTagName('ISO_3166-1_Entry') + + # Iterate through the entries and add to the countries dictionary. + for entry in entries: + + # Retrieve the country code and name from the DOM. + code = entry.getElementsByTagName( + 'ISO_3166-1_Alpha-2_Code_element')[0].firstChild.data + name = entry.getElementsByTagName( + 'ISO_3166-1_Country_name')[0].firstChild.data + + # Add to the countries dictionary. + countries[code] = name.title() + + else: + + log.debug('Opening country code CSV: {0}'.format( + str(data_dir) + '/data/iso_3166-1_list_en.xml')) + + # Create the country codes file object. + f = io.open(str(data_dir) + '/data/iso_3166-1.csv', 'r', + encoding='utf-8') + + # Create csv reader object. + csv_reader = csv.reader(f, delimiter=',', quotechar='"') + + # Iterate through the rows and add to the countries dictionary. + for row in csv_reader: + + # Retrieve the country code and name columns. + code = row[0] + name = row[1] + + # Add to the countries dictionary. + countries[code] = name + + return countries + + +def ipv4_is_defined(address): + """ + The function for checking if an IPv4 address is defined (does not need to + be resolved). + + Args: + address (:obj:`str`): An IPv4 address. + + Returns: + namedtuple: + + :is_defined (bool): True if given address is defined, otherwise + False + :ietf_name (str): IETF assignment name if given address is + defined, otherwise '' + :ietf_rfc (str): IETF assignment RFC if given address is defined, + otherwise '' + """ + + # Initialize the IP address object. + query_ip = IPv4Address(str(address)) + + # Initialize the results named tuple + results = namedtuple('ipv4_is_defined_results', 'is_defined, ietf_name, ' + 'ietf_rfc') + + # This Network + if query_ip in IPv4Network('0.0.0.0/8'): + + return results(True, 'This Network', 'RFC 1122, Section 3.2.1.3') + + # Loopback + elif query_ip.is_loopback: + + return results(True, 'Loopback', 'RFC 1122, Section 3.2.1.3') + + # Link Local + elif query_ip.is_link_local: + + return results(True, 'Link Local', 'RFC 3927') + + # IETF Protocol Assignments + elif query_ip in IPv4Network('192.0.0.0/24'): + + return results(True, 'IETF Protocol Assignments', 'RFC 5736') + + # TEST-NET-1 + elif query_ip in IPv4Network('192.0.2.0/24'): + + return results(True, 'TEST-NET-1', 'RFC 5737') + + # 6to4 Relay Anycast + elif query_ip in IPv4Network('192.88.99.0/24'): + + return results(True, '6to4 Relay Anycast', 'RFC 3068') + + # Network Interconnect Device Benchmark Testing + elif query_ip in IPv4Network('198.18.0.0/15'): + + return (results(True, + 'Network Interconnect Device Benchmark Testing', + 'RFC 2544')) + + # TEST-NET-2 + elif query_ip in IPv4Network('198.51.100.0/24'): + + return results(True, 'TEST-NET-2', 'RFC 5737') + + # TEST-NET-3 + elif query_ip in IPv4Network('203.0.113.0/24'): + + return results(True, 'TEST-NET-3', 'RFC 5737') + + # Multicast + elif query_ip.is_multicast: + + return results(True, 'Multicast', 'RFC 3171') + + # Limited Broadcast + elif query_ip in IPv4Network('255.255.255.255/32'): + + return results(True, 'Limited Broadcast', 'RFC 919, Section 7') + + # Private-Use Networks + elif query_ip.is_private: + + return results(True, 'Private-Use Networks', 'RFC 1918') + + # New IANA Reserved + # TODO: Someone needs to find the RFC for this + elif query_ip in IPv4Network('198.97.38.0/24'): + + return results(True, 'IANA Reserved', '') + + return results(False, '', '') + + +def ipv6_is_defined(address): + """ + The function for checking if an IPv6 address is defined (does not need to + be resolved). + + Args: + address (:obj:`str`): An IPv6 address. + + Returns: + namedtuple: + + :is_defined (bool): True if given address is defined, otherwise + False + :ietf_name (str): IETF assignment name if given address is + defined, otherwise '' + :ietf_rfc (str): IETF assignment RFC if given address is defined, + otherwise '' + """ + + # Initialize the IP address object. + query_ip = IPv6Address(str(address)) + + # Initialize the results named tuple + results = namedtuple('ipv6_is_defined_results', 'is_defined, ietf_name, ' + 'ietf_rfc') + # Multicast + if query_ip.is_multicast: + + return results(True, 'Multicast', 'RFC 4291, Section 2.7') + + # Unspecified + elif query_ip.is_unspecified: + + return results(True, 'Unspecified', 'RFC 4291, Section 2.5.2') + + # Loopback. + elif query_ip.is_loopback: + + return results(True, 'Loopback', 'RFC 4291, Section 2.5.3') + + # Reserved + elif query_ip.is_reserved: + + return results(True, 'Reserved', 'RFC 4291') + + # Link-Local + elif query_ip.is_link_local: + + return results(True, 'Link-Local', 'RFC 4291, Section 2.5.6') + + # Site-Local + elif query_ip.is_site_local: + + return results(True, 'Site-Local', 'RFC 4291, Section 2.5.7') + + # Unique Local Unicast + elif query_ip.is_private: + + return results(True, 'Unique Local Unicast', 'RFC 4193') + + return results(False, '', '') + + +def unique_everseen(iterable, key=None): + """ + The generator to list unique elements, preserving the order. Remember all + elements ever seen. This was taken from the itertools recipes. + + Args: + iterable (:obj:`iter`): An iterable to process. + key (:obj:`callable`): Optional function to run when checking + elements (e.g., str.lower) + + Yields: + The next unique element found. + """ + + seen = set() + seen_add = seen.add + + if key is None: + + for element in filterfalse(seen.__contains__, iterable): + + seen_add(element) + yield element + + else: + + for element in iterable: + + k = key(element) + + if k not in seen: + + seen_add(k) + yield element + + +def unique_addresses(data=None, file_path=None): + """ + The function to search an input string and/or file, extracting and + counting IPv4/IPv6 addresses/networks. Summarizes ports with sub-counts. + If both a string and file_path are provided, it will process them both. + + Args: + data (:obj:`str`): The data to process. + file_path (:obj:`str`): An optional file path to process. + + Returns: + dict: The addresses/networks mapped to ports and counts: + + :: + + { + '1.2.3.4' (dict) - Each address or network found is a + dictionary: + { + 'count' (int) - Total number of times seen. + 'ports' (dict) - Mapping of port numbers as keys and + the number of times seen for this ip as values. + } + } + + Raises: + ValueError: Arguments provided are invalid. + """ + + if not data and not file_path: + + raise ValueError('No data or file path provided.') + + ret = {} + base = { + 'count': 0, + 'ports': {} + } + + file_data = None + if file_path: + + log.debug('Opening file for unique address analysis: {0}'.format( + str(file_path))) + + f = open(str(file_path), 'r') + + # Read the file. + file_data = f.read() + + pattern = re.compile( + str(IP_REGEX), + re.DOTALL + ) + + # Check if there is data. + log.debug('Analyzing input/file data'.format( + str(file_path))) + for input_data in [data, file_data]: + + if input_data: + + # Search for IPs. + for match in pattern.finditer(input_data): + + is_net = False + port = None + try: + + found = match.group('ip') + + if '.' in found and ':' in found: + + split = found.split(':') + ip_or_net = split[0] + port = split[1] + + elif '[' in found: + + split = found.split(']:') + ip_or_net = split[0][1:] + port = split[1] + + elif '/' in found: + + is_net = True + ip_or_net = found + + else: + + ip_or_net = found + + if is_net: + + ip_obj = ip_network(ip_or_net) + + else: + ip_obj = ip_address(ip_or_net) + + obj_str = ip_obj.__str__() + + if obj_str not in ret.keys(): + + ret[obj_str] = copy.deepcopy(base) + + ret[obj_str]['count'] += 1 + + if port: + + try: + + ret[obj_str]['ports'][str(port)] += 1 + + except KeyError: + + ret[obj_str]['ports'][str(port)] = 1 + + except (KeyError, ValueError): + + continue + + return ret + + +def ipv4_generate_random(total=100): + """ + The generator to produce random, unique IPv4 addresses that are not + defined (can be looked up using ipwhois). + + Args: + total (:obj:`int`): The total number of IPv4 addresses to generate. + + Yields: + str: The next IPv4 address. + """ + + count = 0 + yielded = set() + while count < total: + + address = str(IPv4Address(random.randint(0, 2**32-1))) + + if not ipv4_is_defined(address)[0] and address not in yielded: + + count += 1 + yielded.add(address) + yield address + + +def ipv6_generate_random(total=100): + """ + The generator to produce random, unique IPv6 addresses that are not + defined (can be looked up using ipwhois). + + Args: + total (:obj:`int`): The total number of IPv6 addresses to generate. + + Yields: + str: The next IPv6 address. + """ + + count = 0 + yielded = set() + while count < total: + + address = str(IPv6Address(random.randint(0, 2**128-1))) + + if not ipv6_is_defined(address)[0] and address not in yielded: + + count += 1 + yielded.add(address) + yield address diff --git a/env/lib/python3.7/site-packages/ipwhois/whois.py b/env/lib/python3.7/site-packages/ipwhois/whois.py new file mode 100644 index 0000000..3cd830d --- /dev/null +++ b/env/lib/python3.7/site-packages/ipwhois/whois.py @@ -0,0 +1,809 @@ +# Copyright (c) 2013-2017 Philip Hane +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import sys +import re +import copy +from datetime import datetime +import logging +from .utils import unique_everseen +from . import (BlacklistError, WhoisLookupError, NetError) + +if sys.version_info >= (3, 3): # pragma: no cover + from ipaddress import (ip_address, + ip_network, + summarize_address_range, + collapse_addresses) +else: # pragma: no cover + from ipaddr import (IPAddress as ip_address, + IPNetwork as ip_network, + summarize_address_range, + collapse_address_list as collapse_addresses) + +log = logging.getLogger(__name__) + +# Legacy base whois output dictionary. +BASE_NET = { + 'cidr': None, + 'name': None, + 'handle': None, + 'range': None, + 'description': None, + 'country': None, + 'state': None, + 'city': None, + 'address': None, + 'postal_code': None, + 'emails': None, + 'created': None, + 'updated': None +} + +RIR_WHOIS = { + 'arin': { + 'server': 'whois.arin.net', + 'fields': { + 'name': r'(NetName):[^\S\n]+(?P.+?)\n', + 'handle': r'(NetHandle):[^\S\n]+(?P.+?)\n', + 'description': r'(OrgName|CustName):[^\S\n]+(?P.+?)' + '(?=(\n\S):?)', + 'country': r'(Country):[^\S\n]+(?P.+?)\n', + 'state': r'(StateProv):[^\S\n]+(?P.+?)\n', + 'city': r'(City):[^\S\n]+(?P.+?)\n', + 'address': r'(Address):[^\S\n]+(?P.+?)(?=(\n\S):?)', + 'postal_code': r'(PostalCode):[^\S\n]+(?P.+?)\n', + 'emails': ( + r'.+?:.*?[^\S\n]+(?P[\w\-\.]+?@[\w\-\.]+\.[\w\-]+)(' + '[^\S\n]+.*?)*?\n' + ), + 'created': r'(RegDate):[^\S\n]+(?P.+?)\n', + 'updated': r'(Updated):[^\S\n]+(?P.+?)\n', + }, + 'dt_format': '%Y-%m-%d' + }, + 'ripencc': { + 'server': 'whois.ripe.net', + 'fields': { + 'name': r'(netname):[^\S\n]+(?P.+?)\n', + 'handle': r'(nic-hdl):[^\S\n]+(?P.+?)\n', + 'description': r'(descr):[^\S\n]+(?P.+?)(?=(\n\S):?)', + 'country': r'(country):[^\S\n]+(?P.+?)\n', + 'address': r'(address):[^\S\n]+(?P.+?)(?=(\n\S):?)', + 'emails': ( + r'.+?:.*?[^\S\n]+(?P[\w\-\.]+?@[\w\-\.]+\.[\w\-]+)(' + '[^\S\n]+.*?)*?\n' + ), + 'created': ( + r'(created):[^\S\n]+(?P[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]' + '{2}:[0-9]{2}:[0-9]{2}Z).*?\n' + ), + 'updated': ( + r'(last-modified):[^\S\n]+(?P[0-9]{4}-[0-9]{2}-[0-9]{2}T' + '[0-9]{2}:[0-9]{2}:[0-9]{2}Z).*?\n' + ) + }, + 'dt_format': '%Y-%m-%dT%H:%M:%SZ' + }, + 'apnic': { + 'server': 'whois.apnic.net', + 'fields': { + 'name': r'(netname):[^\S\n]+(?P.+?)\n', + 'handle': r'(nic-hdl):[^\S\n]+(?P.+?)\n', + 'description': r'(descr):[^\S\n]+(?P.+?)(?=(\n\S):?)', + 'country': r'(country):[^\S\n]+(?P.+?)\n', + 'address': r'(address):[^\S\n]+(?P.+?)(?=(\n\S):?)', + 'emails': ( + r'.+?:.*?[^\S\n]+(?P[\w\-\.]+?@[\w\-\.]+\.[\w\-]+)(' + '[^\S\n]+.*?)*?\n' + ), + 'updated': r'(changed):[^\S\n]+.*(?P[0-9]{8}).*?\n' + }, + 'dt_format': '%Y%m%d' + }, + 'lacnic': { + 'server': 'whois.lacnic.net', + 'fields': { + 'handle': r'(nic-hdl):[^\S\n]+(?P.+?)\n', + 'description': r'(owner):[^\S\n]+(?P.+?)(?=(\n\S):?)', + 'country': r'(country):[^\S\n]+(?P.+?)\n', + 'emails': ( + r'.+?:.*?[^\S\n]+(?P[\w\-\.]+?@[\w\-\.]+\.[\w\-]+)(' + '[^\S\n]+.*?)*?\n' + ), + 'created': r'(created):[^\S\n]+(?P[0-9]{8}).*?\n', + 'updated': r'(changed):[^\S\n]+(?P[0-9]{8}).*?\n' + }, + 'dt_format': '%Y%m%d' + }, + 'afrinic': { + 'server': 'whois.afrinic.net', + 'fields': { + 'name': r'(netname):[^\S\n]+(?P.+?)\n', + 'handle': r'(nic-hdl):[^\S\n]+(?P.+?)\n', + 'description': r'(descr):[^\S\n]+(?P.+?)(?=(\n\S):?)', + 'country': r'(country):[^\S\n]+(?P.+?)\n', + 'address': r'(address):[^\S\n]+(?P.+?)(?=(\n\S):?)', + 'emails': ( + r'.+?:.*?[^\S\n]+(?P[\w\-\.]+?@[\w\-\.]+\.[\w\-]+)(' + '[^\S\n]+.*?)*?\n' + ), + } + } +} + +RWHOIS = { + 'fields': { + 'cidr': r'(network:IP-Network):(?P.+?)\n', + 'name': r'(network:ID):(?P.+?)\n', + 'description': ( + r'(network:(Org-Name|Organization(;I)?)):(?P.+?)\n' + ), + 'country': r'(network:(Country|Country-Code)):(?P.+?)\n', + 'state': r'(network:State):(?P.+?)\n', + 'city': r'(network:City):(?P.+?)\n', + 'address': r'(network:Street-Address):(?P.+?)\n', + 'postal_code': r'(network:Postal-Code):(?P.+?)\n', + 'emails': ( + r'.+?:.*?[^\S\n]+(?P[\w\-\.]+?@[\w\-\.]+\.[\w\-]+)(' + '[^\S\n]+.*?)*?\n' + ), + 'created': r'(network:Created):(?P.+?)\n', + 'updated': r'(network:Updated):(?P.+?)\n' + } +} + +ASN_REFERRALS = { + 'whois://whois.ripe.net': 'ripencc', + 'whois://whois.apnic.net': 'apnic', + 'whois://whois.lacnic.net': 'lacnic', + 'whois://whois.afrinic.net': 'afrinic', +} + + +class Whois: + """ + The class for parsing via whois + + Args: + net (:obj:`ipwhois.net.Net`): The network object. + + Raises: + NetError: The parameter provided is not an instance of + ipwhois.net.Net + IPDefinedError: The address provided is defined (does not need to be + resolved). + """ + + def __init__(self, net): + + from .net import Net + + # ipwhois.net.Net validation + if isinstance(net, Net): + + self._net = net + + else: + + raise NetError('The provided net parameter is not an instance of ' + 'ipwhois.net.Net') + + def parse_fields(self, response, fields_dict, net_start=None, + net_end=None, dt_format=None, field_list=None): + """ + The function for parsing whois fields from a data input. + + Args: + response (:obj:`str`): The response from the whois/rwhois server. + fields_dict (:obj:`dict`): The mapping of fields to regex search + values (required). + net_start (:obj:`int`): The starting point of the network (if + parsing multiple networks). Defaults to None. + net_end (:obj:`int`): The ending point of the network (if parsing + multiple networks). Defaults to None. + dt_format (:obj:`str`): The format of datetime fields if known. + Defaults to None. + field_list (:obj:`list` of :obj:`str`): If provided, fields to + parse. Defaults to: + + :: + + ['name', 'handle', 'description', 'country', 'state', + 'city', 'address', 'postal_code', 'emails', 'created', + 'updated'] + + Returns: + dict: A dictionary of fields provided in fields_dict, mapping to + the results of the regex searches. + """ + + ret = {} + + if not field_list: + + field_list = ['name', 'handle', 'description', 'country', 'state', + 'city', 'address', 'postal_code', 'emails', + 'created', 'updated'] + + generate = ((field, pattern) for (field, pattern) in + fields_dict.items() if field in field_list) + + for field, pattern in generate: + + pattern = re.compile( + str(pattern), + re.DOTALL + ) + + if net_start is not None: + + match = pattern.finditer(response, net_end, net_start) + + elif net_end is not None: + + match = pattern.finditer(response, net_end) + + else: + + match = pattern.finditer(response) + + values = [] + sub_section_end = None + for m in match: + + if sub_section_end: + + if field not in ( + 'emails' + ) and (sub_section_end != (m.start() - 1)): + + break + + try: + + values.append(m.group('val').strip()) + + except IndexError: + + pass + + sub_section_end = m.end() + + if len(values) > 0: + + value = None + try: + + if field == 'country': + + value = values[0].upper() + + elif field in ['created', 'updated'] and dt_format: + + value = datetime.strptime( + values[0], + str(dt_format)).isoformat('T') + + elif field in ['emails']: + + value = list(unique_everseen(values)) + + else: + + values = unique_everseen(values) + value = '\n'.join(values).strip() + + except ValueError as e: + + log.debug('Whois field parsing failed for {0}: {1}'.format( + field, e)) + pass + + ret[field] = value + + return ret + + def _parse_fields(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('Whois._parse_fields() has been deprecated and will be ' + 'removed. You should now use Whois.parse_fields().') + return self.parse_fields(*args, **kwargs) + + def get_nets_arin(self, response): + """ + The function for parsing network blocks from ARIN whois data. + + Args: + response (:obj:`str`): The response from the ARIN whois server. + + Returns: + list of dict: Mapping of networks with start and end positions. + + :: + + [{ + 'cidr' (str) - The network routing block + 'start' (int) - The starting point of the network + 'end' (int) - The endpoint point of the network + }] + """ + + nets = [] + + # Find the first NetRange value. + pattern = re.compile( + r'^NetRange:[^\S\n]+(.+)$', + re.MULTILINE + ) + temp = pattern.search(response) + net_range = None + net_range_start = None + if temp is not None: + net_range = temp.group(1).strip() + net_range_start = temp.start() + + # Iterate through all of the networks found, storing the CIDR value + # and the start and end positions. + for match in re.finditer( + r'^CIDR:[^\S\n]+(.+?,[^\S\n].+|.+)$', + response, + re.MULTILINE + ): + + try: + + net = copy.deepcopy(BASE_NET) + + if len(nets) > 0: + temp = pattern.search(response, match.start()) + net_range = None + net_range_start = None + if temp is not None: + net_range = temp.group(1).strip() + net_range_start = temp.start() + + if net_range is not None: + if net_range_start < match.start() or len(nets) > 0: + + try: + + net['range'] = '{0} - {1}'.format( + ip_network(net_range)[0].__str__(), + ip_network(net_range)[-1].__str__() + ) if '/' in net_range else net_range + + except ValueError: # pragma: no cover + + net['range'] = net_range + + net['cidr'] = ', '.join( + [ip_network(c.strip()).__str__() + for c in match.group(1).split(', ')] + ) + net['start'] = match.start() + net['end'] = match.end() + nets.append(net) + + except ValueError: + + pass + + return nets + + def _get_nets_arin(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('Whois._get_nets_arin() has been deprecated and will be ' + 'removed. You should now use Whois.get_nets_arin().') + return self.get_nets_arin(*args, **kwargs) + + def get_nets_lacnic(self, response): + """ + The function for parsing network blocks from LACNIC whois data. + + Args: + response (:obj:`str`): The response from the LACNIC whois server. + + Returns: + list of dict: Mapping of networks with start and end positions. + + :: + + [{ + 'cidr' (str) - The network routing block + 'start' (int) - The starting point of the network + 'end' (int) - The endpoint point of the network + }] + """ + + nets = [] + + # Iterate through all of the networks found, storing the CIDR value + # and the start and end positions. + for match in re.finditer( + r'^(inetnum|inet6num|route):[^\S\n]+(.+?,[^\S\n].+|.+)$', + response, + re.MULTILINE + ): + + try: + + net = copy.deepcopy(BASE_NET) + net_range = match.group(2).strip() + + try: + + net['range'] = net['range'] = '{0} - {1}'.format( + ip_network(net_range)[0].__str__(), + ip_network(net_range)[-1].__str__() + ) if '/' in net_range else net_range + + except ValueError: # pragma: no cover + + net['range'] = net_range + + temp = [] + for addr in net_range.split(', '): + + count = addr.count('.') + if count is not 0 and count < 4: + + addr_split = addr.strip().split('/') + for i in range(count + 1, 4): + addr_split[0] += '.0' + + addr = '/'.join(addr_split) + + temp.append(ip_network(addr.strip()).__str__()) + + net['cidr'] = ', '.join(temp) + net['start'] = match.start() + net['end'] = match.end() + nets.append(net) + + except ValueError: + + pass + + return nets + + def _get_nets_lacnic(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('Whois._get_nets_lacnic() has been deprecated and will be ' + 'removed. You should now use Whois.get_nets_lacnic().') + return self.get_nets_lacnic(*args, **kwargs) + + def get_nets_other(self, response): + """ + The function for parsing network blocks from generic whois data. + + Args: + response (:obj:`str`): The response from the whois/rwhois server. + + Returns: + list of dict: Mapping of networks with start and end positions. + + :: + + [{ + 'cidr' (str) - The network routing block + 'start' (int) - The starting point of the network + 'end' (int) - The endpoint point of the network + }] + """ + + nets = [] + + # Iterate through all of the networks found, storing the CIDR value + # and the start and end positions. + for match in re.finditer( + r'^(inetnum|inet6num|route):[^\S\n]+((.+?)[^\S\n]-[^\S\n](.+)|' + '.+)$', + response, + re.MULTILINE + ): + + try: + + net = copy.deepcopy(BASE_NET) + net_range = match.group(2).strip() + + try: + + net['range'] = net['range'] = '{0} - {1}'.format( + ip_network(net_range)[0].__str__(), + ip_network(net_range)[-1].__str__() + ) if '/' in net_range else net_range + + except ValueError: # pragma: no cover + + net['range'] = net_range + + if match.group(3) and match.group(4): + + addrs = [] + addrs.extend(summarize_address_range( + ip_address(match.group(3).strip()), + ip_address(match.group(4).strip()))) + + cidr = ', '.join( + [i.__str__() for i in collapse_addresses(addrs)] + ) + + else: + + cidr = ip_network(net_range).__str__() + + net['cidr'] = cidr + net['start'] = match.start() + net['end'] = match.end() + nets.append(net) + + except (ValueError, TypeError): + + pass + + return nets + + def _get_nets_other(self, *args, **kwargs): + """ + Deprecated. This will be removed in a future release. + """ + + from warnings import warn + warn('Whois._get_nets_other() has been deprecated and will be ' + 'removed. You should now use Whois.get_nets_other().') + return self.get_nets_other(*args, **kwargs) + + def lookup(self, inc_raw=False, retry_count=3, response=None, + get_referral=False, extra_blacklist=None, + ignore_referral_errors=False, asn_data=None, + field_list=None, is_offline=False): + """ + The function for retrieving and parsing whois information for an IP + address via port 43/tcp (WHOIS). + + Args: + inc_raw (:obj:`bool`, optional): Whether to include the raw + results in the returned dictionary. Defaults to False. + retry_count (:obj:`int`): The number of times to retry in case + socket errors, timeouts, connection resets, etc. are + encountered. Defaults to 3. + response (:obj:`str`): Optional response object, this bypasses the + NIR lookup. Required when is_offline=True. + get_referral (:obj:`bool`): Whether to retrieve referral whois + information, if available. Defaults to False. + extra_blacklist (:obj:`list`): Blacklisted whois servers in + addition to the global BLACKLIST. Defaults to None. + ignore_referral_errors (:obj:`bool`): Whether to ignore and + continue when an exception is encountered on referral whois + lookups. Defaults to False. + asn_data (:obj:`dict`): Result from + :obj:`ipwhois.asn.IPASN.lookup` (required). + field_list (:obj:`list` of :obj:`str`): If provided, fields to + parse. Defaults to: + + :: + + ['name', 'handle', 'description', 'country', 'state', + 'city', 'address', 'postal_code', 'emails', 'created', + 'updated'] + + is_offline (:obj:`bool`): Whether to perform lookups offline. If + True, response and asn_data must be provided. Primarily used + for testing. Defaults to False. + + Returns: + dict: The IP whois lookup results + + :: + + { + 'query' (str) - The IP address + 'asn' (str) - The Autonomous System Number + 'asn_date' (str) - The ASN Allocation date + 'asn_registry' (str) - The assigned ASN registry + 'asn_cidr' (str) - The assigned ASN CIDR + 'asn_country_code' (str) - The assigned ASN country code + 'asn_description' (str) - The ASN description + 'nets' (list) - Dictionaries containing network + information which consists of the fields listed in the + ipwhois.whois.RIR_WHOIS dictionary. + 'raw' (str) - Raw whois results if the inc_raw parameter + is True. + 'referral' (dict) - Referral whois information if + get_referral is True and the server is not blacklisted. + Consists of fields listed in the ipwhois.whois.RWHOIS + dictionary. + 'raw_referral' (str) - Raw referral whois results if the + inc_raw parameter is True. + } + """ + + # Create the return dictionary. + results = { + 'query': self._net.address_str, + 'nets': [], + 'raw': None, + 'referral': None, + 'raw_referral': None + } + + # The referral server and port. Only used if get_referral is True. + referral_server = None + referral_port = 0 + + # Only fetch the response if we haven't already. + if response is None or (not is_offline and + asn_data['asn_registry'] is not 'arin'): + + log.debug('Response not given, perform WHOIS lookup for {0}' + .format(self._net.address_str)) + + # Retrieve the whois data. + response = self._net.get_whois( + asn_registry=asn_data['asn_registry'], retry_count=retry_count, + extra_blacklist=extra_blacklist + ) + + if get_referral: + + # Search for a referral server. + for match in re.finditer( + r'^ReferralServer:[^\S\n]+(.+:[0-9]+)$', + response, + re.MULTILINE + ): + + try: + + temp = match.group(1) + if 'rwhois://' not in temp: # pragma: no cover + raise ValueError + + temp = temp.replace('rwhois://', '').split(':') + + if int(temp[1]) > 65535: # pragma: no cover + raise ValueError + + referral_server = temp[0] + referral_port = int(temp[1]) + + except (ValueError, KeyError): # pragma: no cover + + continue + + break + + # Retrieve the referral whois data. + if get_referral and referral_server: + + log.debug('Perform referral WHOIS lookup') + + response_ref = None + + try: + + response_ref = self._net.get_whois( + asn_registry='', retry_count=retry_count, + server=referral_server, port=referral_port, + extra_blacklist=extra_blacklist + ) + + except (BlacklistError, WhoisLookupError): + + if ignore_referral_errors: + + pass + + else: + + raise + + if response_ref: + + log.debug('Parsing referral WHOIS data') + + if inc_raw: + + results['raw_referral'] = response_ref + + temp_rnet = self._parse_fields( + response_ref, + RWHOIS['fields'], + field_list=field_list + ) + + # Add the networks to the return dictionary. + results['referral'] = temp_rnet + + # If inc_raw parameter is True, add the response to return dictionary. + if inc_raw: + + results['raw'] = response + + nets = [] + + if asn_data['asn_registry'] == 'arin': + + nets_response = self._get_nets_arin(response) + + elif asn_data['asn_registry'] == 'lacnic': + + nets_response = self._get_nets_lacnic(response) + + else: + + nets_response = self._get_nets_other(response) + + nets.extend(nets_response) + + # Iterate through all of the network sections and parse out the + # appropriate fields for each. + log.debug('Parsing WHOIS data') + for index, net in enumerate(nets): + + section_end = None + if index + 1 < len(nets): + + section_end = nets[index + 1]['start'] + + try: + + dt_format = RIR_WHOIS[results['asn_registry']]['dt_format'] + + except KeyError: + + dt_format = None + + temp_net = self._parse_fields( + response, + RIR_WHOIS[asn_data['asn_registry']]['fields'], + section_end, + net['end'], + dt_format, + field_list + ) + + # Merge the net dictionaries. + net.update(temp_net) + + # The start and end values are no longer needed. + del net['start'], net['end'] + + # Add the networks to the return dictionary. + results['nets'] = nets + + return results diff --git a/env/lib/python3.7/site-packages/pip-18.1.dist-info/INSTALLER b/env/lib/python3.7/site-packages/pip-18.1.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip-18.1.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.7/site-packages/pip-18.1.dist-info/LICENSE.txt b/env/lib/python3.7/site-packages/pip-18.1.dist-info/LICENSE.txt new file mode 100644 index 0000000..d3379fa --- /dev/null +++ b/env/lib/python3.7/site-packages/pip-18.1.dist-info/LICENSE.txt @@ -0,0 +1,20 @@ +Copyright (c) 2008-2018 The pip developers (see AUTHORS.txt file) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/env/lib/python3.7/site-packages/pip-18.1.dist-info/METADATA b/env/lib/python3.7/site-packages/pip-18.1.dist-info/METADATA new file mode 100644 index 0000000..2e314aa --- /dev/null +++ b/env/lib/python3.7/site-packages/pip-18.1.dist-info/METADATA @@ -0,0 +1,70 @@ +Metadata-Version: 2.1 +Name: pip +Version: 18.1 +Summary: The PyPA recommended tool for installing Python packages. +Home-page: https://pip.pypa.io/ +Author: The pip developers +Author-email: pypa-dev@groups.google.com +License: MIT +Keywords: distutils easy_install egg setuptools wheel virtualenv +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Topic :: Software Development :: Build Tools +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: Implementation :: CPython +Classifier: Programming Language :: Python :: Implementation :: PyPy +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* + +pip +=== + +The `PyPA recommended`_ tool for installing Python packages. + +.. image:: https://img.shields.io/pypi/v/pip.svg + :target: https://pypi.org/project/pip/ + +.. image:: https://img.shields.io/travis/pypa/pip/master.svg?label=travis-ci + :target: https://travis-ci.org/pypa/pip + +.. image:: https://img.shields.io/appveyor/ci/pypa/pip.svg?label=appveyor-ci + :target: https://ci.appveyor.com/project/pypa/pip/history + +.. image:: https://readthedocs.org/projects/pip/badge/?version=latest + :target: https://pip.pypa.io/en/latest + +* `Installation`_ +* `Documentation`_ +* `Changelog`_ +* `GitHub Page`_ +* `Issue Tracking`_ +* `User mailing list`_ +* `Dev mailing list`_ +* User IRC: #pypa on Freenode. +* Dev IRC: #pypa-dev on Freenode. + +Code of Conduct +--------------- + +Everyone interacting in the pip project's codebases, issue trackers, chat +rooms and mailing lists is expected to follow the `PyPA Code of Conduct`_. + +.. _PyPA recommended: https://packaging.python.org/en/latest/current/ +.. _Installation: https://pip.pypa.io/en/stable/installing.html +.. _Documentation: https://pip.pypa.io/en/stable/ +.. _Changelog: https://pip.pypa.io/en/stable/news.html +.. _GitHub Page: https://github.com/pypa/pip +.. _Issue Tracking: https://github.com/pypa/pip/issues +.. _User mailing list: https://groups.google.com/forum/#!forum/python-virtualenv +.. _Dev mailing list: https://groups.google.com/forum/#!forum/pypa-dev +.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + diff --git a/env/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD b/env/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD new file mode 100644 index 0000000..739feb3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip-18.1.dist-info/RECORD @@ -0,0 +1,614 @@ +pip/__init__.py,sha256=nO-iphoXiDoci_ZAMl-PG2zdd4Y7m88jBDILTYzwGy4,21 +pip/__main__.py,sha256=L3IHqBeasELUHvwy5CT_izVEMhM12tve289qut49DvU,623 +pip/_internal/__init__.py,sha256=b0jSFCCViGhB1RWni35_NMkH3Y-mbZrV648DGMagDjs,2869 +pip/_internal/build_env.py,sha256=zKhqmDMnrX5OTSNQ4xBw-mN5mTGVu6wjiNFW-ajWYEI,4797 +pip/_internal/cache.py,sha256=96_aKtDbwgLEVNgNabOT8GrFCYZEACedoiucqU5ccg8,6829 +pip/_internal/configuration.py,sha256=KMgG3ufFrUKX_QESi2cMVvFi47tl845Bg1ZkNthlWik,13243 +pip/_internal/download.py,sha256=c5Hkimq39eJdZ6DN0_0etjK43-0a5CK_W_3sVLqH87g,33300 +pip/_internal/exceptions.py,sha256=EIGotnq6qM2nbGtnlgZ8Xp5VfP2W4-9UOCzQGMwy5MY,8899 +pip/_internal/index.py,sha256=6CAtZ8QTLcpw0fJqQ9OPu-Os1ettLZtVY1pPSKia8r8,34789 +pip/_internal/locations.py,sha256=ujNrLnA04Y_EmSriO0nS6qkkw_BkPfobB_hdwIDPvpM,6307 +pip/_internal/pep425tags.py,sha256=TQhxOPss4RjxgyVgxpSRe31HaTcWmn-LVjWBbkvkjzk,10845 +pip/_internal/pyproject.py,sha256=fpO52MCa3w5xSlXIBXw39BDTGzP8G4570EW34hVvIKQ,5481 +pip/_internal/resolve.py,sha256=tdepxCewsXXNFKSIYGSxiLvzi1xCv7UVFT9jRCDO90A,13578 +pip/_internal/wheel.py,sha256=fg9E936DaI1LyrBPHqtzHG_WEVyuUwipHISkD6N3jNw,32007 +pip/_internal/cli/__init__.py,sha256=FkHBgpxxb-_gd6r1FjnNhfMOzAUYyXoXKJ6abijfcFU,132 +pip/_internal/cli/autocompletion.py,sha256=ptvsMdGjq42pzoY4skABVF43u2xAtLJlXAulPi-A10Y,6083 +pip/_internal/cli/base_command.py,sha256=ke6af4iWzrZoc3HtiPKnCZJvD6GlX8dRwBwpFCg1axc,9963 +pip/_internal/cli/cmdoptions.py,sha256=WoPPY1uHsDjA_NvZek8Mko38rxraD3pX8eZUkNKvk10,19468 +pip/_internal/cli/main_parser.py,sha256=Ga_kT7if-Gg0rmmRqlGEHW6JWVm9zwzO7igJm6RE9EI,2763 +pip/_internal/cli/parser.py,sha256=VZKUKJPbU6I2cHPLDOikin-aCx7OvLcZ3fzYp3xytd8,9378 +pip/_internal/cli/status_codes.py,sha256=F6uDG6Gj7RNKQJUDnd87QKqI16Us-t-B0wPF_4QMpWc,156 +pip/_internal/commands/__init__.py,sha256=CQAzhVx9ViPtqLNUvAeqnKj5iWfFEcqMx5RlZWjJ30c,2251 +pip/_internal/commands/check.py,sha256=CyeYH2kfDKSGSURoBfWtx-sTcZZQP-bK170NmKYlmsg,1398 +pip/_internal/commands/completion.py,sha256=hqvCvoxsIHjysiD7olHKTqK2lzE1_lS6LWn69kN5qyI,2929 +pip/_internal/commands/configuration.py,sha256=265HWuUxPggCNcIeWHA3p-LDDiRVnexwFgwmHGgWOHY,7125 +pip/_internal/commands/download.py,sha256=D_iGMp3xX2iD7KZYZAjXlYT3rf3xjwxyYe05KE-DVzE,6514 +pip/_internal/commands/freeze.py,sha256=VvS3G0wrm_9BH3B7Ex5msLL_1UQTtCq5G8dDI63Iemo,3259 +pip/_internal/commands/hash.py,sha256=K1JycsD-rpjqrRcL_ijacY9UKmI82pQcLYq4kCM4Pv0,1681 +pip/_internal/commands/help.py,sha256=MwBhPJpW1Dt3GfJV3V8V6kgAy_pXT0jGrZJB1wCTW-E,1090 +pip/_internal/commands/install.py,sha256=tKyzfo5bhDGLVTTQCQJ9PFnDjimQvEWnwIAI2XHpaac,21039 +pip/_internal/commands/list.py,sha256=n740MsR0cG34EuvGWMzdVl0uIA3UIYx1_95FUsTktN0,10272 +pip/_internal/commands/search.py,sha256=sLZ9icKMEEGekHvzRRZMiTd1zCFIZeDptyyU1mQCYzk,4728 +pip/_internal/commands/show.py,sha256=9EVh86vY0NZdlhT-wsuV-zq_MAV6qqV4S1Akn3wkUuw,6289 +pip/_internal/commands/uninstall.py,sha256=h0gfPF5jylDESx_IHgF6bZME7QAEOHzQHdn65GP-jrE,2963 +pip/_internal/commands/wheel.py,sha256=ZuVf_DMpKCUzBVstolvQPAeajQRC51Oky5_hDHzhhFs,7020 +pip/_internal/models/__init__.py,sha256=3DHUd_qxpPozfzouoqa9g9ts1Czr5qaHfFxbnxriepM,63 +pip/_internal/models/candidate.py,sha256=zq2Vb5l5JflrVX7smHTJHQciZWHyoJZuYTLeQa1G16c,741 +pip/_internal/models/format_control.py,sha256=aDbH4D2XuyaGjtRjTLQhNzClAcLZdJCKSHO8xbZSmFA,2202 +pip/_internal/models/index.py,sha256=YI1WlhWfS9mVPY0bIboA5la2pjJ2J0qgPJIbvdEjZBk,996 +pip/_internal/models/link.py,sha256=E61PvS2Wrmb9-zT-eAc_8_xI3C-89wJlpL8SL-mlQmg,3998 +pip/_internal/operations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/operations/check.py,sha256=ahcOg5p68nNow6_wy5prYYK0KZq22lm0CsJn8AyDMCI,4937 +pip/_internal/operations/freeze.py,sha256=lskaBcqf3bPZupG032fuLf76QYv5wpAQ6jsiXac56Bg,10450 +pip/_internal/operations/prepare.py,sha256=atoLFj3OD5KfXsa5dYBMC_mI06l068F5yZhF4jle1JA,14280 +pip/_internal/req/__init__.py,sha256=JnNZWvKUQuqAwHh64LCD3zprzWIVQEXChTo2UGHzVqo,2093 +pip/_internal/req/constructors.py,sha256=97WQp9Svh-Jw3oLZL9_57gJ3zihm5LnWlSRjOwOorDU,9573 +pip/_internal/req/req_file.py,sha256=ORA0GKUjGd6vy7pmBwXR55FFj4h_OxYykFQ6gHuWvt0,11940 +pip/_internal/req/req_install.py,sha256=ry1RtNNCefDHAnf3EeGMpea-9pC6Yk1uHzP0Q5p2Un0,34046 +pip/_internal/req/req_set.py,sha256=nE6oagXJSiQREuuebX3oJO5OHSOVUIlvLLilodetBzc,7264 +pip/_internal/req/req_tracker.py,sha256=zH28YHV5TXAVh1ZOEZi6Z1Edkiu26dN2tXfR6VbQ3B4,2370 +pip/_internal/req/req_uninstall.py,sha256=ORSPah64KOVrKo-InMM3zgS5HQqbl5TLHFnE_Lxstq8,16737 +pip/_internal/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_internal/utils/appdirs.py,sha256=SPfibHtvOKzD_sHrpEZ60HfLae3GharU4Tg7SB3c-XM,9120 +pip/_internal/utils/compat.py,sha256=LSAvzXcsGY2O2drKIPszR5Ja2G0kup__51l3bx1jR_Q,8015 +pip/_internal/utils/deprecation.py,sha256=yQTe6dyWlBfxSBrOv_MdRXF1RPLER_EWOp-pa2zLoZc,3021 +pip/_internal/utils/encoding.py,sha256=D8tmfStCah6xh9OLhH9mWLr77q4akhg580YHJMKpq3Y,1025 +pip/_internal/utils/filesystem.py,sha256=ZOIHbacJ-SJtuZru4GoA5DuSIYyeaE4G5kfZPf5cn1A,915 +pip/_internal/utils/glibc.py,sha256=prOrsBjmgkDE-hY4Pl120yF5MIlkkmGrFLs8XfIyT-w,3004 +pip/_internal/utils/hashes.py,sha256=rJk-gj6F-sHggXAG97dhynqUHFFgApyZLWgaG2xCHME,2900 +pip/_internal/utils/logging.py,sha256=BQeUDEER3zlK0O4yv6DBfz6TK3f9XoLXyDlnB0mZVf0,6295 +pip/_internal/utils/misc.py,sha256=YscDfBiFx1spYOtSgdI_5hnc5BZUysWAyz1aVL5y-48,29904 +pip/_internal/utils/models.py,sha256=DQYZSRhjvSdDTAaJLLCpDtxAn1S_-v_8nlNjv4T2jwY,1042 +pip/_internal/utils/outdated.py,sha256=BXtCMKR6gjTrvMfP3MWzZ1Y4ZU4qqoCfbRNqQCusVt8,5642 +pip/_internal/utils/packaging.py,sha256=Ru8ls_S8PPKR8RKEn7jMetENY_A9jPet1HlhTZwpFxU,2443 +pip/_internal/utils/setuptools_build.py,sha256=0blfscmNJW_iZ5DcswJeDB_PbtTEjfK9RL1R1WEDW2E,278 +pip/_internal/utils/temp_dir.py,sha256=n2FkVlwRX_hS61fYt3nSAh2e2V6CcZn_dfbPId1pAQE,2615 +pip/_internal/utils/typing.py,sha256=ztYtZAcqjCYDwP-WlF6EiAAskAsZBMMXtuqvfgZIlgQ,1139 +pip/_internal/utils/ui.py,sha256=FW8wdtc7DvNwJClGr_TvGZlqcoO482GYe0UY9nKmpso,13657 +pip/_internal/vcs/__init__.py,sha256=2Ct9ogOwzS6ZKKaEXKN2XDiBOiFHMcejnN1KM21mLrQ,16319 +pip/_internal/vcs/bazaar.py,sha256=rjskVmSSn68O7lC5JrGmDTWXneXFMMJJvj_bbdSM8QA,3669 +pip/_internal/vcs/git.py,sha256=n1cFBqTnLIcxAOClZMgOBqELjEjygDBPZ9z-Q7g0qVQ,12580 +pip/_internal/vcs/mercurial.py,sha256=jVTa0XQpFR6EiBcaqW4E4JjTce_t1tFnKRaIhaIPlS8,3471 +pip/_internal/vcs/subversion.py,sha256=vDLTfcjj0kgqcEsbPBfveC4CRxyhWiOjke-qN0Zr8CE,7676 +pip/_vendor/__init__.py,sha256=XnhkujjE1qUGRlYGYbIRrEGYYYBcNLBraE27HH48wYw,4756 +pip/_vendor/appdirs.py,sha256=BENKsvcA08IpccD9345-rMrg3aXWFA1q6BFEglnHg6I,24547 +pip/_vendor/distro.py,sha256=dOMrjIXv-3GmEbtP-NJc057Sv19P7ZAdke-v0TBeNio,42455 +pip/_vendor/ipaddress.py,sha256=2OgbkeAD2rLkcXqbcvof3J5R7lRwjNLoBySyTkBtKnc,79852 +pip/_vendor/pyparsing.py,sha256=My2ZwDJCEaZkZgZyG9gL--48RLGmf9vnVCTW93rhdYI,226342 +pip/_vendor/retrying.py,sha256=k3fflf5_Mm0XcIJYhB7Tj34bqCCPhUDkYbx1NvW2FPE,9972 +pip/_vendor/six.py,sha256=A08MPb-Gi9FfInI3IW7HimXFmEH2T2IPzHgDvdhZPRA,30888 +pip/_vendor/cachecontrol/__init__.py,sha256=6cRPchVqkAkeUtYTSW8qCetjSqJo-GxP-n4VMVDbvmc,302 +pip/_vendor/cachecontrol/_cmd.py,sha256=URGE0KrA87QekCG3SGPatlSPT571dZTDjNa-ZXX3pDc,1295 +pip/_vendor/cachecontrol/adapter.py,sha256=eBGAtVNRZgtl_Kj5JV54miqL9YND-D0JZPahwY8kFtY,4863 +pip/_vendor/cachecontrol/cache.py,sha256=1fc4wJP8HYt1ycnJXeEw5pCpeBL2Cqxx6g9Fb0AYDWQ,805 +pip/_vendor/cachecontrol/compat.py,sha256=kHNvMRdt6s_Xwqq_9qJmr9ou3wYMOMUMxPPcwNxT8Mc,695 +pip/_vendor/cachecontrol/controller.py,sha256=U7g-YwizQ2O5NRgK_MZreF1ntM4E49C3PuF3od-Vwz4,13698 +pip/_vendor/cachecontrol/filewrapper.py,sha256=vACKO8Llzu_ZWyjV1Fxn1MA4TGU60N5N3GSrAFdAY2Q,2533 +pip/_vendor/cachecontrol/heuristics.py,sha256=BFGHJ3yQcxvZizfo90LLZ04T_Z5XSCXvFotrp7Us0sc,4070 +pip/_vendor/cachecontrol/serialize.py,sha256=GebE34fgToyWwAsRPguh8hEPN6CqoG-5hRMXRsjVABQ,6954 +pip/_vendor/cachecontrol/wrapper.py,sha256=sfr9YHWx-5TwNz1H5rT6QOo8ggII6v3vbEDjQFwR6wc,671 +pip/_vendor/cachecontrol/caches/__init__.py,sha256=-gHNKYvaeD0kOk5M74eOrsSgIKUtC6i6GfbmugGweEo,86 +pip/_vendor/cachecontrol/caches/file_cache.py,sha256=8vrSzzGcdfEfICago1uSFbkumNJMGLbCdEkXsmUIExw,4177 +pip/_vendor/cachecontrol/caches/redis_cache.py,sha256=HxelMpNCo-dYr2fiJDwM3hhhRmxUYtB5tXm1GpAAT4Y,856 +pip/_vendor/certifi/__init__.py,sha256=5lCYV1iWxoirX1OAaSHkBYUuZGdcwEjEBS6DS_trL0s,63 +pip/_vendor/certifi/__main__.py,sha256=NaCn6WtWME-zzVWQ2j4zFyl8cY4knDa9CwtHNIeFPhM,53 +pip/_vendor/certifi/cacert.pem,sha256=XA-4HVBsOrBD5lfg-b3PiUzAvwUd2qlIzwXypIMIRGM,263074 +pip/_vendor/certifi/core.py,sha256=xPQDdG_siy5A7BfqGWa7RJhcA61xXEqPiSrw9GNyhHE,836 +pip/_vendor/chardet/__init__.py,sha256=YsP5wQlsHJ2auF1RZJfypiSrCA7_bQiRm3ES_NI76-Y,1559 +pip/_vendor/chardet/big5freq.py,sha256=D_zK5GyzoVsRes0HkLJziltFQX0bKCLOrFe9_xDvO_8,31254 +pip/_vendor/chardet/big5prober.py,sha256=kBxHbdetBpPe7xrlb-e990iot64g_eGSLd32lB7_h3M,1757 +pip/_vendor/chardet/chardistribution.py,sha256=3woWS62KrGooKyqz4zQSnjFbJpa6V7g02daAibTwcl8,9411 +pip/_vendor/chardet/charsetgroupprober.py,sha256=6bDu8YIiRuScX4ca9Igb0U69TA2PGXXDej6Cc4_9kO4,3787 +pip/_vendor/chardet/charsetprober.py,sha256=KSmwJErjypyj0bRZmC5F5eM7c8YQgLYIjZXintZNstg,5110 +pip/_vendor/chardet/codingstatemachine.py,sha256=VYp_6cyyki5sHgXDSZnXW4q1oelHc3cu9AyQTX7uug8,3590 +pip/_vendor/chardet/compat.py,sha256=PKTzHkSbtbHDqS9PyujMbX74q1a8mMpeQTDVsQhZMRw,1134 +pip/_vendor/chardet/cp949prober.py,sha256=TZ434QX8zzBsnUvL_8wm4AQVTZ2ZkqEEQL_lNw9f9ow,1855 +pip/_vendor/chardet/enums.py,sha256=Aimwdb9as1dJKZaFNUH2OhWIVBVd6ZkJJ_WK5sNY8cU,1661 +pip/_vendor/chardet/escprober.py,sha256=kkyqVg1Yw3DIOAMJ2bdlyQgUFQhuHAW8dUGskToNWSc,3950 +pip/_vendor/chardet/escsm.py,sha256=RuXlgNvTIDarndvllNCk5WZBIpdCxQ0kcd9EAuxUh84,10510 +pip/_vendor/chardet/eucjpprober.py,sha256=iD8Jdp0ISRjgjiVN7f0e8xGeQJ5GM2oeZ1dA8nbSeUw,3749 +pip/_vendor/chardet/euckrfreq.py,sha256=-7GdmvgWez4-eO4SuXpa7tBiDi5vRXQ8WvdFAzVaSfo,13546 +pip/_vendor/chardet/euckrprober.py,sha256=MqFMTQXxW4HbzIpZ9lKDHB3GN8SP4yiHenTmf8g_PxY,1748 +pip/_vendor/chardet/euctwfreq.py,sha256=No1WyduFOgB5VITUA7PLyC5oJRNzRyMbBxaKI1l16MA,31621 +pip/_vendor/chardet/euctwprober.py,sha256=13p6EP4yRaxqnP4iHtxHOJ6R2zxHq1_m8hTRjzVZ95c,1747 +pip/_vendor/chardet/gb2312freq.py,sha256=JX8lsweKLmnCwmk8UHEQsLgkr_rP_kEbvivC4qPOrlc,20715 +pip/_vendor/chardet/gb2312prober.py,sha256=gGvIWi9WhDjE-xQXHvNIyrnLvEbMAYgyUSZ65HUfylw,1754 +pip/_vendor/chardet/hebrewprober.py,sha256=c3SZ-K7hvyzGY6JRAZxJgwJ_sUS9k0WYkvMY00YBYFo,13838 +pip/_vendor/chardet/jisfreq.py,sha256=vpmJv2Bu0J8gnMVRPHMFefTRvo_ha1mryLig8CBwgOg,25777 +pip/_vendor/chardet/jpcntx.py,sha256=PYlNqRUQT8LM3cT5FmHGP0iiscFlTWED92MALvBungo,19643 +pip/_vendor/chardet/langbulgarianmodel.py,sha256=1HqQS9Pbtnj1xQgxitJMvw8X6kKr5OockNCZWfEQrPE,12839 +pip/_vendor/chardet/langcyrillicmodel.py,sha256=LODajvsetH87yYDDQKA2CULXUH87tI223dhfjh9Zx9c,17948 +pip/_vendor/chardet/langgreekmodel.py,sha256=8YAW7bU8YwSJap0kIJSbPMw1BEqzGjWzqcqf0WgUKAA,12688 +pip/_vendor/chardet/langhebrewmodel.py,sha256=JSnqmE5E62tDLTPTvLpQsg5gOMO4PbdWRvV7Avkc0HA,11345 +pip/_vendor/chardet/langhungarianmodel.py,sha256=RhapYSG5l0ZaO-VV4Fan5sW0WRGQqhwBM61yx3yxyOA,12592 +pip/_vendor/chardet/langthaimodel.py,sha256=8l0173Gu_W6G8mxmQOTEF4ls2YdE7FxWf3QkSxEGXJQ,11290 +pip/_vendor/chardet/langturkishmodel.py,sha256=W22eRNJsqI6uWAfwXSKVWWnCerYqrI8dZQTm_M0lRFk,11102 +pip/_vendor/chardet/latin1prober.py,sha256=S2IoORhFk39FEFOlSFWtgVybRiP6h7BlLldHVclNkU8,5370 +pip/_vendor/chardet/mbcharsetprober.py,sha256=AR95eFH9vuqSfvLQZN-L5ijea25NOBCoXqw8s5O9xLQ,3413 +pip/_vendor/chardet/mbcsgroupprober.py,sha256=h6TRnnYq2OxG1WdD5JOyxcdVpn7dG0q-vB8nWr5mbh4,2012 +pip/_vendor/chardet/mbcssm.py,sha256=SY32wVIF3HzcjY3BaEspy9metbNSKxIIB0RKPn7tjpI,25481 +pip/_vendor/chardet/sbcharsetprober.py,sha256=LDSpCldDCFlYwUkGkwD2oFxLlPWIWXT09akH_2PiY74,5657 +pip/_vendor/chardet/sbcsgroupprober.py,sha256=1IprcCB_k1qfmnxGC6MBbxELlKqD3scW6S8YIwdeyXA,3546 +pip/_vendor/chardet/sjisprober.py,sha256=IIt-lZj0WJqK4rmUZzKZP4GJlE8KUEtFYVuY96ek5MQ,3774 +pip/_vendor/chardet/universaldetector.py,sha256=qL0174lSZE442eB21nnktT9_VcAye07laFWUeUrjttY,12485 +pip/_vendor/chardet/utf8prober.py,sha256=IdD8v3zWOsB8OLiyPi-y_fqwipRFxV9Nc1eKBLSuIEw,2766 +pip/_vendor/chardet/version.py,sha256=sp3B08mrDXB-pf3K9fqJ_zeDHOCLC8RrngQyDFap_7g,242 +pip/_vendor/chardet/cli/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +pip/_vendor/chardet/cli/chardetect.py,sha256=DI8dlV3FBD0c0XA_y3sQ78z754DUv1J8n34RtDjOXNw,2774 +pip/_vendor/colorama/__init__.py,sha256=V3-Hv_vOa-2lE5Q_0mGkdhZo-9e4XrGTW_44cU81qQY,240 +pip/_vendor/colorama/ansi.py,sha256=Fi0un-QLqRm-v7o_nKiOqyC8PapBJK7DLV_q9LKtTO0,2524 +pip/_vendor/colorama/ansitowin32.py,sha256=QrieYX2tsaWIO19P6biMa1zUCt-_abudoEp2_IdqZZU,9668 +pip/_vendor/colorama/initialise.py,sha256=cHqVJtb82OG7HUCxvQ2joG7N_CoxbIKbI_fgryZkj20,1917 +pip/_vendor/colorama/win32.py,sha256=5Hc7L1LabubrYDhdWAfRyzlt14ErP3YKDvf_zYaarLk,5426 +pip/_vendor/colorama/winterm.py,sha256=V7U7ojwG1q4n6PKripjEvW_htYQi5ueXSM3LUUoqqDY,6290 +pip/_vendor/distlib/__init__.py,sha256=GxRrh1augb66Eo9NB9jrdwQS02KcBypj9o_-C3oyKZI,581 +pip/_vendor/distlib/compat.py,sha256=xdNZmqFN5HwF30HjRn5M415pcC2kgXRBXn767xS8v-M,41404 +pip/_vendor/distlib/database.py,sha256=LqTcNkDyV4bWcc_qDxiYJHnXaNxFs1O1bFSAg_reaI0,50868 +pip/_vendor/distlib/index.py,sha256=Dd1kIV06XIdynNpKxHMMRRIKsXuoUsG7QIzntfVtZCI,21073 +pip/_vendor/distlib/locators.py,sha256=e4UaQSzNg5iG3PfQRH6lnVMfLOwhm2sVmGGRdjdB3ik,51657 +pip/_vendor/distlib/manifest.py,sha256=nQEhYmgoreaBZzyFzwYsXxJARu3fo4EkunU163U16iE,14811 +pip/_vendor/distlib/markers.py,sha256=6Ac3cCfFBERexiESWIOXmg-apIP8l2esafNSX3KMy-8,4387 +pip/_vendor/distlib/metadata.py,sha256=Ns92dqeMxopDPQsiEWnhMtd4RagJaA58lz8O_vjCxyk,39986 +pip/_vendor/distlib/resources.py,sha256=2FGv0ZHF14KXjLIlL0R991lyQQGcewOS4mJ-5n-JVnc,10766 +pip/_vendor/distlib/scripts.py,sha256=WEqXkpRvqR6oe-QlMRYg8gEJxXRWJeWn1GPc0ihZ4N0,16585 +pip/_vendor/distlib/t32.exe,sha256=ftub1bsSPUCOnBn-eCtcarKTk0N0CBEP53BumkIxWJE,92672 +pip/_vendor/distlib/t64.exe,sha256=iChOG627LWTHY8-jzSwlo9SYU5a-0JHwQu4AqDz8I68,102400 +pip/_vendor/distlib/util.py,sha256=FnzjaibVcIg1xOtET6QPNeqTnn3LcWLCjNOficMyGKA,59494 +pip/_vendor/distlib/version.py,sha256=_n7F6juvQGAcn769E_SHa7fOcf5ERlEVymJ_EjPRwGw,23391 +pip/_vendor/distlib/w32.exe,sha256=NPYPpt7PIjVqABEu1CzabbDyHHkJpuw-_qZq_48H0j0,89088 +pip/_vendor/distlib/w64.exe,sha256=Yb-qr1OQEzL8KRGTk-XHUZDwMSljfQeZnVoTk-K4e7E,99328 +pip/_vendor/distlib/wheel.py,sha256=W9aKwi4CQL_bQFYb8IcwH-c6WK-yku5P8SY3RGPv-Mk,39506 +pip/_vendor/distlib/_backport/__init__.py,sha256=bqS_dTOH6uW9iGgd0uzfpPjo6vZ4xpPZ7kyfZJ2vNaw,274 +pip/_vendor/distlib/_backport/misc.py,sha256=KWecINdbFNOxSOP1fGF680CJnaC6S4fBRgEtaYTw0ig,971 +pip/_vendor/distlib/_backport/shutil.py,sha256=VW1t3uYqUjWZH7jV-6QiimLhnldoV5uIpH4EuiT1jfw,25647 +pip/_vendor/distlib/_backport/sysconfig.cfg,sha256=swZKxq9RY5e9r3PXCrlvQPMsvOdiWZBTHLEbqS8LJLU,2617 +pip/_vendor/distlib/_backport/sysconfig.py,sha256=JdJ9ztRy4Hc-b5-VS74x3nUtdEIVr_OBvMsIb8O2sjc,26964 +pip/_vendor/distlib/_backport/tarfile.py,sha256=Ihp7rXRcjbIKw8COm9wSePV9ARGXbSF9gGXAMn2Q-KU,92628 +pip/_vendor/html5lib/__init__.py,sha256=Ztrn7UvF-wIFAgRBBa0ML-Gu5AffH3BPX_INJx4SaBI,1162 +pip/_vendor/html5lib/_ihatexml.py,sha256=3LBtJMlzgwM8vpQiU1TvGmEEmNH72sV0yD8yS53y07A,16705 +pip/_vendor/html5lib/_inputstream.py,sha256=bPUWcAfJScK4xkjQQaG_HsI2BvEVbFvI0AsodDYPQj0,32552 +pip/_vendor/html5lib/_tokenizer.py,sha256=YAaOEBD6qc5ISq9Xt9Nif1OFgcybTTfMdwqBkZhpAq4,76580 +pip/_vendor/html5lib/_utils.py,sha256=ismpASeqa2jqEPQjHUj8vReAf7yIoKnvLN5fuOw6nv0,4015 +pip/_vendor/html5lib/constants.py,sha256=4lmZWLtEPRLnl8NzftOoYTJdo6jpeMtP6dqQC0g_bWQ,83518 +pip/_vendor/html5lib/html5parser.py,sha256=g5g2ezkusHxhi7b23vK_-d6K6BfIJRbqIQmvQ9z4EgI,118963 +pip/_vendor/html5lib/serializer.py,sha256=yfcfBHse2wDs6ojxn-kieJjLT5s1ipilQJ0gL3-rJis,15758 +pip/_vendor/html5lib/_trie/__init__.py,sha256=8VR1bcgD2OpeS2XExpu5yBhP_Q1K-lwKbBKICBPf1kU,289 +pip/_vendor/html5lib/_trie/_base.py,sha256=uJHVhzif9S0MJXgy9F98iEev5evi_rgUk5BmEbUSp8c,930 +pip/_vendor/html5lib/_trie/datrie.py,sha256=EQpqSfkZRuTbE-DuhW7xMdVDxdZNZ0CfmnYfHA_3zxM,1178 +pip/_vendor/html5lib/_trie/py.py,sha256=wXmQLrZRf4MyWNyg0m3h81m9InhLR7GJ002mIIZh-8o,1775 +pip/_vendor/html5lib/filters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/html5lib/filters/alphabeticalattributes.py,sha256=lViZc2JMCclXi_5gduvmdzrRxtO5Xo9ONnbHBVCsykU,919 +pip/_vendor/html5lib/filters/base.py,sha256=z-IU9ZAYjpsVsqmVt7kuWC63jR11hDMr6CVrvuao8W0,286 +pip/_vendor/html5lib/filters/inject_meta_charset.py,sha256=egDXUEHXmAG9504xz0K6ALDgYkvUrC2q15YUVeNlVQg,2945 +pip/_vendor/html5lib/filters/lint.py,sha256=jk6q56xY0ojiYfvpdP-OZSm9eTqcAdRqhCoPItemPYA,3643 +pip/_vendor/html5lib/filters/optionaltags.py,sha256=8lWT75J0aBOHmPgfmqTHSfPpPMp01T84NKu0CRedxcE,10588 +pip/_vendor/html5lib/filters/sanitizer.py,sha256=4ON02KNjuqda1lCw5_JCUZxb0BzWR5M7ON84dtJ7dm0,26248 +pip/_vendor/html5lib/filters/whitespace.py,sha256=8eWqZxd4UC4zlFGW6iyY6f-2uuT8pOCSALc3IZt7_t4,1214 +pip/_vendor/html5lib/treeadapters/__init__.py,sha256=A0rY5gXIe4bJOiSGRO_j_tFhngRBO8QZPzPtPw5dFzo,679 +pip/_vendor/html5lib/treeadapters/genshi.py,sha256=CH27pAsDKmu4ZGkAUrwty7u0KauGLCZRLPMzaO3M5vo,1715 +pip/_vendor/html5lib/treeadapters/sax.py,sha256=BKS8woQTnKiqeffHsxChUqL4q2ZR_wb5fc9MJ3zQC8s,1776 +pip/_vendor/html5lib/treebuilders/__init__.py,sha256=AysSJyvPfikCMMsTVvaxwkgDieELD5dfR8FJIAuq7hY,3592 +pip/_vendor/html5lib/treebuilders/base.py,sha256=wQGp5yy22TNG8tJ6aREe4UUeTR7A99dEz0BXVaedWb4,14579 +pip/_vendor/html5lib/treebuilders/dom.py,sha256=SY3MsijXyzdNPc8aK5IQsupBoM8J67y56DgNtGvsb9g,8835 +pip/_vendor/html5lib/treebuilders/etree.py,sha256=aqIBOGj_dFYqBURIcTegGNBhAIJOw5iFDHb4jrkYH-8,12764 +pip/_vendor/html5lib/treebuilders/etree_lxml.py,sha256=9V0dXxbJYYq-Skgb5-_OL2NkVYpjioEb4CHajo0e9yI,14122 +pip/_vendor/html5lib/treewalkers/__init__.py,sha256=yhXxHpjlSqfQyUag3v8-vWjMPriFBU8YRAPNpDgBTn8,5714 +pip/_vendor/html5lib/treewalkers/base.py,sha256=ouiOsuSzvI0KgzdWP8PlxIaSNs9falhbiinAEc_UIJY,7476 +pip/_vendor/html5lib/treewalkers/dom.py,sha256=EHyFR8D8lYNnyDU9lx_IKigVJRyecUGua0mOi7HBukc,1413 +pip/_vendor/html5lib/treewalkers/etree.py,sha256=sz1o6mmE93NQ53qJFDO7HKyDtuwgK-Ay3qSFZPC6u00,4550 +pip/_vendor/html5lib/treewalkers/etree_lxml.py,sha256=sY6wfRshWTllu6n48TPWpKsQRPp-0CQrT0hj_AdzHSU,6309 +pip/_vendor/html5lib/treewalkers/genshi.py,sha256=4D2PECZ5n3ZN3qu3jMl9yY7B81jnQApBQSVlfaIuYbA,2309 +pip/_vendor/idna/__init__.py,sha256=9Nt7xpyet3DmOrPUGooDdAwmHZZu1qUAy2EaJ93kGiQ,58 +pip/_vendor/idna/codec.py,sha256=lvYb7yu7PhAqFaAIAdWcwgaWI2UmgseUua-1c0AsG0A,3299 +pip/_vendor/idna/compat.py,sha256=R-h29D-6mrnJzbXxymrWUW7iZUvy-26TQwZ0ij57i4U,232 +pip/_vendor/idna/core.py,sha256=OwI5R_uuXU4PlOSoG8cjaMPA1hhdGGjjZ8I2MZhSPxo,11858 +pip/_vendor/idna/idnadata.py,sha256=zwxvoSsYqPHNa6xzXWHizXpDC28JJMGXRinhJ4Gkcz0,39285 +pip/_vendor/idna/intranges.py,sha256=TY1lpxZIQWEP6tNqjZkFA5hgoMWOj1OBmnUG8ihT87E,1749 +pip/_vendor/idna/package_data.py,sha256=Vt9rtr32BzO7O25rypo8nzAs3syTJhG1ojU3J-s2RFo,21 +pip/_vendor/idna/uts46data.py,sha256=czULzYN5Lr9K5MmOH-1g3CJY7QPjGeHjYmC3saJ_BHk,197803 +pip/_vendor/lockfile/__init__.py,sha256=Tqpz90DwKYfhPsfzVOJl84TL87pdFE5ePNHdXAxs4Tk,9371 +pip/_vendor/lockfile/linklockfile.py,sha256=C7OH3H4GdK68u4FQgp8fkP2kO4fyUTSyj3X6blgfobc,2652 +pip/_vendor/lockfile/mkdirlockfile.py,sha256=e3qgIL-etZMLsS-3ft19iW_8IQ360HNkGOqE3yBKsUw,3096 +pip/_vendor/lockfile/pidlockfile.py,sha256=ukH9uk6NFuxyVmG5QiWw4iKq3fT7MjqUguX95avYPIY,6090 +pip/_vendor/lockfile/sqlitelockfile.py,sha256=o2TMkMRY0iwn-iL1XMRRIFStMUkS4i3ajceeYNntKFg,5506 +pip/_vendor/lockfile/symlinklockfile.py,sha256=ABwXXmvTHvCl5viPblShL3PG-gGsLiT1roAMfDRwhi8,2616 +pip/_vendor/msgpack/__init__.py,sha256=y0bk2YbzK6J2e0J_dyreN6nD7yM2IezT6m_tU2h-Mdg,1677 +pip/_vendor/msgpack/_version.py,sha256=dN7wVIjbyuQIJ35B2o6gymQNDLPlj_7-uTfgCv7KErM,20 +pip/_vendor/msgpack/exceptions.py,sha256=lPkAi_u12NlFajDz4FELSHEdfU8hrR3zeTvKX8aQuz4,1056 +pip/_vendor/msgpack/fallback.py,sha256=h0ll8xnq12mI9PuQ9Qd_Ihtt08Sp8L0JqhG9KY8Vyjk,36411 +pip/_vendor/packaging/__about__.py,sha256=mH-sMIEu48PzdYakZ6Y6OBzL3TlSetzz1fQSkCXiy30,720 +pip/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 +pip/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 +pip/_vendor/packaging/_structures.py,sha256=DCpKtb7u94_oqgVsIJQTrTyZcb3Gz7sSGbk9vYDMME0,1418 +pip/_vendor/packaging/markers.py,sha256=ftZegBU5oEmulEKApDGEPgti2lYIchFQHAfH9tZy3_U,8221 +pip/_vendor/packaging/requirements.py,sha256=xIWdoZXVKhUHxqFP5xmnKylM7NHXQS48hUfIIX1PvY0,4439 +pip/_vendor/packaging/specifiers.py,sha256=pFp716eLYBRt0eLNsy6cnWD9dyMKq-Zag7bsLbLv4Fs,28026 +pip/_vendor/packaging/utils.py,sha256=c9obOpok2CpKDApkc2M5ma0YFnT-jtt4I6XI4F0jYiI,1580 +pip/_vendor/packaging/version.py,sha256=MKL8nbKLPLGPouIwFvwSVnYRzNpkMo5AIcsa6LGqDF8,12219 +pip/_vendor/pep517/__init__.py,sha256=GH4HshnLERtjAjkY0zHoz3f7-35UcIvr27iFWSOUazU,82 +pip/_vendor/pep517/_in_process.py,sha256=iWpagFk2GhNBbvl-Ca2RagfD0ALuits4WWSM6nQMTdg,5831 +pip/_vendor/pep517/check.py,sha256=Yp2NHW71DIOCgkFb7HKJOzKmsum_s_OokRP6HnR3bTg,5761 +pip/_vendor/pep517/colorlog.py,sha256=2AJuPI_DHM5T9IDgcTwf0E8suyHAFnfsesogr0AB7RQ,4048 +pip/_vendor/pep517/compat.py,sha256=4SFG4QN-cNj8ebSa0wV0HUtEEQWwmbok2a0uk1gYEOM,631 +pip/_vendor/pep517/envbuild.py,sha256=osRsJVd7hir1w_uFXiVeeWxfJ3iYhwxsKRgNBWpqtCI,5672 +pip/_vendor/pep517/wrappers.py,sha256=RhgWm-MLxpYPgc9cZ3-A3ToN99ZzgM8-ia4FDB58koM,5018 +pip/_vendor/pkg_resources/__init__.py,sha256=ykZI7-YBIAQ7ztWf0RskP8Oy1VQU88o-16PJbIMCtLg,103915 +pip/_vendor/pkg_resources/py31compat.py,sha256=CRk8fkiPRDLsbi5pZcKsHI__Pbmh_94L8mr9Qy9Ab2U,562 +pip/_vendor/progress/__init__.py,sha256=Hv3Y8Hr6RyM34NdZkrZQWMURjS2h5sONRHJSvZXWZgQ,3188 +pip/_vendor/progress/bar.py,sha256=hlkDAEv9pRRiWqR5XL6vIAgMG4u_dBGEW_8klQhBRq0,2942 +pip/_vendor/progress/counter.py,sha256=XtBuZY4yYmr50E2A_fAzjWhm0IkwaVwxNsNVYDE7nsw,1528 +pip/_vendor/progress/helpers.py,sha256=6FsBLh_xUlKiVua-zZIutCjxth-IO8FtyUj6I2tx9fg,2952 +pip/_vendor/progress/spinner.py,sha256=m7bASI2GUbLFG-PbAefdHtrrWWlJLFhhSBbw70gp2TY,1439 +pip/_vendor/pytoml/__init__.py,sha256=q12Xv23Tta44gtK4HGK68Gr4tKfciILidFPmPuoIqIo,92 +pip/_vendor/pytoml/core.py,sha256=9CrLLTs1PdWjEwRnYzt_i4dhHcZvGxs_GsMlYAX3iY4,509 +pip/_vendor/pytoml/parser.py,sha256=mcTzHB2GQGyK8KVwuQ0EraSz_78O36U60NqHBtgVmV0,11247 +pip/_vendor/pytoml/writer.py,sha256=-mSOVGaiGLrpj5BRR7czmquZXJGflcElHrwAd33J48A,3815 +pip/_vendor/requests/__init__.py,sha256=OrwNk1JwZGqIQ4JVGgMbfpstqey-oHS_Re_Dw6D4ciI,4209 +pip/_vendor/requests/__version__.py,sha256=rJ2xgNOLhjspGkNPfgXTBctqqvsf2uJMFTaE0rlVtbI,436 +pip/_vendor/requests/_internal_utils.py,sha256=Zx3PnEUccyfsB-ie11nZVAW8qClJy0gx1qNME7rgT18,1096 +pip/_vendor/requests/adapters.py,sha256=y5DISepvSsGlu3II_VUsdgKBej1dGY4b5beRrTE2tsI,21428 +pip/_vendor/requests/api.py,sha256=zub9ENcEUT2m9gwgBgqH5RIRDfrx2kwRpZ7L6hX3mcw,6261 +pip/_vendor/requests/auth.py,sha256=oRSQkBYcLkTEssudkzoR1UW1Glb1ts3p1RWusgHf1YU,10208 +pip/_vendor/requests/certs.py,sha256=nXRVq9DtGmv_1AYbwjTu9UrgAcdJv05ZvkNeaoLOZxY,465 +pip/_vendor/requests/compat.py,sha256=7EC6fZY4dJDxuBQnqUGwe13OTZ3VLGO3QfOApE5lE3I,1998 +pip/_vendor/requests/cookies.py,sha256=olUaLeNci_z1K-Bn5PeEKllSspmQqN9-s8Ug7CasaPE,18346 +pip/_vendor/requests/exceptions.py,sha256=-mLam3TAx80V09EaH3H-ZxR61eAVuLRZ8zgBBSLjK44,3197 +pip/_vendor/requests/help.py,sha256=T4K-Oo_FS9fxF8NHVR8hxMwFo71gIkRM7UddCc9vH7Y,3669 +pip/_vendor/requests/hooks.py,sha256=HXAHoC1FNTFRZX6-lNdvPM7Tst4kvGwYTN-AOKRxoRU,767 +pip/_vendor/requests/models.py,sha256=3fmmYdDW7U18SrVeZaseHuk8KPI-7vLp_435DY3ejes,34160 +pip/_vendor/requests/packages.py,sha256=njJmVifY4aSctuW3PP5EFRCxjEwMRDO6J_feG2dKWsI,695 +pip/_vendor/requests/sessions.py,sha256=71MK2HCadovka1vAx9dyDFWAuw69KgRPRBpd0HWSEAo,27829 +pip/_vendor/requests/status_codes.py,sha256=pgw-xlnxO5zHQWn3fKps2cxwQehKzPxEbdhIrMQe6Ec,4128 +pip/_vendor/requests/structures.py,sha256=zoP8qly2Jak5e89HwpqjN1z2diztI-_gaqts1raJJBc,2981 +pip/_vendor/requests/utils.py,sha256=3OxbbLUQFVdm84fdBD9nduXvhw6hIzj59mhvBomKuJI,30156 +pip/_vendor/urllib3/__init__.py,sha256=DZucS8tlzGYKmK5FIsyUViMghpCq_0_0Ouvm_Jp9GNc,2853 +pip/_vendor/urllib3/_collections.py,sha256=iNeAU_we9L3lMGRUKKdq24Mf7o050TXP5U4Jm9AzAY4,10841 +pip/_vendor/urllib3/connection.py,sha256=My76qeWMDkV-KP1l3iChXHOE7J-ZCaUdP3sPIiLA2uE,14485 +pip/_vendor/urllib3/connectionpool.py,sha256=w20OwKdIqk6f8FIl6QGgn6jf9gZ0-tmgH7VPxnpEgkQ,35464 +pip/_vendor/urllib3/exceptions.py,sha256=rFeIfBNKC8KJ61ux-MtJyJlEC9G9ggkmCeF751JwVR4,6604 +pip/_vendor/urllib3/fields.py,sha256=D_TE_SK15YatdbhWDMN0OE3X6UCJn1RTkANINCYOobE,5943 +pip/_vendor/urllib3/filepost.py,sha256=40CROlpRKVBpFUkD0R6wJf_PpvbcRQRFUu0OOQlFkKM,2436 +pip/_vendor/urllib3/poolmanager.py,sha256=FHBjb7odbP2LyQRzeitgpuh1AQAPyegzmrm2b3gSZlY,16821 +pip/_vendor/urllib3/request.py,sha256=fwjlq5nQfcUa7aoncR25z6-fJAX_oNTcPksKKGjBm38,5996 +pip/_vendor/urllib3/response.py,sha256=uAuOTZSuTodzvQWIDCZghDoKmZ2bKbgIRCfaVIIZfn8,24667 +pip/_vendor/urllib3/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/appengine.py,sha256=Q3BDy5C_TrI-3cSyo0ELNGlNiK2eSVptQAQMdz4PH9Q,11197 +pip/_vendor/urllib3/contrib/ntlmpool.py,sha256=Q9-rO5Rh2-IqyEd4ZicpTDfMnOlf0IPPCkjhChBCjV4,4478 +pip/_vendor/urllib3/contrib/pyopenssl.py,sha256=cM7fVZJRrdLZsprcdWe3meM_hvq8LR73UNDveIMa-20,15480 +pip/_vendor/urllib3/contrib/securetransport.py,sha256=BqXSlChN9_hjCWgyN6JdcgvBUdc37QCCX4u3_8zE_9o,30309 +pip/_vendor/urllib3/contrib/socks.py,sha256=Iom0snbHkCuZbZ7Sle2Kueha1W0jYAJ0SyCOtePLaio,6391 +pip/_vendor/urllib3/contrib/_securetransport/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/contrib/_securetransport/bindings.py,sha256=x2kLSh-ASZKsun0FxtraBuLVe3oHuth4YW6yZ5Vof-w,17560 +pip/_vendor/urllib3/contrib/_securetransport/low_level.py,sha256=Umy5u-3Z957GirdapnicXVOpHaM4xdOZABJuJxfaeJA,12162 +pip/_vendor/urllib3/packages/__init__.py,sha256=nlChrGzkjCkmhCX9HrF_qHPUgosfsPQkVIJxiiLhk9g,109 +pip/_vendor/urllib3/packages/ordered_dict.py,sha256=VQaPONfhVMsb8B63Xg7ZOydJqIE_jzeMhVN3Pec6ogw,8935 +pip/_vendor/urllib3/packages/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 +pip/_vendor/urllib3/packages/backports/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pip/_vendor/urllib3/packages/backports/makefile.py,sha256=r1IADol_pBBq2Y1ub4CPyuS2hXuShK47nfFngZRcRhI,1461 +pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py,sha256=WBVbxQBojNAxfZwNavkox3BgJiMA9BJmm-_fwd0jD_o,688 +pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py,sha256=XCW0ydHg171GfOqNbvUAnRzQ0lc0twp5-dIlolgf4RM,5719 +pip/_vendor/urllib3/util/__init__.py,sha256=6Ran4oAVIy40Cu_oEPWnNV9bwF5rXx6G1DUZ7oehjPY,1044 +pip/_vendor/urllib3/util/connection.py,sha256=8K1VXm8BHsM3QATJJGBNRa_MStkzDy1Da2IaPAaCU8c,4279 +pip/_vendor/urllib3/util/queue.py,sha256=myTX3JDHntglKQNBf3b6dasHH-uF-W59vzGSQiFdAfI,497 +pip/_vendor/urllib3/util/request.py,sha256=H5_lrHvtwl2U2BbT1UYN9HpruNc1gsNFlz2njQmhPrQ,3705 +pip/_vendor/urllib3/util/response.py,sha256=SSNL888W-MQ8t3HAi44kNGgF682p6H__ytEXzBYxV_M,2343 +pip/_vendor/urllib3/util/retry.py,sha256=tlxiEq8OU2BSenPpPjYYO1URne8A-qTEgaykam6rZPg,15104 +pip/_vendor/urllib3/util/ssl_.py,sha256=iHJopgSv8_vXfmGg3lOsTS3ldMD9zhe130huHZxQEGU,14022 +pip/_vendor/urllib3/util/timeout.py,sha256=7lHNrgL5YH2cI1j-yZnzV_J8jBlRVdmFhQaNyM1_2b8,9757 +pip/_vendor/urllib3/util/url.py,sha256=qCY_HHUXvo05wAsEERALgExtlgxLnAHSQ7ce1b-g3SM,6487 +pip/_vendor/urllib3/util/wait.py,sha256=_4vvsT1BTTpqxQYK-2kXVfGsUsVRiuc4R4F-0Bf5BPc,5468 +pip/_vendor/webencodings/__init__.py,sha256=qOBJIuPy_4ByYH6W_bNgJF-qYQ2DoU-dKsDu5yRWCXg,10579 +pip/_vendor/webencodings/labels.py,sha256=4AO_KxTddqGtrL9ns7kAPjb0CcN6xsCIxbK37HY9r3E,8979 +pip/_vendor/webencodings/mklabels.py,sha256=GYIeywnpaLnP0GSic8LFWgd0UVvO_l1Nc6YoF-87R_4,1305 +pip/_vendor/webencodings/tests.py,sha256=OtGLyjhNY1fvkW1GvLJ_FV9ZoqC9Anyjr7q3kxTbzNs,6563 +pip/_vendor/webencodings/x_user_defined.py,sha256=yOqWSdmpytGfUgh_Z6JYgDNhoc-BAHyyeeT15Fr42tM,4307 +pip-18.1.dist-info/LICENSE.txt,sha256=ORqHhOMZ2uVDFHfUzJvFBPxdcf2eieHIDxzThV9dfPo,1090 +pip-18.1.dist-info/METADATA,sha256=D7pqBJTuqM9w_HTW91a0XGjLT9vynlBAE4pPCt_W_UE,2588 +pip-18.1.dist-info/WHEEL,sha256=8T8fxefr_r-A79qbOJ9d_AaEgkpCGmEPHc-gpCq5BRg,110 +pip-18.1.dist-info/entry_points.txt,sha256=S_zfxY25QtQDVY1BiLAmOKSkkI5llzCKPLiYOSEupsY,98 +pip-18.1.dist-info/top_level.txt,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip-18.1.dist-info/RECORD,, +../../../bin/pip,sha256=GJRRYxCMPyWhKt5YOlES-ErqfPnxSoQhfiQ-bkzU_bM,258 +../../../bin/pip3,sha256=GJRRYxCMPyWhKt5YOlES-ErqfPnxSoQhfiQ-bkzU_bM,258 +../../../bin/pip3.7,sha256=GJRRYxCMPyWhKt5YOlES-ErqfPnxSoQhfiQ-bkzU_bM,258 +pip-18.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +pip/__pycache__/__main__.cpython-37.pyc,, +pip/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/__pycache__/six.cpython-37.pyc,, +pip/_vendor/__pycache__/retrying.cpython-37.pyc,, +pip/_vendor/__pycache__/pyparsing.cpython-37.pyc,, +pip/_vendor/__pycache__/ipaddress.cpython-37.pyc,, +pip/_vendor/__pycache__/distro.cpython-37.pyc,, +pip/_vendor/__pycache__/appdirs.cpython-37.pyc,, +pip/_vendor/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc,, +pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc,, +pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc,, +pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc,, +pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc,, +pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc,, +pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc,, +pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc,, +pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/utils.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/structures.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/packages.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/models.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/help.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/certs.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/auth.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/api.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc,, +pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc,, +pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc,, +pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc,, +pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/counter.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/bar.cpython-37.pyc,, +pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc,, +pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/check.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc,, +pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/version.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc,, +pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc,, +pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc,, +pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc,, +pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc,, +pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/core.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/codec.cpython-37.pyc,, +pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc,, +pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc,, +pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc,, +pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc,, +pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc,, +pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc,, +pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc,, +pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/version.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/util.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/index.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/database.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc,, +pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc,, +pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/version.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc,, +pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc,, +pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/certifi/__pycache__/core.cpython-37.pyc,, +pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc,, +pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc,, +pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc,, +pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/__pycache__/wheel.cpython-37.pyc,, +pip/_internal/__pycache__/resolve.cpython-37.pyc,, +pip/_internal/__pycache__/pyproject.cpython-37.pyc,, +pip/_internal/__pycache__/pep425tags.cpython-37.pyc,, +pip/_internal/__pycache__/locations.cpython-37.pyc,, +pip/_internal/__pycache__/index.cpython-37.pyc,, +pip/_internal/__pycache__/exceptions.cpython-37.pyc,, +pip/_internal/__pycache__/download.cpython-37.pyc,, +pip/_internal/__pycache__/configuration.cpython-37.pyc,, +pip/_internal/__pycache__/cache.cpython-37.pyc,, +pip/_internal/__pycache__/build_env.cpython-37.pyc,, +pip/_internal/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/git.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc,, +pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/utils/__pycache__/ui.cpython-37.pyc,, +pip/_internal/utils/__pycache__/typing.cpython-37.pyc,, +pip/_internal/utils/__pycache__/temp_dir.cpython-37.pyc,, +pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc,, +pip/_internal/utils/__pycache__/packaging.cpython-37.pyc,, +pip/_internal/utils/__pycache__/outdated.cpython-37.pyc,, +pip/_internal/utils/__pycache__/models.cpython-37.pyc,, +pip/_internal/utils/__pycache__/misc.cpython-37.pyc,, +pip/_internal/utils/__pycache__/logging.cpython-37.pyc,, +pip/_internal/utils/__pycache__/hashes.cpython-37.pyc,, +pip/_internal/utils/__pycache__/glibc.cpython-37.pyc,, +pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc,, +pip/_internal/utils/__pycache__/encoding.cpython-37.pyc,, +pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc,, +pip/_internal/utils/__pycache__/compat.cpython-37.pyc,, +pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc,, +pip/_internal/utils/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_uninstall.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_set.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_install.cpython-37.pyc,, +pip/_internal/req/__pycache__/req_file.cpython-37.pyc,, +pip/_internal/req/__pycache__/constructors.cpython-37.pyc,, +pip/_internal/req/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/operations/__pycache__/prepare.cpython-37.pyc,, +pip/_internal/operations/__pycache__/freeze.cpython-37.pyc,, +pip/_internal/operations/__pycache__/check.cpython-37.pyc,, +pip/_internal/operations/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/models/__pycache__/link.cpython-37.pyc,, +pip/_internal/models/__pycache__/index.cpython-37.pyc,, +pip/_internal/models/__pycache__/format_control.cpython-37.pyc,, +pip/_internal/models/__pycache__/candidate.cpython-37.pyc,, +pip/_internal/models/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/commands/__pycache__/wheel.cpython-37.pyc,, +pip/_internal/commands/__pycache__/uninstall.cpython-37.pyc,, +pip/_internal/commands/__pycache__/show.cpython-37.pyc,, +pip/_internal/commands/__pycache__/search.cpython-37.pyc,, +pip/_internal/commands/__pycache__/list.cpython-37.pyc,, +pip/_internal/commands/__pycache__/install.cpython-37.pyc,, +pip/_internal/commands/__pycache__/help.cpython-37.pyc,, +pip/_internal/commands/__pycache__/hash.cpython-37.pyc,, +pip/_internal/commands/__pycache__/freeze.cpython-37.pyc,, +pip/_internal/commands/__pycache__/download.cpython-37.pyc,, +pip/_internal/commands/__pycache__/configuration.cpython-37.pyc,, +pip/_internal/commands/__pycache__/completion.cpython-37.pyc,, +pip/_internal/commands/__pycache__/check.cpython-37.pyc,, +pip/_internal/commands/__pycache__/__init__.cpython-37.pyc,, +pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc,, +pip/_internal/cli/__pycache__/parser.cpython-37.pyc,, +pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc,, +pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc,, +pip/_internal/cli/__pycache__/base_command.cpython-37.pyc,, +pip/_internal/cli/__pycache__/autocompletion.cpython-37.pyc,, +pip/_internal/cli/__pycache__/__init__.cpython-37.pyc,, diff --git a/env/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL b/env/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL new file mode 100644 index 0000000..1001235 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip-18.1.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.32.1) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/env/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt b/env/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt new file mode 100644 index 0000000..f5809cb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip-18.1.dist-info/entry_points.txt @@ -0,0 +1,5 @@ +[console_scripts] +pip = pip._internal:main +pip3 = pip._internal:main +pip3.7 = pip._internal:main + diff --git a/env/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt b/env/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip-18.1.dist-info/top_level.txt @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.7/site-packages/pip/__init__.py b/env/lib/python3.7/site-packages/pip/__init__.py new file mode 100644 index 0000000..ae265fa --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/__init__.py @@ -0,0 +1 @@ +__version__ = "18.1" diff --git a/env/lib/python3.7/site-packages/pip/__main__.py b/env/lib/python3.7/site-packages/pip/__main__.py new file mode 100644 index 0000000..0c223f8 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/__main__.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import + +import os +import sys + +# If we are running from a wheel, add the wheel to sys.path +# This allows the usage python pip-*.whl/pip install pip-*.whl +if __package__ == '': + # __file__ is pip-*.whl/pip/__main__.py + # first dirname call strips of '/__main__.py', second strips off '/pip' + # Resulting path is the name of the wheel itself + # Add that to sys.path so we can import pip + path = os.path.dirname(os.path.dirname(__file__)) + sys.path.insert(0, path) + +from pip._internal import main as _main # isort:skip # noqa + +if __name__ == '__main__': + sys.exit(_main()) diff --git a/env/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5e27cd269d793cd13cd329a12a648ee5fe8f9f9 GIT binary patch literal 152 zcmZ?b<>g`kf~fgwF`_{FF^B^Lj6jA15EpX*i4=w?h7`tN22G|a7DEd?LqAQ%Tio&S zWvNBQnfZC~@hcgMn1IT_#4la_lH3CQg3JQl%)H`~#GD-61KC&%#0&t<7bHsn literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..472803f08bfac6c2a7769ae63ed1b1466aab1fba GIT binary patch literal 406 zcmXv}u};G<5Vf7S4Q*2p;v0}Uv|ShxLJW*7Y!Q-WYPYzx6JtAq&U^^X$S-+i;un}W zNA#q7cfPy#?tE94BLr4`UOqJhq3`rK8inK*+;0H{5?CXHD~wZ4G^t1*vnrFh$acit zOR}Yh!9NZ=+~JDK3~Gfyl6ItL=K92psxd}#A}FxdGCP!V{DHcpOdio}@B{nM498Rc z>>J$%$&|5;3lA|>bHh~~3&v7pY&MM}#@20Uon*|xCr~7fkD1^5IA+Z9)sAnV6?4nO zOB@R2YHnmwSSy_x166zJLM*Ma3#RHIVM4n+Nzr~y8cw97BHvZ`Lhc;8J^ap>!Pq5m v=b#g~*7Mcdrrw6vt5od$ccs@>H=_m literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/__init__.py b/env/lib/python3.7/site-packages/pip/_internal/__init__.py new file mode 100644 index 0000000..276124d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/__init__.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python +from __future__ import absolute_import + +import locale +import logging +import os +import warnings + +import sys + +# 2016-06-17 barry@debian.org: urllib3 1.14 added optional support for socks, +# but if invoked (i.e. imported), it will issue a warning to stderr if socks +# isn't available. requests unconditionally imports urllib3's socks contrib +# module, triggering this warning. The warning breaks DEP-8 tests (because of +# the stderr output) and is just plain annoying in normal usage. I don't want +# to add socks as yet another dependency for pip, nor do I want to allow-stder +# in the DEP-8 tests, so just suppress the warning. pdb tells me this has to +# be done before the import of pip.vcs. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.filterwarnings("ignore", category=DependencyWarning) # noqa + +# We want to inject the use of SecureTransport as early as possible so that any +# references or sessions or what have you are ensured to have it, however we +# only want to do this in the case that we're running on macOS and the linked +# OpenSSL is too old to handle TLSv1.2 +try: + import ssl +except ImportError: + pass +else: + # Checks for OpenSSL 1.0.1 on MacOS + if sys.platform == "darwin" and ssl.OPENSSL_VERSION_NUMBER < 0x1000100f: + try: + from pip._vendor.urllib3.contrib import securetransport + except (ImportError, OSError): + pass + else: + securetransport.inject_into_urllib3() + +from pip._internal.cli.autocompletion import autocomplete +from pip._internal.cli.main_parser import parse_command +from pip._internal.commands import commands_dict +from pip._internal.exceptions import PipError +from pip._internal.utils import deprecation +from pip._internal.vcs import git, mercurial, subversion, bazaar # noqa +from pip._vendor.urllib3.exceptions import InsecureRequestWarning + +logger = logging.getLogger(__name__) + +# Hide the InsecureRequestWarning from urllib3 +warnings.filterwarnings("ignore", category=InsecureRequestWarning) + + +def main(args=None): + if args is None: + args = sys.argv[1:] + + # Configure our deprecation warnings to be sent through loggers + deprecation.install_warning_logger() + + autocomplete() + + try: + cmd_name, cmd_args = parse_command(args) + except PipError as exc: + sys.stderr.write("ERROR: %s" % exc) + sys.stderr.write(os.linesep) + sys.exit(1) + + # Needed for locale.getpreferredencoding(False) to work + # in pip._internal.utils.encoding.auto_decode + try: + locale.setlocale(locale.LC_ALL, '') + except locale.Error as e: + # setlocale can apparently crash if locale are uninitialized + logger.debug("Ignoring error %s when setting locale", e) + command = commands_dict[cmd_name](isolated=("--isolated" in cmd_args)) + return command.main(cmd_args) diff --git a/env/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..858e1d02e28f8a3b054502e9438ed00de05fe860 GIT binary patch literal 1798 zcmZuxUvJws5GN^FmL30#lekISq|Uk&$hM>d_750}VQUv)8M35Eu(cBk2#Uyfawy3q z>7)*vzI1!+XPEOiV9)&k`xty0u%~{7J?%(2MYBzWj>jYKba%fWb-!M(B6xyd?>zZr z2BE*q;_|70@+G|T9!7{FiaAPgfU(gDCjqgu6F7Eu1J}-_pk!w+@L+a$IrRe{BUb8H zsLOm>dPy)E)$EySP<@25c^9#n-ee)PGuV16yF%hp=wO^;@V`&gxY@pDqLoR-fUW^jdJu>NUQY zE(J?guk-8ajo^mW8~kRv94x0R!Ag27xRrK;uC+Izs?}f>s&Xdpu-g|ncz0UgYEd6; z(-xim83${W9H8~N*QTfISU00Xne(AyVUiAVp?1MG`!yS|jIt~qJ&Ht@WIgRAy(||D zHvKqKte1Xe>o+0(9}wS#_$}3%%u;vk7AI^B_qlr+L$$|v z3DMG+9DCGziO);p(qwK-E-*k{-hFL~KdWr*@9*t@-d&R#ovm#fJOSA*Gu;Mb_w*;0 zbtO~ESa}{toSjuSHWHu*Aa2m|-{|w&kt3z>U>0!LFCW>Lxt4YHKlVb5ZXnJ!N$_Zt%Lf#=_!-Bsz}?jRX# zOe@%kPkUKkJ^k1i?HeYUVj_$9-4N77h2iF4ByNNEr|`-y2!wsyaD3tsf?IYp@J*NC zHg1y@koNRC-d(?=t6_LFRB%(mP!RAG%OIc&P!x1tTsJF!+C?cAU>U4HCY#|2+{s*Q z4h84Q;YXWL4;z@fA%$an8b=9-G%q~?A<6a3w!PIwvY_eg)t!@AiaL}f z8b&mYXc;jJLRWfB?G#k=LrW(>Y}ITV=q-ER67L%q|6ZEYA!lD0V5MP4jrc$f7{ssE daKj@QB=($nY>3jv9`Q*HY{gi_HBxmN&OgRJ@{Irh literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/__pycache__/build_env.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc30dee3d8c0ae5eee685f9a966fa5c49cc97db9 GIT binary patch literal 5007 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/__pycache__/cache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4a0310196d7f8b5dd088898fed627721ccd47bd5 GIT binary patch literal 6792 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 SgaP_*)vDY0htJj3)&BvHR)xR- literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/__pycache__/configuration.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a781cf104e0f0e08428b37f738f65e7d71a81636 GIT binary patch literal 9791 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/__pycache__/pep425tags.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a31a925b094deb7fc539e66064a692cbcd8edf20 GIT binary patch literal 7247 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/__pycache__/pyproject.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1c3149e65ec5669d23deefa34e54a2903693f456 GIT binary patch literal 2671 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/base_command.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab16aba9d3021cf0a92c4bfc85164f73e69b4063 GIT binary patch literal 6267 zcmbVQOK%)kcCJ@(*_GY&1PUXaqBeHKR>{EP@$w6Cj)XglvNBf*|X=3Xs(x|G(v7-x zALl;nobP<+-mTRf4L|pH*S`7hYnt|7R5v{Lor z+;p4qMfajASEEbuW%shm*P<)&RrjjO*Q0Ck+wR-(ygRST6HzO^?p{~H#eGw)s`#pV!mM$m!^(>A0f_Y)w zOSx#H&gsNK+7n@#WGzEZEvCsv*nOlbmVKTvF5g<~1wO{<-eVhnKN8tzEb2W-dF%_p zc&i`__g7XPt;o6MmHS^VJz87!?yfC8yyx9pTJiFh((2mc;{DZCSzBv=-hT9?J*uDn za%tu9+9wb1x4-n-j~;su9<8%?|D($ z?P4wrZFiaQdOYpQdO`;qg#+gGe6b1P$zIs=wi&0>@H(5U^OVN@;_KzFy~WS&FMjT= zthL)q?N3o_=ikkbWNCCx9s2S|KNFdc@nn=R&DCLvMxc|$xmIAn;tW_@B`^c)dmZ*x z4GKXKIXfr?_V=1w4$6Upw-e~lzZyS}VcHKm243_l;IZ*6;>kFYp|%C%7WzKrj16N} z6Xw1a7*xVz4Pp3yU)nQ7VM7}lzt)GER}3s_Jt!S&v)Z01?1M7O#i4nK9-bpA2USto zs!`pcu}8ASgZj`q)L}##7FB2u3Rkn{)$Bp5Bn$lv-&R`cV9Ogv8VfTB0&f#a?B$9t zt;CO+tOP9U@KC9~v_n`58PUMOc=@?ztqJ}X_Qg+Aa*-0+vn+XDkaj$e6U@n?`s5sj z<@cZ-^eLr{iBz?$j;-oHNGfgt=uM6sQ#FhsM617y%R|(4Ln0 z^`VhKfuI`tRw*!Em{10N%jOR#9a>%)Z-+mo6eSz)O7`v0o`T$>2v07rWtJ9 z;O}E6vOwZlYm!%}R92n5Amn_G%0`+&Ibr3}+DgNOe?XNr!TTBXE+0r*9ma($!v4dJ zU0K1G0ET#~vLwQo0pVo<3cj-|OZ1|}*hz|S(?g5p_c3}I4Kb7kP*dPHX_8W|Lz$YA zf1;|g9B`F-2Zu{s|X#aT2*5(JO17$ zx{twvK!cQCef26bFlFsPAL@sMEqWU#contM$pO^oT{={?c#8_JEtCH#gd;qeLL*}U zN2c83!g2rc+$G3O;8AnWqQg)-fX*H2-xzzwo<20T=rQI{@0o%?#zeV*2VCTZsY3_1 zO8n!%5cXC%Fh8WS!@mlwg9_yibyZ(b^;P~I`q#4WM15aFI&shliUe0;@?c7wqTEY; zaC^6jHB1i;tik~7%?wR3yKnH{4&mvaKq9GHnmGN`;s2>?dzP*ZnlzG_8(RBVH%6P- zIzuQOlwW{RiLnrVRE%^`hJtxkKw>HeD4!Fma|I-*3PK@yb#`u}){gidJP(O>nfykXtw2ic2C_MeVqw;J$7M?1T;s(pnM2{dsT zNKo51Uh3(;*3cRj zhsHkEPNV&qwt{iR^@Dc~u|DK(Kno|^u=FxaZ#~UI0my@0bX&D^GTWT+_J^oQ|%1NrY|JBm!<5lmI#m7sJ+JoDRX+H{@Nh+EfARM4-O}`_; zZN=4&sYY{tL>GeA!eI9PPKPPLZ-zWrz8s^n87 zS0r8p-f6=bi?9PWV`jTRN(?DD#Te2AOOsBRDc6NfN)xV%lSxBVa9If0dcVub&Uu}Z z1|@_toIDM$A(4}xv)%R7=fM)WIo|IHStCL{J|kWxvC^iWf#`C1CI~Ykd)`m@7+qs=cZq|+5`#Pnf?ifXV%BUi>^rAtfs_E#C-hh{`1G(o$?vlssAW zyk{WKc}q^0h&{>TW*7u4;eU<-|2ZXebV}WLLOCKRuO#G#6xY0tOh%v5Rty8o!f@uC zE4I}^-S{_-H7}v+h~+YhE{*TCePX&GnLz=(wxHsulAKyOrspHK(IMTTA31K)1LZ3| zfT`?!2rSX=X@7Bhue5VR=tIP%L->cGH7tUM6wxxhXQR&cKv@sWp-njV?9vnMnf*lD zSs3b&xVBe@UxDwySOxU6URZDFb5F^`>!8OK^e7F>V|nup^4pNV0|^`Q?_zb=X?5eZ z6MYM{k?nL2+0J^*smmCEjp%d5#HL5$* z$@k3Sg#QZO3a!r2$xG^#D}#@m=IHkYVxmnyYJ&YXDNbsVLkGNxwCN*u9fwLygh>nI zUXLjh>>x}P9LfhyL>LOgCHqmO6M!G;3v- zK5Fr0nqQX%RW*3{|CudgET4g5mhm)~TCF+=;rKu@K7*-bIn0P*vX02(oLBb1r%9l8 z6xooaGFd(fVl#eh1vrH$g2OI&@F%B}Y*!2s=XIJ8)p)mB~OD#WBF; z=dUpAB4$zNFKu$3Dm-z}(G#hM@CM+{o=HnZMaMv(sOVfT?e!@rdo`Y>dHxkcX2bxs za#cZA5zt29=K#EH-3ENsjjDn&1SX>rK^q{E z8V20}@mdcPpYOJ6Q1+t*$OhX1Fn|w@SERi1H<*A2ln@8ula$b2_%A6@i#BPge?!HW zNLqI8n~$;L2h_@m-mch0)P1x-{%h*+8%lmf$!n@QGm4r*D_d$&B2RR#f^4 z2bR0*Jk6agX&>}&{tf!~#z7I5;@2wjl-5CPfImYbt3)ZnPRy|Gfd4hs|1BlQD^)q= zT{ATN3!aSVk!@7(Xga65)(89wUgXv{`hvn+k0V~v_!iaHN9<++`hZJA{x-D`59Hq> zap~e}0Usp4L|8!Rs;)WQxu4YMK^j;0C+bSYz3@|+oFPH?a7~lbxDri87N?k6P7P;I zb|lIbrGAhH;IGXLu9Z{kEa!$q3v<3mR8o;fdFteNO1+d8$Tl^D>K{C2B!S#VbNUZ+A?1p*Xs_OJmUZuzpsl{VBX5$yy+5ZKg C0=jts literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/cmdoptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fce517bcbc7e20e73d29bf4c5cf81fd472c96b8e GIT binary patch literal 14988 zcmcgzX?PpQdBzP8Jakx=WW}-9v}Fo10s6MXNQx5(RF(nM;~rs>`EZhEBm-SqykKigma**;I7r%!(M{l3}7!Pu^orX?OM zX1|&FX6Bpkp5f{7@nQmh)z9Dm!q|mG;@{{c{<|H8r||W@m`Nl=qM8s%k+PGmR5g{P za@tN;)A-HUnO3%%WmwkEwer<`t57YpMyewW%h|=&Xmym!d3&riUL9{uR44eoVDD+| zt?uRWh`q11zq+5xMfH-1tA%Qr;a9}7)E^X}{uS{a@f>J7!*x~hJnBw~7sQLGdyru-i5g&OK;J7& z%fRx?#WnoSimnLo`%Z5AKCvUNi|-Qe7ax!l;=3{8NcDvHptyk+C&eq` zd+>Wod`Ns4zwZ(s5g*0xQ{rRdd+|HR7`{)uicea69DQ@u(+vB5@dKX#4Zr|7nK&g7`&X z{3Y?rOsfkF`-=D#@vGw3#IK9rz{nRF_M76j81~x?TVmK(dEDO-zl+&iV#x0?c*s~(NnkfB?c_x`i6uqXYq%hpJZ@G?Vn2s@YT$X*}Usmp0&z2h6l9oIi@SdQnLj&GU1H2kJ)6&tp@ zZrXOYVq8KuB~8zDjCE-_4b+={57D;eHx08+GdVeBw%gJXQ%2o%@Kvg70IM&H>(bwr z(lOem@}yTW+EzO%8x845W!gP_{FSbq3GcXlKTrt*M zOvz-?Od|9(vZCCkA zfaNhwP{J;y!|~P2%gZYZtE;v13m2Bd+$AP?II4fo5z*0MY~F3PunP-HxvG>3CoZop ztkmY`=FczG&MdBkMNidhZG|1UhSuX}UDY!EdDrokYXgv3?k+D<#p>G1rKNMV^K+}` z7ghn-fAP8H=W4(*|8#BT^3u}c(m6m!PS35>)}CADCh0k+TTjtq@CP%--+BCc58~k` zc9J_VWp^ZQq^_r~-HCGQj>MV7i+iu9cTzW#JLwyVTghbN<-^Y=c2Z!lbnxM#fxi{$ zca#It8v`pf-1SXa_qhS{n_-m82KJ-V0yl!kuoJ?n`v&vGlw-E!6z|?t#Hmxpmh5`m zpE*Hse~0#--;HJB55*0_4D}E5QP)yR<*=ZzXbMr&uu>+>@-)Jn#ukq0idqEKZ(mNR zL+JU9lQVv+Jp;}wGq2lrxxU?SHvN|$B_MxmG26}5ZEL3964Bt5b~oJDGPh(jvL4`0 zqH+O`L~bHEk=&b9cc9$cj4WPgL(=$q%XoYQ8?jYTV>^kDCO(|lfUhCauN1DQL`Gyq zu93c;_7i?`CxuN(-AJknJBiKI^~_G@X8Kklnea24S&|Lk0(g0XoA#4Va&HcosA>Td~;98l*TbF?Z`th-+wHJ8c0e zt_=38H)VY*B8R7YN5rBITsuwEfpRgtPP=VeU=ipbvt#?Dj~ExtBPKBemg-P%{71h; zz1#5h#_;e#Kd^7&2I;{hi)lkbx%dhqk#tCWhUUbZt`4JTm`6imriTd^%StkMKsSz9 zp|;+!Y*EuXuX4h6K{)SJCF&QB>*{E#;e>7%uRh!pV~H9BQf~|CO4@*q2fe!y?~&+0 z!@8tob@t0!)&Oj{m5JRAtZDWePMoYoEi%^C2En8ldb}1L8O{W{CTV^|)*kCy~3GOL}2p+f)vw>4h08m9lCda4O<#^>#eMEYZyi^AQdvYALB3 zFl~>#F&&Qqfp-9pM81&Bq{dQ3NJ%b8PGQ7VijATB9&ekY^O`y&EE^ugp#QoRJ&OQXF$c}6K3x2}TBs@WO7E_rG{sa9T7-`Q}(7&{R z-n7X%V6_JOgY~hg^py#a2mYg`<#N00H(jTERVoi=e3~H9s;O+QThlbLav3JlmMvIW zlg$0JAz}N0vRroDvXE`hXn|&A1)yf4F0NyD%gk@xlRVeKHf$WYw{D^9hyWUgaSX!_ z;3T@tI<6yUOO@c6c~~cEOX3Bl?=KmhFlWPS%eu8;)q6YFacl|aA(A6n`c=y`reXq5 zEtN*qz2LoYLKCDG5hN_cX?=vT@fCDi2AkOKDtf~Si@0Gof^@ydc@;4gUD+UJ8G3j#!l~}Z%+NC^t~TLKQLzFC zDFctn4|Cc9RF6@YA{Yfe6)c7b$Kz71$Y4C9he21?^uB^5rsC4o=GQPjG`L&cg6*Puw_G zcNHesb{#?cge5&Yw?Z!Jw6UOj2DM{5xSX*=*!-mq*Lj8Yk{071euJu+?6ZwByF5%gei z(}-BY(2)->&}~34^kDfGToiC^PcX34mIF@Vo#qm44%Tz68)o%S8cIA&1SjG}n~3L7 zO=3bm1KXnKiTB~bdET~o>P4=v0D{TPQV`RVg9Tb$e~I8_7y-8Y`M8jVC3uZYZ?JOF zyk@mJEyL-w*2xxaz@l(#Lz?v_Sq=y8KbXzX;g|vMOSam6kK8?KYu?5tV?<(ea9Oag z3>(4zUkoChSr7A3gD|^cyQcrz9-7O;s}fca%k|v)78Ny;*BJ>Yz=2>WZ15s2mleRS zh2K#wdt31QBk3k(;^CzsuZ4%G0xFkP16SY$6?Ne1{gH-e*JKg}AMOYF?%HoBpS+Q6 zB*cg)icvB4Y5}gr_)@T^T!sL87)R^Ia9qFEB2{@Bn8KtNCao~J9VXYqqzN_3@iVKh zpn67AD+;d3eT1S!*i7-ZjeuNq4UKZvIOdfQbJd&E#xbkJ)(55SlGTR#IksMcd)R5C zWR}*!9UxVHfJ$dE5zQl{H8l-MAmHW^TMQVLo@G&2Q1PGmdi(K6BvYvr3`QzB#!r|I zswcBim&y+_^bGFo$&AgRJ@O3mb4Wlq!j{AQ%Dc!SISvd692{RG8r3f~#$l}BFK>HZv-5@q1Q6}c~;qGpUn_T%O$wylZCg|hM;KhAV*2vRh2X2FO*ktkk#H@u*9Bct-!dE0 zSR@SJ%-|*DI4E-wiCo)-ylT~>WZU&D7*xc0E<7^}`5PU2FE1<`k3IN^af~I1y%mUZ zuk{?V4dl?7P|DD5h}jk7n()}B#fBzUHXgkH9uXqj%1iI*lsYj${71p?JihGp_r(Ol zfdKc_90Vi3M0!A8g9q9tS-6)0h`vDqB9^D#3oPmdJc8B&H71%N?St?(q87J>BLF2# z{vY`eY;d8R02$3bz_Nq6MV8y)1;PP_&xdVtw}^9*b}Pd&IihS^&X%W%LhdY- zL8&sd6(bmlx8fiQySGB*U(I7P3QO<~HiEH1oMDmh*BC!?cI z>*p9vzl8)F1Z$2c_0F$%PzuCp^UjG5AkQ*fO6{1_pn zJQfqk@hWdIlLQqx!4&|Zo2T0 z$D_9zy?L6lh4YtI*OulkE(A|sG}RU;2sx*EB!FbRf*^-V|+jtx$5agY`Anj^!* z@I|PmAN+JRF9pXJ9L`jcN{Sj0OGBjlNHo)Yn~Yp1MuwV)`$W-gINC2q^vS)6Lu-h8Y-zD54q1YO@dNb>>y zqq-sfd&{D&0vON%&!!jMu$#j?sJ3WFpIM~rKQdJt3K@?+83y|P|Ioq4Z0t9n1J!+d zbdaQSCBiXcz;GlkX|4zgq>E-q$!*1CV3(Ux-K1#Z<{X&9zp8*65S4e@zUw08Iw>ge z=C-+dvZP5ETUIbSqlwj>X_daXYFm zNiuY)43!z|AAHl6Kg`n+1uDZdwfOXzo=X4?&S?aSKl`+Z7DmYw-zDil=09>*$rK~8 z5{K9n3s0V)aGLGLsTmA3IoyNHh0b>Z9Wx^EQm=Xk5hk1(OeyNuOBklG&NROB_(u8R z9UOLSA}t8ZmJIGZhp54fe3v){8XaI%aF}oe{n!b{aZL_dw1XTCnaTlom-Cyq)sUa7 zQP5@jF`7>h?P&sulu~%sDN#*-Sc7$xuk6*|wrB|SXly$hC3U^2n<_b`saeK+fD0vyVrf_s9Gf5fD_}pXINa(}} zhty;=$Z=&qmh^7CS!CEdP&9M(x@^M;MVVHeL4``QZwUq=oIBwBDj;`3VcY*maUmk)*EeR?kD8?Tcy;goRR!Vu6B zh(RdQqJ(qH>>3-UWfMFSX&t|^ixZhqh&boN$YrN-AP0|wx*Ywg_fe@IZ*f4HVd+pa zR7GOO3<{s-D3yn~g_-LM#2s{Yl)%9Q5}V*@_%OtF|9c*RWhFiw! zk8uCr46vJn>!8eI9wIvtu_R@lm4!}2V~`2TyZASLhyTtRy0E3eBHRKuaW zt&e-uGy$H!MBx_&n9%_%F*#DreB??OA5O$41E(rRl&|T@a$H3|E{UM(IGlg*x(Ewe zm0&OY=%Irb^#H~+@4@{3r(vVi0gSIy(Ya2X`Gu)vrxp`JyhVXRbPgg#6i(4xV#})M zLRP$o2q$1r5HY$)NTG=!)SCkp$7H2ZF{U1#D#iYAZyb_(m`kJ#Nj+(NN?zsoo$rne zVX7E}duY%I_al!+$Z;6UiQe7_OuSvEFcsRce|@Wz8#>7{P7LEZg{X^H*KSWu8&jKI zde*5-x^v2EPrW7L4pMb^0CI0g_hIdq!CX`A?i3LXZblusjG?)eP2>e&!0QnUR>-@< zDU>SHdjI_`u9wckPTbYna3zGwH*rMTTf#Ygg$I(-bvw`j*mOrC z8;=#~9qUq#WoT8yXN+Vrb_;{H7y5*9z-kN!hjgmO&KBh%`&kY)=2>mbk%y(5H@Fp{ zl~OpaUnAd1y#qbZ22UBoX9rxxj97@n33mq=?5RU2t zxD7~@4ECRiya?6^)P@uG=zx&iqePu9_D?bCPEm0085b9^dUiebB6?vwjyvhtX`N0s z_+kUCN#Agwg#c~uB?>-97(mN3Pm$#u3_dyz4bZclq^cW)X}!z5i4p3t#{t4w4(F{Yk`4oN6G#U~u3v%jekRu(HeWC-X|g$*`e z$1OMM^Qk)#a_!TjGMet%@i{)7>yWnA zD~xAIgVWsuQt5SDnhu7>V(OGp#%#&m>fkV~5*&uGaV{~A{k_P}gaw?yb|CLl{{mje00VOaJWZrpFY6_U@iDm%vn8{7H4kAnM@9s zal@D-nuw0CdSJc5vBu24fy0f5Eo4Bxja6o{a`O zIZ26W4e{#Af@gnnrsJs@PKwSz?Mx!wPZpsUG4wk`OVK|(DZUEXYdKJ{dunX0NH-Jz zXq5^{i4f`woP9yyFdfWC@e3&&onVizNpfvZ+pyN_B`)a9Yv|sRx|{UHnxiY#k$cDHBnZJhS|hPk(D6F6S#L$8k8mJ6tf9$@!Vm<{Ejk=rBPS^# zFF*(ClX{8LI>Z67GlaHy1(*Co%9!JThSN*^w!zzQ;HedCnQk3M9#xsM zDd8PaRSi|~J(C(&1@F_V!9_mH#dS&$0tY;F-3}*4%Zs!j@l7RmOTmkDlmqh=kIm;K zbg=>o<0{kwM~a{%a>v^a&RF4gEYf)qDzpiJgp}-O8&b*JXB+B6~CEXKy7pQo5BM=VpE<(@5M(-7M^& z4#^ZgUJAD8Y6EAWD1aul!8&@WcMuo}3nGKm13&skZFHH@f=q#fcFzE{PkY#eVk}Tmx<6;eF!fcF^4${5}iiS zxB`yfAR;5vK$MO=3px|hXGl7#fF0B)B|sCah)6vEO~qKaW|FTt3-wDQ4bgQ2gdNJ! z_wx+ow^2+MCB3;XC^-?m^9rRGd@eGO*h9ijETV;z6FO02)*5C5=MWy!F0@}bewA?8 zC~%DC3T?7BY@*0TW})Phe!9`tJM6@01E_T}p2i1UuQJl+m0(ZgjYn6JJmfm}5~<0$ z1-CCp7#I1l`I7zz0=`arw)CDbU#khXUaN)0T5SWlM_kpaDQs#&-H%5&vO(7+DeJA$ z^j?52*Eg>z0jg6nq!n-qWVI{3%hVO*FOkHe9Du$CcWAge_PIPo>O@h>u6plq6S@;- zdle9JAPuW?rAJ=3C2KP^N|V{u0LchoqOC*5mxbYV8{n1@G2XCkZTUM=pIz0qE=oC*`^q{jPWz)mK z1NU)MUFV`H^{Xh6!s#-duceF#rzli~N)&%83R%>3JoMEyiXp;063P@nsP|Ll2dHvC z<(T=3bqFtpCX>}cEHJ*B3m?VDSNp$Mor2A>EJ7QmH}~ zZ)m4sx^DO_Zar8xSOyMUxQsuzVwpaYp|>2vxMg&YCY99v;)9w8D1CfPJiTqcJYdJ&%s`r5-~=-H+s}Urm&CUy;<$TKN{b7 NihIA&Z!z0%`QIvZAyEJT literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/main_parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8400c89ae885f017047b4b2e6d28726927dc3378 GIT binary patch literal 2189 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 D2?rkq literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/cli/__pycache__/status_codes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..922cb87105db73b4f9c761d53c858b6b680c8ec6 GIT binary patch literal 358 zcmXw!%}T>S5P-8u+LY2#4}v~{m_yCQqo{2YF<3W}G!+(MsNE=$%}&DC`r#s;%sspW94z1_h_Ne&! jS+mrU5^ri)7c{BQ$`8@I$O_u9``, ```` or ```` + if completion_type: + options = auto_complete_paths(current, completion_type) + options = ((opt, 0) for opt in options) + for option in options: + opt_label = option[0] + # append '=' to options which require args + if option[1] and option[0][:2] == "--": + opt_label += '=' + print(opt_label) + else: + # show main parser options only when necessary + + opts = [i.option_list for i in parser.option_groups] + opts.append(parser.option_list) + opts = (o for it in opts for o in it) + if current.startswith('-'): + for opt in opts: + if opt.help != optparse.SUPPRESS_HELP: + subcommands += opt._long_opts + opt._short_opts + else: + # get completion type given cwords and all available options + completion_type = get_path_completion_type(cwords, cword, opts) + if completion_type: + subcommands = auto_complete_paths(current, completion_type) + + print(' '.join([x for x in subcommands if x.startswith(current)])) + sys.exit(1) + + +def get_path_completion_type(cwords, cword, opts): + """Get the type of path completion (``file``, ``dir``, ``path`` or None) + + :param cwords: same as the environmental variable ``COMP_WORDS`` + :param cword: same as the environmental variable ``COMP_CWORD`` + :param opts: The available options to check + :return: path completion type (``file``, ``dir``, ``path`` or None) + """ + if cword < 2 or not cwords[cword - 2].startswith('-'): + return + for opt in opts: + if opt.help == optparse.SUPPRESS_HELP: + continue + for o in str(opt).split('/'): + if cwords[cword - 2].split('=')[0] == o: + if not opt.metavar or any( + x in ('path', 'file', 'dir') + for x in opt.metavar.split('/')): + return opt.metavar + + +def auto_complete_paths(current, completion_type): + """If ``completion_type`` is ``file`` or ``path``, list all regular files + and directories starting with ``current``; otherwise only list directories + starting with ``current``. + + :param current: The word to be completed + :param completion_type: path completion type(`file`, `path` or `dir`)i + :return: A generator of regular files and/or directories + """ + directory, filename = os.path.split(current) + current_path = os.path.abspath(directory) + # Don't complete paths if they can't be accessed + if not os.access(current_path, os.R_OK): + return + filename = os.path.normcase(filename) + # list all files that start with ``filename`` + file_list = (x for x in os.listdir(current_path) + if os.path.normcase(x).startswith(filename)) + for f in file_list: + opt = os.path.join(current_path, f) + comp_file = os.path.normcase(os.path.join(directory, f)) + # complete regular files when there is not ```` after option + # complete directories when there is ````, ```` or + # ````after option + if completion_type != 'dir' and os.path.isfile(opt): + yield comp_file + elif os.path.isdir(opt): + yield os.path.join(comp_file, '') diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/base_command.py b/env/lib/python3.7/site-packages/pip/_internal/cli/base_command.py new file mode 100644 index 0000000..dac4b05 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/cli/base_command.py @@ -0,0 +1,278 @@ +"""Base Command class, and related routines""" +from __future__ import absolute_import + +import logging +import logging.config +import optparse +import os +import sys + +from pip._internal.cli import cmdoptions +from pip._internal.cli.parser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.cli.status_codes import ( + ERROR, PREVIOUS_BUILD_DIR_ERROR, SUCCESS, UNKNOWN_ERROR, + VIRTUALENV_NOT_FOUND, +) +from pip._internal.download import PipSession +from pip._internal.exceptions import ( + BadCommand, CommandError, InstallationError, PreviousBuildDirError, + UninstallationError, +) +from pip._internal.index import PackageFinder +from pip._internal.locations import running_under_virtualenv +from pip._internal.req.constructors import ( + install_req_from_editable, install_req_from_line, +) +from pip._internal.req.req_file import parse_requirements +from pip._internal.utils.logging import setup_logging +from pip._internal.utils.misc import get_prog, normalize_path +from pip._internal.utils.outdated import pip_version_check +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Optional # noqa: F401 + +__all__ = ['Command'] + +logger = logging.getLogger(__name__) + + +class Command(object): + name = None # type: Optional[str] + usage = None # type: Optional[str] + hidden = False # type: bool + ignore_require_venv = False # type: bool + + def __init__(self, isolated=False): + parser_kw = { + 'usage': self.usage, + 'prog': '%s %s' % (get_prog(), self.name), + 'formatter': UpdatingDefaultsHelpFormatter(), + 'add_help_option': False, + 'name': self.name, + 'description': self.__doc__, + 'isolated': isolated, + } + + self.parser = ConfigOptionParser(**parser_kw) + + # Commands should add options to this option group + optgroup_name = '%s Options' % self.name.capitalize() + self.cmd_opts = optparse.OptionGroup(self.parser, optgroup_name) + + # Add the general options + gen_opts = cmdoptions.make_option_group( + cmdoptions.general_group, + self.parser, + ) + self.parser.add_option_group(gen_opts) + + def _build_session(self, options, retries=None, timeout=None): + session = PipSession( + cache=( + normalize_path(os.path.join(options.cache_dir, "http")) + if options.cache_dir else None + ), + retries=retries if retries is not None else options.retries, + insecure_hosts=options.trusted_hosts, + ) + + # Handle custom ca-bundles from the user + if options.cert: + session.verify = options.cert + + # Handle SSL client certificate + if options.client_cert: + session.cert = options.client_cert + + # Handle timeouts + if options.timeout or timeout: + session.timeout = ( + timeout if timeout is not None else options.timeout + ) + + # Handle configured proxies + if options.proxy: + session.proxies = { + "http": options.proxy, + "https": options.proxy, + } + + # Determine if we can prompt the user for authentication or not + session.auth.prompting = not options.no_input + + return session + + def parse_args(self, args): + # factored out for testability + return self.parser.parse_args(args) + + def main(self, args): + options, args = self.parse_args(args) + + # Set verbosity so that it can be used elsewhere. + self.verbosity = options.verbose - options.quiet + + setup_logging( + verbosity=self.verbosity, + no_color=options.no_color, + user_log_file=options.log, + ) + + # TODO: Try to get these passing down from the command? + # without resorting to os.environ to hold these. + # This also affects isolated builds and it should. + + if options.no_input: + os.environ['PIP_NO_INPUT'] = '1' + + if options.exists_action: + os.environ['PIP_EXISTS_ACTION'] = ' '.join(options.exists_action) + + if options.require_venv and not self.ignore_require_venv: + # If a venv is required check if it can really be found + if not running_under_virtualenv(): + logger.critical( + 'Could not find an activated virtualenv (required).' + ) + sys.exit(VIRTUALENV_NOT_FOUND) + + try: + status = self.run(options, args) + # FIXME: all commands should return an exit status + # and when it is done, isinstance is not needed anymore + if isinstance(status, int): + return status + except PreviousBuildDirError as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return PREVIOUS_BUILD_DIR_ERROR + except (InstallationError, UninstallationError, BadCommand) as exc: + logger.critical(str(exc)) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except CommandError as exc: + logger.critical('ERROR: %s', exc) + logger.debug('Exception information:', exc_info=True) + + return ERROR + except KeyboardInterrupt: + logger.critical('Operation cancelled by user') + logger.debug('Exception information:', exc_info=True) + + return ERROR + except BaseException: + logger.critical('Exception:', exc_info=True) + + return UNKNOWN_ERROR + finally: + allow_version_check = ( + # Does this command have the index_group options? + hasattr(options, "no_index") and + # Is this command allowed to perform this check? + not (options.disable_pip_version_check or options.no_index) + ) + # Check if we're using the latest version of pip available + if allow_version_check: + session = self._build_session( + options, + retries=0, + timeout=min(5, options.timeout) + ) + with session: + pip_version_check(session, options) + + # Shutdown the logging module + logging.shutdown() + + return SUCCESS + + +class RequirementCommand(Command): + + @staticmethod + def populate_requirement_set(requirement_set, args, options, finder, + session, name, wheel_cache): + """ + Marshal cmd line args into a requirement set. + """ + # NOTE: As a side-effect, options.require_hashes and + # requirement_set.require_hashes may be updated + + for filename in options.constraints: + for req_to_add in parse_requirements( + filename, + constraint=True, finder=finder, options=options, + session=session, wheel_cache=wheel_cache): + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for req in args: + req_to_add = install_req_from_line( + req, None, isolated=options.isolated_mode, + wheel_cache=wheel_cache + ) + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for req in options.editables: + req_to_add = install_req_from_editable( + req, + isolated=options.isolated_mode, + wheel_cache=wheel_cache + ) + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + + for filename in options.requirements: + for req_to_add in parse_requirements( + filename, + finder=finder, options=options, session=session, + wheel_cache=wheel_cache): + req_to_add.is_direct = True + requirement_set.add_requirement(req_to_add) + # If --require-hashes was a line in a requirements file, tell + # RequirementSet about it: + requirement_set.require_hashes = options.require_hashes + + if not (args or options.editables or options.requirements): + opts = {'name': name} + if options.find_links: + raise CommandError( + 'You must give at least one requirement to %(name)s ' + '(maybe you meant "pip %(name)s %(links)s"?)' % + dict(opts, links=' '.join(options.find_links))) + else: + raise CommandError( + 'You must give at least one requirement to %(name)s ' + '(see "pip help %(name)s")' % opts) + + def _build_package_finder(self, options, session, + platform=None, python_versions=None, + abi=None, implementation=None): + """ + Create a package finder appropriate to this requirement command. + """ + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + return PackageFinder( + find_links=options.find_links, + format_control=options.format_control, + index_urls=index_urls, + trusted_hosts=options.trusted_hosts, + allow_all_prereleases=options.pre, + process_dependency_links=options.process_dependency_links, + session=session, + platform=platform, + versions=python_versions, + abi=abi, + implementation=implementation, + prefer_binary=options.prefer_binary, + ) diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py b/env/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py new file mode 100644 index 0000000..3033cd4 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/cli/cmdoptions.py @@ -0,0 +1,714 @@ +""" +shared options and groups + +The principle here is to define options once, but *not* instantiate them +globally. One reason being that options with action='append' can carry state +between parses. pip parses general options twice internally, and shouldn't +pass on state. To be consistent, all options will follow this design. + +""" +from __future__ import absolute_import + +import warnings +from functools import partial +from optparse import SUPPRESS_HELP, Option, OptionGroup + +from pip._internal.exceptions import CommandError +from pip._internal.locations import USER_CACHE_DIR, src_prefix +from pip._internal.models.format_control import FormatControl +from pip._internal.models.index import PyPI +from pip._internal.utils.hashes import STRONG_HASHES +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import BAR_TYPES + +if MYPY_CHECK_RUNNING: + from typing import Any # noqa: F401 + + +def make_option_group(group, parser): + """ + Return an OptionGroup object + group -- assumed to be dict with 'name' and 'options' keys + parser -- an optparse Parser + """ + option_group = OptionGroup(parser, group['name']) + for option in group['options']: + option_group.add_option(option()) + return option_group + + +def check_install_build_global(options, check_options=None): + """Disable wheels if per-setup.py call options are set. + + :param options: The OptionParser options to update. + :param check_options: The options to check, if not supplied defaults to + options. + """ + if check_options is None: + check_options = options + + def getname(n): + return getattr(check_options, n, None) + names = ["build_options", "global_options", "install_options"] + if any(map(getname, names)): + control = options.format_control + control.disallow_binaries() + warnings.warn( + 'Disabling all use of wheels due to the use of --build-options ' + '/ --global-options / --install-options.', stacklevel=2, + ) + + +def check_dist_restriction(options, check_target=False): + """Function for determining if custom platform options are allowed. + + :param options: The OptionParser options. + :param check_target: Whether or not to check if --target is being used. + """ + dist_restriction_set = any([ + options.python_version, + options.platform, + options.abi, + options.implementation, + ]) + + binary_only = FormatControl(set(), {':all:'}) + sdist_dependencies_allowed = ( + options.format_control != binary_only and + not options.ignore_dependencies + ) + + # Installations or downloads using dist restrictions must not combine + # source distributions and dist-specific wheels, as they are not + # gauranteed to be locally compatible. + if dist_restriction_set and sdist_dependencies_allowed: + raise CommandError( + "When restricting platform and interpreter constraints using " + "--python-version, --platform, --abi, or --implementation, " + "either --no-deps must be set, or --only-binary=:all: must be " + "set and --no-binary must not be set (or must be set to " + ":none:)." + ) + + if check_target: + if dist_restriction_set and not options.target_dir: + raise CommandError( + "Can not use any platform or abi specific options unless " + "installing via '--target'" + ) + + +########### +# options # +########### + +help_ = partial( + Option, + '-h', '--help', + dest='help', + action='help', + help='Show help.', +) # type: Any + +isolated_mode = partial( + Option, + "--isolated", + dest="isolated_mode", + action="store_true", + default=False, + help=( + "Run pip in an isolated mode, ignoring environment variables and user " + "configuration." + ), +) + +require_virtualenv = partial( + Option, + # Run only if inside a virtualenv, bail if not. + '--require-virtualenv', '--require-venv', + dest='require_venv', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Any + +verbose = partial( + Option, + '-v', '--verbose', + dest='verbose', + action='count', + default=0, + help='Give more output. Option is additive, and can be used up to 3 times.' +) + +no_color = partial( + Option, + '--no-color', + dest='no_color', + action='store_true', + default=False, + help="Suppress colored output", +) + +version = partial( + Option, + '-V', '--version', + dest='version', + action='store_true', + help='Show version and exit.', +) # type: Any + +quiet = partial( + Option, + '-q', '--quiet', + dest='quiet', + action='count', + default=0, + help=( + 'Give less output. Option is additive, and can be used up to 3' + ' times (corresponding to WARNING, ERROR, and CRITICAL logging' + ' levels).' + ), +) # type: Any + +progress_bar = partial( + Option, + '--progress-bar', + dest='progress_bar', + type='choice', + choices=list(BAR_TYPES.keys()), + default='on', + help=( + 'Specify type of progress to be displayed [' + + '|'.join(BAR_TYPES.keys()) + '] (default: %default)' + ), +) # type: Any + +log = partial( + Option, + "--log", "--log-file", "--local-log", + dest="log", + metavar="path", + help="Path to a verbose appending log." +) # type: Any + +no_input = partial( + Option, + # Don't ask for input + '--no-input', + dest='no_input', + action='store_true', + default=False, + help=SUPPRESS_HELP +) # type: Any + +proxy = partial( + Option, + '--proxy', + dest='proxy', + type='str', + default='', + help="Specify a proxy in the form [user:passwd@]proxy.server:port." +) # type: Any + +retries = partial( + Option, + '--retries', + dest='retries', + type='int', + default=5, + help="Maximum number of retries each connection should attempt " + "(default %default times).", +) # type: Any + +timeout = partial( + Option, + '--timeout', '--default-timeout', + metavar='sec', + dest='timeout', + type='float', + default=15, + help='Set the socket timeout (default %default seconds).', +) # type: Any + +skip_requirements_regex = partial( + Option, + # A regex to be used to skip requirements + '--skip-requirements-regex', + dest='skip_requirements_regex', + type='str', + default='', + help=SUPPRESS_HELP, +) # type: Any + + +def exists_action(): + return Option( + # Option when path already exist + '--exists-action', + dest='exists_action', + type='choice', + choices=['s', 'i', 'w', 'b', 'a'], + default=[], + action='append', + metavar='action', + help="Default action when a path already exists: " + "(s)witch, (i)gnore, (w)ipe, (b)ackup, (a)bort).", + ) + + +cert = partial( + Option, + '--cert', + dest='cert', + type='str', + metavar='path', + help="Path to alternate CA bundle.", +) # type: Any + +client_cert = partial( + Option, + '--client-cert', + dest='client_cert', + type='str', + default=None, + metavar='path', + help="Path to SSL client certificate, a single file containing the " + "private key and the certificate in PEM format.", +) # type: Any + +index_url = partial( + Option, + '-i', '--index-url', '--pypi-url', + dest='index_url', + metavar='URL', + default=PyPI.simple_url, + help="Base URL of Python Package Index (default %default). " + "This should point to a repository compliant with PEP 503 " + "(the simple repository API) or a local directory laid out " + "in the same format.", +) # type: Any + + +def extra_index_url(): + return Option( + '--extra-index-url', + dest='extra_index_urls', + metavar='URL', + action='append', + default=[], + help="Extra URLs of package indexes to use in addition to " + "--index-url. Should follow the same rules as " + "--index-url.", + ) + + +no_index = partial( + Option, + '--no-index', + dest='no_index', + action='store_true', + default=False, + help='Ignore package index (only looking at --find-links URLs instead).', +) # type: Any + + +def find_links(): + return Option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='url', + help="If a url or path to an html file, then parse for links to " + "archives. If a local path or file:// url that's a directory, " + "then look for archives in the directory listing.", + ) + + +def trusted_host(): + return Option( + "--trusted-host", + dest="trusted_hosts", + action="append", + metavar="HOSTNAME", + default=[], + help="Mark this host as trusted, even though it does not have valid " + "or any HTTPS.", + ) + + +# Remove after 1.5 +process_dependency_links = partial( + Option, + "--process-dependency-links", + dest="process_dependency_links", + action="store_true", + default=False, + help="Enable the processing of dependency links.", +) # type: Any + + +def constraints(): + return Option( + '-c', '--constraint', + dest='constraints', + action='append', + default=[], + metavar='file', + help='Constrain versions using the given constraints file. ' + 'This option can be used multiple times.' + ) + + +def requirements(): + return Option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Install from the given requirements file. ' + 'This option can be used multiple times.' + ) + + +def editable(): + return Option( + '-e', '--editable', + dest='editables', + action='append', + default=[], + metavar='path/url', + help=('Install a project in editable mode (i.e. setuptools ' + '"develop mode") from a local project path or a VCS url.'), + ) + + +src = partial( + Option, + '--src', '--source', '--source-dir', '--source-directory', + dest='src_dir', + metavar='dir', + default=src_prefix, + help='Directory to check out editable projects into. ' + 'The default in a virtualenv is "/src". ' + 'The default for global installs is "/src".' +) # type: Any + + +def _get_format_control(values, option): + """Get a format_control object.""" + return getattr(values, option.dest) + + +def _handle_no_binary(option, opt_str, value, parser): + existing = _get_format_control(parser.values, option) + FormatControl.handle_mutual_excludes( + value, existing.no_binary, existing.only_binary, + ) + + +def _handle_only_binary(option, opt_str, value, parser): + existing = _get_format_control(parser.values, option) + FormatControl.handle_mutual_excludes( + value, existing.only_binary, existing.no_binary, + ) + + +def no_binary(): + format_control = FormatControl(set(), set()) + return Option( + "--no-binary", dest="format_control", action="callback", + callback=_handle_no_binary, type="str", + default=format_control, + help="Do not use binary packages. Can be supplied multiple times, and " + "each time adds to the existing value. Accepts either :all: to " + "disable all binary packages, :none: to empty the set, or one or " + "more package names with commas between them. Note that some " + "packages are tricky to compile and may fail to install when " + "this option is used on them.", + ) + + +def only_binary(): + format_control = FormatControl(set(), set()) + return Option( + "--only-binary", dest="format_control", action="callback", + callback=_handle_only_binary, type="str", + default=format_control, + help="Do not use source packages. Can be supplied multiple times, and " + "each time adds to the existing value. Accepts either :all: to " + "disable all source packages, :none: to empty the set, or one or " + "more package names with commas between them. Packages without " + "binary distributions will fail to install when this option is " + "used on them.", + ) + + +platform = partial( + Option, + '--platform', + dest='platform', + metavar='platform', + default=None, + help=("Only use wheels compatible with . " + "Defaults to the platform of the running system."), +) + + +python_version = partial( + Option, + '--python-version', + dest='python_version', + metavar='python_version', + default=None, + help=("Only use wheels compatible with Python " + "interpreter version . If not specified, then the " + "current system interpreter minor version is used. A major " + "version (e.g. '2') can be specified to match all " + "minor revs of that major version. A minor version " + "(e.g. '34') can also be specified."), +) + + +implementation = partial( + Option, + '--implementation', + dest='implementation', + metavar='implementation', + default=None, + help=("Only use wheels compatible with Python " + "implementation , e.g. 'pp', 'jy', 'cp', " + " or 'ip'. If not specified, then the current " + "interpreter implementation is used. Use 'py' to force " + "implementation-agnostic wheels."), +) + + +abi = partial( + Option, + '--abi', + dest='abi', + metavar='abi', + default=None, + help=("Only use wheels compatible with Python " + "abi , e.g. 'pypy_41'. If not specified, then the " + "current interpreter abi tag is used. Generally " + "you will need to specify --implementation, " + "--platform, and --python-version when using " + "this option."), +) + + +def prefer_binary(): + return Option( + "--prefer-binary", + dest="prefer_binary", + action="store_true", + default=False, + help="Prefer older binary packages over newer source packages." + ) + + +cache_dir = partial( + Option, + "--cache-dir", + dest="cache_dir", + default=USER_CACHE_DIR, + metavar="dir", + help="Store the cache data in ." +) + +no_cache = partial( + Option, + "--no-cache-dir", + dest="cache_dir", + action="store_false", + help="Disable the cache.", +) + +no_deps = partial( + Option, + '--no-deps', '--no-dependencies', + dest='ignore_dependencies', + action='store_true', + default=False, + help="Don't install package dependencies.", +) # type: Any + +build_dir = partial( + Option, + '-b', '--build', '--build-dir', '--build-directory', + dest='build_dir', + metavar='dir', + help='Directory to unpack packages into and build in. Note that ' + 'an initial build still takes place in a temporary directory. ' + 'The location of temporary directories can be controlled by setting ' + 'the TMPDIR environment variable (TEMP on Windows) appropriately. ' + 'When passed, build directories are not cleaned in case of failures.' +) # type: Any + +ignore_requires_python = partial( + Option, + '--ignore-requires-python', + dest='ignore_requires_python', + action='store_true', + help='Ignore the Requires-Python information.' +) # type: Any + +no_build_isolation = partial( + Option, + '--no-build-isolation', + dest='build_isolation', + action='store_false', + default=True, + help='Disable isolation when building a modern source distribution. ' + 'Build dependencies specified by PEP 518 must be already installed ' + 'if this option is used.' +) # type: Any + +install_options = partial( + Option, + '--install-option', + dest='install_options', + action='append', + metavar='options', + help="Extra arguments to be supplied to the setup.py install " + "command (use like --install-option=\"--install-scripts=/usr/local/" + "bin\"). Use multiple --install-option options to pass multiple " + "options to setup.py install. If you are using an option with a " + "directory path, be sure to use absolute path.", +) # type: Any + +global_options = partial( + Option, + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the install command.", +) # type: Any + +no_clean = partial( + Option, + '--no-clean', + action='store_true', + default=False, + help="Don't clean up build directories." +) # type: Any + +pre = partial( + Option, + '--pre', + action='store_true', + default=False, + help="Include pre-release and development versions. By default, " + "pip only finds stable versions.", +) # type: Any + +disable_pip_version_check = partial( + Option, + "--disable-pip-version-check", + dest="disable_pip_version_check", + action="store_true", + default=False, + help="Don't periodically check PyPI to determine whether a new version " + "of pip is available for download. Implied with --no-index.", +) # type: Any + + +# Deprecated, Remove later +always_unzip = partial( + Option, + '-Z', '--always-unzip', + dest='always_unzip', + action='store_true', + help=SUPPRESS_HELP, +) # type: Any + + +def _merge_hash(option, opt_str, value, parser): + """Given a value spelled "algo:digest", append the digest to a list + pointed to in a dict by the algo name.""" + if not parser.values.hashes: + parser.values.hashes = {} + try: + algo, digest = value.split(':', 1) + except ValueError: + parser.error('Arguments to %s must be a hash name ' + 'followed by a value, like --hash=sha256:abcde...' % + opt_str) + if algo not in STRONG_HASHES: + parser.error('Allowed hash algorithms for %s are %s.' % + (opt_str, ', '.join(STRONG_HASHES))) + parser.values.hashes.setdefault(algo, []).append(digest) + + +hash = partial( + Option, + '--hash', + # Hash values eventually end up in InstallRequirement.hashes due to + # __dict__ copying in process_line(). + dest='hashes', + action='callback', + callback=_merge_hash, + type='string', + help="Verify that the package's archive matches this " + 'hash before installing. Example: --hash=sha256:abcdef...', +) # type: Any + + +require_hashes = partial( + Option, + '--require-hashes', + dest='require_hashes', + action='store_true', + default=False, + help='Require a hash to check each requirement against, for ' + 'repeatable installs. This option is implied when any package in a ' + 'requirements file has a --hash option.', +) # type: Any + + +########## +# groups # +########## + +general_group = { + 'name': 'General Options', + 'options': [ + help_, + isolated_mode, + require_virtualenv, + verbose, + version, + quiet, + log, + no_input, + proxy, + retries, + timeout, + skip_requirements_regex, + exists_action, + trusted_host, + cert, + client_cert, + cache_dir, + no_cache, + disable_pip_version_check, + no_color, + ] +} + +index_group = { + 'name': 'Package Index Options', + 'options': [ + index_url, + extra_index_url, + no_index, + find_links, + process_dependency_links, + ] +} diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py b/env/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py new file mode 100644 index 0000000..1774a6b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/cli/main_parser.py @@ -0,0 +1,96 @@ +"""A single place for constructing and exposing the main parser +""" + +import os +import sys + +from pip import __version__ +from pip._internal.cli import cmdoptions +from pip._internal.cli.parser import ( + ConfigOptionParser, UpdatingDefaultsHelpFormatter, +) +from pip._internal.commands import ( + commands_dict, get_similar_commands, get_summaries, +) +from pip._internal.exceptions import CommandError +from pip._internal.utils.misc import get_prog + +__all__ = ["create_main_parser", "parse_command"] + + +def create_main_parser(): + """Creates and returns the main parser for pip's CLI + """ + + parser_kw = { + 'usage': '\n%prog [options]', + 'add_help_option': False, + 'formatter': UpdatingDefaultsHelpFormatter(), + 'name': 'global', + 'prog': get_prog(), + } + + parser = ConfigOptionParser(**parser_kw) + parser.disable_interspersed_args() + + pip_pkg_dir = os.path.abspath(os.path.join( + os.path.dirname(__file__), "..", "..", + )) + parser.version = 'pip %s from %s (python %s)' % ( + __version__, pip_pkg_dir, sys.version[:3], + ) + + # add the general options + gen_opts = cmdoptions.make_option_group(cmdoptions.general_group, parser) + parser.add_option_group(gen_opts) + + parser.main = True # so the help formatter knows + + # create command listing for description + command_summaries = get_summaries() + description = [''] + ['%-27s %s' % (i, j) for i, j in command_summaries] + parser.description = '\n'.join(description) + + return parser + + +def parse_command(args): + parser = create_main_parser() + + # Note: parser calls disable_interspersed_args(), so the result of this + # call is to split the initial args into the general options before the + # subcommand and everything else. + # For example: + # args: ['--timeout=5', 'install', '--user', 'INITools'] + # general_options: ['--timeout==5'] + # args_else: ['install', '--user', 'INITools'] + general_options, args_else = parser.parse_args(args) + + # --version + if general_options.version: + sys.stdout.write(parser.version) + sys.stdout.write(os.linesep) + sys.exit() + + # pip || pip help -> print_help() + if not args_else or (args_else[0] == 'help' and len(args_else) == 1): + parser.print_help() + sys.exit() + + # the subcommand name + cmd_name = args_else[0] + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + # all the args without the subcommand + cmd_args = args[:] + cmd_args.remove(cmd_name) + + return cmd_name, cmd_args diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/parser.py b/env/lib/python3.7/site-packages/pip/_internal/cli/parser.py new file mode 100644 index 0000000..e1eaac4 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/cli/parser.py @@ -0,0 +1,261 @@ +"""Base option parser setup""" +from __future__ import absolute_import + +import logging +import optparse +import sys +import textwrap +from distutils.util import strtobool + +from pip._vendor.six import string_types + +from pip._internal.cli.status_codes import UNKNOWN_ERROR +from pip._internal.configuration import Configuration, ConfigurationError +from pip._internal.utils.compat import get_terminal_size + +logger = logging.getLogger(__name__) + + +class PrettyHelpFormatter(optparse.IndentedHelpFormatter): + """A prettier/less verbose help formatter for optparse.""" + + def __init__(self, *args, **kwargs): + # help position must be aligned with __init__.parseopts.description + kwargs['max_help_position'] = 30 + kwargs['indent_increment'] = 1 + kwargs['width'] = get_terminal_size()[0] - 2 + optparse.IndentedHelpFormatter.__init__(self, *args, **kwargs) + + def format_option_strings(self, option): + return self._format_option_strings(option, ' <%s>', ', ') + + def _format_option_strings(self, option, mvarfmt=' <%s>', optsep=', '): + """ + Return a comma-separated list of option strings and metavars. + + :param option: tuple of (short opt, long opt), e.g: ('-f', '--format') + :param mvarfmt: metavar format string - evaluated as mvarfmt % metavar + :param optsep: separator + """ + opts = [] + + if option._short_opts: + opts.append(option._short_opts[0]) + if option._long_opts: + opts.append(option._long_opts[0]) + if len(opts) > 1: + opts.insert(1, optsep) + + if option.takes_value(): + metavar = option.metavar or option.dest.lower() + opts.append(mvarfmt % metavar.lower()) + + return ''.join(opts) + + def format_heading(self, heading): + if heading == 'Options': + return '' + return heading + ':\n' + + def format_usage(self, usage): + """ + Ensure there is only one newline between usage and the first heading + if there is no description. + """ + msg = '\nUsage: %s\n' % self.indent_lines(textwrap.dedent(usage), " ") + return msg + + def format_description(self, description): + # leave full control over description to us + if description: + if hasattr(self.parser, 'main'): + label = 'Commands' + else: + label = 'Description' + # some doc strings have initial newlines, some don't + description = description.lstrip('\n') + # some doc strings have final newlines and spaces, some don't + description = description.rstrip() + # dedent, then reindent + description = self.indent_lines(textwrap.dedent(description), " ") + description = '%s:\n%s\n' % (label, description) + return description + else: + return '' + + def format_epilog(self, epilog): + # leave full control over epilog to us + if epilog: + return epilog + else: + return '' + + def indent_lines(self, text, indent): + new_lines = [indent + line for line in text.split('\n')] + return "\n".join(new_lines) + + +class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter): + """Custom help formatter for use in ConfigOptionParser. + + This is updates the defaults before expanding them, allowing + them to show up correctly in the help listing. + """ + + def expand_default(self, option): + if self.parser is not None: + self.parser._update_defaults(self.parser.defaults) + return optparse.IndentedHelpFormatter.expand_default(self, option) + + +class CustomOptionParser(optparse.OptionParser): + + def insert_option_group(self, idx, *args, **kwargs): + """Insert an OptionGroup at a given position.""" + group = self.add_option_group(*args, **kwargs) + + self.option_groups.pop() + self.option_groups.insert(idx, group) + + return group + + @property + def option_list_all(self): + """Get a list of all options, including those in option groups.""" + res = self.option_list[:] + for i in self.option_groups: + res.extend(i.option_list) + + return res + + +class ConfigOptionParser(CustomOptionParser): + """Custom option parser which updates its defaults by checking the + configuration files and environmental variables""" + + def __init__(self, *args, **kwargs): + self.name = kwargs.pop('name') + + isolated = kwargs.pop("isolated", False) + self.config = Configuration(isolated) + + assert self.name + optparse.OptionParser.__init__(self, *args, **kwargs) + + def check_default(self, option, key, val): + try: + return option.check_value(key, val) + except optparse.OptionValueError as exc: + print("An error occurred during configuration: %s" % exc) + sys.exit(3) + + def _get_ordered_configuration_items(self): + # Configuration gives keys in an unordered manner. Order them. + override_order = ["global", self.name, ":env:"] + + # Pool the options into different groups + section_items = {name: [] for name in override_order} + for section_key, val in self.config.items(): + # ignore empty values + if not val: + logger.debug( + "Ignoring configuration key '%s' as it's value is empty.", + section_key + ) + continue + + section, key = section_key.split(".", 1) + if section in override_order: + section_items[section].append((key, val)) + + # Yield each group in their override order + for section in override_order: + for key, val in section_items[section]: + yield key, val + + def _update_defaults(self, defaults): + """Updates the given defaults with values from the config files and + the environ. Does a little special handling for certain types of + options (lists).""" + + # Accumulate complex default state. + self.values = optparse.Values(self.defaults) + late_eval = set() + # Then set the options with those values + for key, val in self._get_ordered_configuration_items(): + # '--' because configuration supports only long names + option = self.get_option('--' + key) + + # Ignore options not present in this parser. E.g. non-globals put + # in [global] by users that want them to apply to all applicable + # commands. + if option is None: + continue + + if option.action in ('store_true', 'store_false', 'count'): + try: + val = strtobool(val) + except ValueError: + error_msg = invalid_config_error_message( + option.action, key, val + ) + self.error(error_msg) + + elif option.action == 'append': + val = val.split() + val = [self.check_default(option, key, v) for v in val] + elif option.action == 'callback': + late_eval.add(option.dest) + opt_str = option.get_opt_string() + val = option.convert_value(opt_str, val) + # From take_action + args = option.callback_args or () + kwargs = option.callback_kwargs or {} + option.callback(option, opt_str, val, self, *args, **kwargs) + else: + val = self.check_default(option, key, val) + + defaults[option.dest] = val + + for key in late_eval: + defaults[key] = getattr(self.values, key) + self.values = None + return defaults + + def get_default_values(self): + """Overriding to make updating the defaults after instantiation of + the option parser possible, _update_defaults() does the dirty work.""" + if not self.process_default_values: + # Old, pre-Optik 1.5 behaviour. + return optparse.Values(self.defaults) + + # Load the configuration, or error out in case of an error + try: + self.config.load() + except ConfigurationError as err: + self.exit(UNKNOWN_ERROR, str(err)) + + defaults = self._update_defaults(self.defaults.copy()) # ours + for option in self._get_all_options(): + default = defaults.get(option.dest) + if isinstance(default, string_types): + opt_str = option.get_opt_string() + defaults[option.dest] = option.check_value(opt_str, default) + return optparse.Values(defaults) + + def error(self, msg): + self.print_usage(sys.stderr) + self.exit(UNKNOWN_ERROR, "%s\n" % msg) + + +def invalid_config_error_message(action, key, val): + """Returns a better error message when invalid configuration option + is provided.""" + if action in ('store_true', 'store_false'): + return ("{0} is not a valid value for {1} option, " + "please specify a boolean value like yes/no, " + "true/false or 1/0 instead.").format(val, key) + + return ("{0} is not a valid value for {1} option, " + "please specify a numerical value like 1/0 " + "instead.").format(val, key) diff --git a/env/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py b/env/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py new file mode 100644 index 0000000..275360a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/cli/status_codes.py @@ -0,0 +1,8 @@ +from __future__ import absolute_import + +SUCCESS = 0 +ERROR = 1 +UNKNOWN_ERROR = 2 +VIRTUALENV_NOT_FOUND = 3 +PREVIOUS_BUILD_DIR_ERROR = 4 +NO_MATCHES_FOUND = 23 diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__init__.py b/env/lib/python3.7/site-packages/pip/_internal/commands/__init__.py new file mode 100644 index 0000000..c7d1da3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/__init__.py @@ -0,0 +1,79 @@ +""" +Package containing all pip commands +""" +from __future__ import absolute_import + +from pip._internal.commands.completion import CompletionCommand +from pip._internal.commands.configuration import ConfigurationCommand +from pip._internal.commands.download import DownloadCommand +from pip._internal.commands.freeze import FreezeCommand +from pip._internal.commands.hash import HashCommand +from pip._internal.commands.help import HelpCommand +from pip._internal.commands.list import ListCommand +from pip._internal.commands.check import CheckCommand +from pip._internal.commands.search import SearchCommand +from pip._internal.commands.show import ShowCommand +from pip._internal.commands.install import InstallCommand +from pip._internal.commands.uninstall import UninstallCommand +from pip._internal.commands.wheel import WheelCommand + +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import List, Type # noqa: F401 + from pip._internal.cli.base_command import Command # noqa: F401 + +commands_order = [ + InstallCommand, + DownloadCommand, + UninstallCommand, + FreezeCommand, + ListCommand, + ShowCommand, + CheckCommand, + ConfigurationCommand, + SearchCommand, + WheelCommand, + HashCommand, + CompletionCommand, + HelpCommand, +] # type: List[Type[Command]] + +commands_dict = {c.name: c for c in commands_order} + + +def get_summaries(ordered=True): + """Yields sorted (command name, command summary) tuples.""" + + if ordered: + cmditems = _sort_commands(commands_dict, commands_order) + else: + cmditems = commands_dict.items() + + for name, command_class in cmditems: + yield (name, command_class.summary) + + +def get_similar_commands(name): + """Command name auto-correct.""" + from difflib import get_close_matches + + name = name.lower() + + close_commands = get_close_matches(name, commands_dict.keys()) + + if close_commands: + return close_commands[0] + else: + return False + + +def _sort_commands(cmddict, order): + def keyfn(key): + try: + return order.index(key[1]) + except ValueError: + # unordered items should come last + return 0xff + + return sorted(cmddict.items(), key=keyfn) diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..789db495ccf9d00c8ad75500e00c22752eafc743 GIT binary patch literal 2457 zcmaJ@OK%%D5GJ{+M`UR&JBnk=k0{SZMJ@Nx7HAO!L7gYs3PGJmvq-SmEGc_qa#!K5 z;MkB(G0JO-W>~HBGDE8V@{z5M83@yoy5oH(T&J2g-%*UDGeqX7S2t4ke*Pj1f zB;;RYMo$HZThNkAln_o_!YOBxD&{hZv?VQNySAZinNxW;Z|IyXsG?gmbY7lOCAVbg zf}B!iw`}O5tSHBI41GpUtEyWybV<&rS$EdZQ}V2;xiv$Vbw*xL4Y#2#x);s(th}TyyO&{nUKB-Lltfj` ziCK{sHL)bh!WPbE#l6DM^4dNTS8kKH)V<1=`5ZsLPu**Lo-gbZ_cLDSi}1b9mo`Xq zW$$X~p&xAfo1ziKQR;_L7;QFuDI49e3nHcbh$p3Y2yl~T)BejOmc3MXq3Xsu1<}lU zth!R9VH^R4>L9GG$5AKT>}mf)`Sk60Cz7$xk5wyowGeyaSTJ?pPqt37LUvEEKZZ$q z%$C=;M6i9#S2l#NgOk%Yw&I=Rapyslq~PAMr1}_KJ|!zZ-4f!2&g@Um9zOHd@84Pf z!Tb4fyZxYjugNkSP08#>yIlb;7lum)5P9Zd(A&_~p(QowLeeKM$^+Vm_Z9hry|y>V zUx=z5`AWcoto3C^1C6?-dw**!Royi>iPfQrtHI7@^eTP*6$(xB!YCCw^5t4EJghYj zWMS%gt?uso(hVL4DGYUQevWpaQF)>l;PYr~DOzbk3!o+6LDwg`nv#^J>@6G6sF>0N z>yQlSo25RzOL*&X(TQ1W`^DdZPK6x;jyStuk=8VSUQ;En4;yBg@^ z7o(7BBt3`~z1wW0J&2y9)o$i8$HO_^$dRlvqC9jWbH;3}xzJfIOod9a!e}WwE0_Vn zvtppQ8P(^&o$*3mApImc23XIV(M^$hM~j3aSw#>`g|Tc}W<};ueFQIM5@5UPDh3>^<_}Yax&f#S}!7PZ;RceX&JwdMxCSS zBk)dpUo+l^DwMt+L;o!-m6V|)%s{|wT4ee<@Bu~;J|h_Ln=C>1E9p>#V!t?GDFQ(c z2{>*2&cIo_J;o0`gSt)5;zV3>*ZGYczy!qS5Ms!N$lESyDB<{WnEngYa#+M_zr)Gz z{(}zEB^O3qyva&WeAyFsw2n0ZW`Y0k$(cwv^3@!24&wz-IZQaMsJnT3G=C41-d)fY)o-VcLSe5#W}(4&6Oy2}TQ{<${s4 zoAgn$nH4;b$ARZ%CC}^h(w-KcrxDxiBBXX}oYt+;xgjyEvl=nau1wTBQF=A*on4rq z%7@ih=TK{Tf>y^AXq`u$#R)oFP_uR6lNwOQH9|je4GHB`pFxeK3A;f22iqExbE2_{ zssDQFQyV34C1{N9Y-Pem!*Z+feo(uZm=3=54}q%r+W`kP8+^3=rIiCj0AiphlH4HfgA j6gN%g-i4`H=gM@#3kATYRa&+fq|C?OyyaM>a?$x8lWmu7 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/check.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d6c319325735f84adb1db61fb738464c6899bbe1 GIT binary patch literal 1259 zcmZ8hPjA~c6elI>k7al0h9XN2E3}~<;9^mBC{SSNh9ViT%aBWf2GCLnib&f^BvB@* zG&ZDD_Av%5IqtF##OqG|3OntQaWZd&-}8^pe2>5PhdzAtC_=E(-@iV+^bq>XZ0;8U z@CHO4f})7x3Z>@Tsc`M24mQ}W+?u4M_EHZchHiWo+~PF+2~k45UlH|~bM2-hir=EC z{}JM#<0;m`5wGjKp;JeHS}a&`k+peokB+p?M9byhY~xsc&-yK5b-Vlm=zYqG5I(z7r zV6^=91TA+@(A8n@!Kv^5*s?1HGx(eM!=fw}aVg`5tAA^k2n-pn_wO7Q`GZr< z8fE>?Iu);YcUN0`Ecs}CzBuObncx?!xxdKx$au!Ph9*-_n28josyeu2LPC|bU-9{z z2~Emo#-|faB&%jR*z`b?T+F2&Z;w|{mr|C^T#pOh%&M|bW;21_owGt^O`j_cwF2UwoK1=W6-V7_GnrD<+z}I)ITf z4?rH+2};_Pc172G265z9pb+-)#EEc(Kfwe$c*iyP$p(j*IP1sTBb^csh_BFcK@V3%A>Zw$$gw27eD|3?j`a z0|g*q#M-Bk4ooAUlIc^(HhIW2DXKC#%O%S;DGT#n_5Tj>mI-)a@M;oU5Zh$iZatba o^|S4<*aJ^7GRkn-;%DkF3`rfnzRUUtGf>jBF?1&QF^SxN0Ns08#{d8T literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/completion.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b8b81c2ad9118c000a033e0421120015cbf0424 GIT binary patch literal 3031 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/freeze.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e8f86b34f975700238da982e02f405bb8e8d7dfa GIT binary patch literal 2827 zcmb7GOK;@H5$2m5&WxnhzU=jjak7pF5JyRnLtq$&kzLy`9IS)bn+=#41jX)|q11eA zcXK5Xqmvf!X?@5ai1wJjVE+?deac_R$zPK*(rA4$2i;R$)vT_^SJnLUcNG@>&t*CSn5w84zXz`x1N+={G@XE8f>BB!Hm=H_1Hb+p3< zxgYr*?XqD$ibkM4G9W$~F05$$nMOur{9Ger>YSU=7BRlkCR_i*soF$ux03@=vRcwO z%d3*hN8tHS7L>9FNxGm|xev-bPYMEZ{AtPaL_R1B$x8-?GvkytYS&Om!m@+7I+}~t ztg@>01(kIr%aV!KCz+5uJHR=ueXO*n>iqR%t_blb5LAnFqQQSXGKmpc#EfiWMGmne z_gihI6Nk9Z;l1+lxfTt+)hsRY;gb*hI&)SAHz$68=gV4FwG6UC$b>OUf+|Umk~tM% z1)M&uGfs0_ND<6B@1}nD+U2f<(}2Nzyonc*AWZ}fp^X+Ili4#G2!sv7k`v0O-Mid@ zAI+VP4ubm?FXzEO%SvWtA--vT|BEe}7|jknkss{ui&HU0q$%e==cM{7j4GT1jBO0@ zJtnD1eW{%rhsIK08s7nAOYP7+w1`d&ViIev5nF}zg?lOK0i+~Dz-Lo3CR=2i?2sE| zm)v{-K(2J%BDXv49dPYS?p^X4xUZ9Y7q)a>>UT8q#tQ&?_0F5*ElA(KhQ z47pDM@(u(*XA#V4L3tvxVjh$oe5S$Ii%bN44grB8IG{l-koLT0GOM6TW;qqpiQQU+ z3JIf9mG9Oibe3RG>*iD@&l28R3(6{ZHETv;ILitWvaC2lktjOuY4h>l{?dGiNr5s@ z0%gk@lY7DOB1;#+amJW3Bq0Qr$g+34Hy8)7#tlPOrU`59{?8Y(;!jPQ2zc_dn@5!J4x^Cz$av zU!#Mo(whugThtY56TMz*y*SQ_OvZ8Rr8$WK9i$kUQj`LQby#La>plGB@9|&1`0T6J zsS>UtbW`;fE?3*)IWOyKVz!o`Y}Q%{M}IYrj?r=lah$S5h&cYQ_WzIeWnS&0@2+za zrpNQ*P(J;mVs-=ONXm? z%U${vy>m%>Msw#{Tb{1tlCImnhZBbw4=}{PF{yra-i>qP%#`R_hvw1*ZAo2P=lYoq zjxGMMv@aa#zC=Hh9ykLGA7h9y!Wd(0Ev=>6y-oBNgEOaj|Kwe{Gt-vNcltx^n_FkD zym7dDadYVsjfB!|vvbQ+2T-pV-3RP)c-va+}+VGI3{e6_$3;?TSgpxr;Sd zxoMrcBGANtr4|;+Qpv|ks7&E^)%3cO++Cf1b+xTb8Lv%=^AdN6I=s88aPBGEC@vOs zJ6zBlW!JhXqe%hmdHgp@tGl|u_MzSU?Y{;1zS8wOB^j^E^ys+5s)dF|`TI)T zO%t`pl%)6jSH*No=IbreCvWT=X)NOFoI^JC>y z%@jR~fht5a_OEx%zI5etmtD$|e)jS5nd;>YeL5OSC84YxoYC_G#+!AKkmY stCktm;lwJDJ^U2nI*+abv5`*i!#?yMsWvE7`yUyeF+x_mpD{9j0?i*VnE(I) literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/hash.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37e80774f398eecc92e303ff834e2a6b6c795564 GIT binary patch literal 2021 zcmZuyTW=gS6t+Fry(OWoq7ZJ=OA0G>HxlrGs!~zf(tuDZHW5Vwl{FcAcPE`&Y){j! zHoT-#pD5xNuzBP!`IRUB0#6*zZju7^%4d%4W9yvnJLl||olX?jBp=TdcvFFHm@aksZ`+{RKXtF4oJ@o-EQz zahhahA=EbPd3TE}i*g34bAK>+IOr1H`RdO14+mfG-lto4cD8h9XLs;$`$4_9zXOIX z!6QcFag{%jv3dJ+SPMmd1`0Kt!R=|GABNgqXynZRkrHay2 zE*{pld111?QHo*|{8*GKDRTKZxMg0r9rXMC$<Bj`HXW?U-m z#p5E0xzuhHoA|ZI_%Nzc1?cd!6ec#{(UDcjh45jeeM*x&QIu*w&KL#Uq;5v6*5CyJ z6@-LiEbaXw$+cTXLUN%m0{&bma{5SY}OOpQC#Fvx*5+)KyDho`sH(R0o-^Oro03K;S1Qs zHYR7k6+F4L1*VG(?Vm;#8!F8(VKiXgg(>fWm=d`P#Gn~g1n2=umA!+ec;7j)o?V%e zd+71{5zspG7@pcwOZi3~lM@@GgDa2bWRmU4%7(nzoagZ8pl--+L#)F4x>X7YhgK3Q zL0j@UFe4QM?1kw>!Za%Frp0Ikh}ua$EOdvOXlXH|CULutSTi=>BA>g9Qe$D@ zn2Yy}oh7RLBT(cL2n6UXVVk(P2}n(rU&jXQx-CO~9%UTJZ&I2StV)gEru3kS(#45K zDJx>ww#|li=COFPg8n3)LmrHBNLIS2TKbgdPivyYb>mQH!G6rsl+tr|yI8yf=fZeh zCt_V@#%tfR!SDJ<+U@!*Ca`bD{|Ho2gA5;&UvC@{g=bKiCm5((SJspqW1w&82nd_m zQ`?Yx5IjOa8u< mI;Pj+uhY2BVE@)U4{w`ZRTp}j_!xeGM;ou;HfdTb*Zu*e{2EvQ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/help.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2790ba2b206f03692b9862d6d0b366628aeaded GIT binary patch literal 1197 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/list.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b80f79461167e145361089f9cceff3b1888b2a9 GIT binary patch literal 8870 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/commands/__pycache__/search.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..34f9dd3c585c169e495e82c2c79e94f736cee11f GIT binary patch literal 4263 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] list + %prog [] [--editor ] edit + + %prog [] get name + %prog [] set name value + %prog [] unset name + """ + + summary = "Manage local and global configuration." + + def __init__(self, *args, **kwargs): + super(ConfigurationCommand, self).__init__(*args, **kwargs) + + self.configuration = None + + self.cmd_opts.add_option( + '--editor', + dest='editor', + action='store', + default=None, + help=( + 'Editor to use to edit the file. Uses VISUAL or EDITOR ' + 'environment variables if not provided.' + ) + ) + + self.cmd_opts.add_option( + '--global', + dest='global_file', + action='store_true', + default=False, + help='Use the system-wide configuration file only' + ) + + self.cmd_opts.add_option( + '--user', + dest='user_file', + action='store_true', + default=False, + help='Use the user configuration file only' + ) + + self.cmd_opts.add_option( + '--venv', + dest='venv_file', + action='store_true', + default=False, + help='Use the virtualenv configuration file only' + ) + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + handlers = { + "list": self.list_values, + "edit": self.open_in_editor, + "get": self.get_name, + "set": self.set_name_value, + "unset": self.unset_name + } + + # Determine action + if not args or args[0] not in handlers: + logger.error("Need an action ({}) to perform.".format( + ", ".join(sorted(handlers))) + ) + return ERROR + + action = args[0] + + # Determine which configuration files are to be loaded + # Depends on whether the command is modifying. + try: + load_only = self._determine_file( + options, need_value=(action in ["get", "set", "unset", "edit"]) + ) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + # Load a new configuration + self.configuration = Configuration( + isolated=options.isolated_mode, load_only=load_only + ) + self.configuration.load() + + # Error handling happens here, not in the action-handlers. + try: + handlers[action](options, args[1:]) + except PipError as e: + logger.error(e.args[0]) + return ERROR + + return SUCCESS + + def _determine_file(self, options, need_value): + file_options = { + kinds.USER: options.user_file, + kinds.GLOBAL: options.global_file, + kinds.VENV: options.venv_file + } + + if sum(file_options.values()) == 0: + if not need_value: + return None + # Default to user, unless there's a virtualenv file. + elif os.path.exists(venv_config_file): + return kinds.VENV + else: + return kinds.USER + elif sum(file_options.values()) == 1: + # There's probably a better expression for this. + return [key for key in file_options if file_options[key]][0] + + raise PipError( + "Need exactly one file to operate upon " + "(--user, --venv, --global) to perform." + ) + + def list_values(self, options, args): + self._get_n_args(args, "list", n=0) + + for key, value in sorted(self.configuration.items()): + logger.info("%s=%r", key, value) + + def get_name(self, options, args): + key = self._get_n_args(args, "get [name]", n=1) + value = self.configuration.get_value(key) + + logger.info("%s", value) + + def set_name_value(self, options, args): + key, value = self._get_n_args(args, "set [name] [value]", n=2) + self.configuration.set_value(key, value) + + self._save_configuration() + + def unset_name(self, options, args): + key = self._get_n_args(args, "unset [name]", n=1) + self.configuration.unset_value(key) + + self._save_configuration() + + def open_in_editor(self, options, args): + editor = self._determine_editor(options) + + fname = self.configuration.get_file_to_edit() + if fname is None: + raise PipError("Could not determine appropriate file.") + + try: + subprocess.check_call([editor, fname]) + except subprocess.CalledProcessError as e: + raise PipError( + "Editor Subprocess exited with exit code {}" + .format(e.returncode) + ) + + def _get_n_args(self, args, example, n): + """Helper to make sure the command got the right number of arguments + """ + if len(args) != n: + msg = ( + 'Got unexpected number of arguments, expected {}. ' + '(example: "{} config {}")' + ).format(n, get_prog(), example) + raise PipError(msg) + + if n == 1: + return args[0] + else: + return args + + def _save_configuration(self): + # We successfully ran a modifying command. Need to save the + # configuration. + try: + self.configuration.save() + except Exception: + logger.error( + "Unable to save configuration. Please report this as a bug.", + exc_info=1 + ) + raise PipError("Internal Error.") + + def _determine_editor(self, options): + if options.editor is not None: + return options.editor + elif "VISUAL" in os.environ: + return os.environ["VISUAL"] + elif "EDITOR" in os.environ: + return os.environ["EDITOR"] + else: + raise PipError("Could not determine editor to use.") diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/download.py b/env/lib/python3.7/site-packages/pip/_internal/commands/download.py new file mode 100644 index 0000000..b3f3c6e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/download.py @@ -0,0 +1,174 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import RequirementCommand +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.resolve import Resolver +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, normalize_path +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +class DownloadCommand(RequirementCommand): + """ + Download packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports downloading from "requirements files", which provide + an easy way to specify a whole environment to be downloaded. + """ + name = 'download' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] ... + %prog [options] ... + %prog [options] ...""" + + summary = 'Download packages.' + + def __init__(self, *args, **kw): + super(DownloadCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.global_options()) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.prefer_binary()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.pre()) + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + cmd_opts.add_option(cmdoptions.progress_bar()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + + cmd_opts.add_option( + '-d', '--dest', '--destination-dir', '--destination-directory', + dest='download_dir', + metavar='dir', + default=os.curdir, + help=("Download packages into ."), + ) + + cmd_opts.add_option(cmdoptions.platform()) + cmd_opts.add_option(cmdoptions.python_version()) + cmd_opts.add_option(cmdoptions.implementation()) + cmd_opts.add_option(cmdoptions.abi()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + options.ignore_installed = True + # editable doesn't really make sense for `pip download`, but the bowels + # of the RequirementSet code require that property. + options.editables = [] + + if options.python_version: + python_versions = [options.python_version] + else: + python_versions = None + + cmdoptions.check_dist_restriction(options) + + options.src_dir = os.path.abspath(options.src_dir) + options.download_dir = normalize_path(options.download_dir) + + ensure_dir(options.download_dir) + + with self._build_session(options) as session: + finder = self._build_package_finder( + options=options, + session=session, + platform=options.platform, + python_versions=python_versions, + abi=options.abi, + implementation=options.implementation, + ) + build_delete = (not (options.no_clean or options.build_dir)) + if options.cache_dir and not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "by the current user and caching wheels has been " + "disabled. check the permissions and owner of that " + "directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + with RequirementTracker() as req_tracker, TempDirectory( + options.build_dir, delete=build_delete, kind="download" + ) as directory: + + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + self.populate_requirement_set( + requirement_set, + args, + options, + finder, + session, + self.name, + None + ) + + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=options.download_dir, + wheel_download_dir=None, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + req_tracker=req_tracker, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=None, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + force_reinstall=False, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=False, + ignore_installed=True, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + downloaded = ' '.join([ + req.name for req in requirement_set.successfully_downloaded + ]) + if downloaded: + logger.info('Successfully downloaded %s', downloaded) + + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + + return requirement_set diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/freeze.py b/env/lib/python3.7/site-packages/pip/_internal/commands/freeze.py new file mode 100644 index 0000000..dc9c53a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/freeze.py @@ -0,0 +1,96 @@ +from __future__ import absolute_import + +import sys + +from pip._internal.cache import WheelCache +from pip._internal.cli.base_command import Command +from pip._internal.models.format_control import FormatControl +from pip._internal.operations.freeze import freeze +from pip._internal.utils.compat import stdlib_pkgs + +DEV_PKGS = {'pip', 'setuptools', 'distribute', 'wheel'} + + +class FreezeCommand(Command): + """ + Output installed packages in requirements format. + + packages are listed in a case-insensitive sorted order. + """ + name = 'freeze' + usage = """ + %prog [options]""" + summary = 'Output installed packages in requirements format.' + log_streams = ("ext://sys.stderr", "ext://sys.stderr") + + def __init__(self, *args, **kw): + super(FreezeCommand, self).__init__(*args, **kw) + + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help="Use the order in the given requirements file and its " + "comments when generating output. This option can be " + "used multiple times.") + self.cmd_opts.add_option( + '-f', '--find-links', + dest='find_links', + action='append', + default=[], + metavar='URL', + help='URL for finding packages, which will be added to the ' + 'output.') + self.cmd_opts.add_option( + '-l', '--local', + dest='local', + action='store_true', + default=False, + help='If in a virtualenv that has global access, do not output ' + 'globally-installed packages.') + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + self.cmd_opts.add_option( + '--all', + dest='freeze_all', + action='store_true', + help='Do not skip these packages in the output:' + ' %s' % ', '.join(DEV_PKGS)) + self.cmd_opts.add_option( + '--exclude-editable', + dest='exclude_editable', + action='store_true', + help='Exclude editable package from output.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + format_control = FormatControl(set(), set()) + wheel_cache = WheelCache(options.cache_dir, format_control) + skip = set(stdlib_pkgs) + if not options.freeze_all: + skip.update(DEV_PKGS) + + freeze_kwargs = dict( + requirement=options.requirements, + find_links=options.find_links, + local_only=options.local, + user_only=options.user, + skip_regex=options.skip_requirements_regex, + isolated=options.isolated_mode, + wheel_cache=wheel_cache, + skip=skip, + exclude_editable=options.exclude_editable, + ) + + try: + for line in freeze(**freeze_kwargs): + sys.stdout.write(line + '\n') + finally: + wheel_cache.cleanup() diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/hash.py b/env/lib/python3.7/site-packages/pip/_internal/commands/hash.py new file mode 100644 index 0000000..423440e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/hash.py @@ -0,0 +1,57 @@ +from __future__ import absolute_import + +import hashlib +import logging +import sys + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR +from pip._internal.utils.hashes import FAVORITE_HASH, STRONG_HASHES +from pip._internal.utils.misc import read_chunks + +logger = logging.getLogger(__name__) + + +class HashCommand(Command): + """ + Compute a hash of a local package archive. + + These can be used with --hash in a requirements file to do repeatable + installs. + + """ + name = 'hash' + usage = '%prog [options] ...' + summary = 'Compute hashes of package archives.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(HashCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-a', '--algorithm', + dest='algorithm', + choices=STRONG_HASHES, + action='store', + default=FAVORITE_HASH, + help='The hash algorithm to use: one of %s' % + ', '.join(STRONG_HASHES)) + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + self.parser.print_usage(sys.stderr) + return ERROR + + algorithm = options.algorithm + for path in args: + logger.info('%s:\n--hash=%s:%s', + path, algorithm, _hash_of_file(path, algorithm)) + + +def _hash_of_file(path, algorithm): + """Return the hash digest of a file.""" + with open(path, 'rb') as archive: + hash = hashlib.new(algorithm) + for chunk in read_chunks(archive): + hash.update(chunk) + return hash.hexdigest() diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/help.py b/env/lib/python3.7/site-packages/pip/_internal/commands/help.py new file mode 100644 index 0000000..49a81cb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/help.py @@ -0,0 +1,37 @@ +from __future__ import absolute_import + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import SUCCESS +from pip._internal.exceptions import CommandError + + +class HelpCommand(Command): + """Show help for commands""" + name = 'help' + usage = """ + %prog """ + summary = 'Show help for commands.' + ignore_require_venv = True + + def run(self, options, args): + from pip._internal.commands import commands_dict, get_similar_commands + + try: + # 'pip help' with no args is handled by pip.__init__.parseopt() + cmd_name = args[0] # the command we need help for + except IndexError: + return SUCCESS + + if cmd_name not in commands_dict: + guess = get_similar_commands(cmd_name) + + msg = ['unknown command "%s"' % cmd_name] + if guess: + msg.append('maybe you meant "%s"' % guess) + + raise CommandError(' - '.join(msg)) + + command = commands_dict[cmd_name]() + command.parser.print_help() + + return SUCCESS diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/install.py b/env/lib/python3.7/site-packages/pip/_internal/commands/install.py new file mode 100644 index 0000000..6fc178f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/install.py @@ -0,0 +1,535 @@ +from __future__ import absolute_import + +import errno +import logging +import operator +import os +import shutil +from optparse import SUPPRESS_HELP + +from pip._vendor import pkg_resources + +from pip._internal.cache import WheelCache +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import RequirementCommand +from pip._internal.cli.status_codes import ERROR +from pip._internal.exceptions import ( + CommandError, InstallationError, PreviousBuildDirError, +) +from pip._internal.locations import distutils_scheme, virtualenv_no_global +from pip._internal.operations.check import check_install_conflicts +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet, install_given_reqs +from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.resolve import Resolver +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ( + ensure_dir, get_installed_version, + protect_pip_from_modification_on_windows, +) +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +try: + import wheel +except ImportError: + wheel = None + + +logger = logging.getLogger(__name__) + + +class InstallCommand(RequirementCommand): + """ + Install packages from: + + - PyPI (and other indexes) using requirement specifiers. + - VCS project urls. + - Local project directories. + - Local or remote source archives. + + pip also supports installing from "requirements files", which provide + an easy way to specify a whole environment to be installed. + """ + name = 'install' + + usage = """ + %prog [options] [package-index-options] ... + %prog [options] -r [package-index-options] ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Install packages.' + + def __init__(self, *args, **kw): + super(InstallCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.pre()) + + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option( + '-t', '--target', + dest='target_dir', + metavar='dir', + default=None, + help='Install packages into . ' + 'By default this will not replace existing files/folders in ' + '. Use --upgrade to replace existing packages in ' + 'with new versions.' + ) + cmd_opts.add_option(cmdoptions.platform()) + cmd_opts.add_option(cmdoptions.python_version()) + cmd_opts.add_option(cmdoptions.implementation()) + cmd_opts.add_option(cmdoptions.abi()) + + cmd_opts.add_option( + '--user', + dest='use_user_site', + action='store_true', + help="Install to the Python user install directory for your " + "platform. Typically ~/.local/, or %APPDATA%\\Python on " + "Windows. (See the Python documentation for site.USER_BASE " + "for full details.)") + cmd_opts.add_option( + '--no-user', + dest='use_user_site', + action='store_false', + help=SUPPRESS_HELP) + cmd_opts.add_option( + '--root', + dest='root_path', + metavar='dir', + default=None, + help="Install everything relative to this alternate root " + "directory.") + cmd_opts.add_option( + '--prefix', + dest='prefix_path', + metavar='dir', + default=None, + help="Installation prefix where lib, bin and other top-level " + "folders are placed") + + cmd_opts.add_option(cmdoptions.build_dir()) + + cmd_opts.add_option(cmdoptions.src()) + + cmd_opts.add_option( + '-U', '--upgrade', + dest='upgrade', + action='store_true', + help='Upgrade all specified packages to the newest available ' + 'version. The handling of dependencies depends on the ' + 'upgrade-strategy used.' + ) + + cmd_opts.add_option( + '--upgrade-strategy', + dest='upgrade_strategy', + default='only-if-needed', + choices=['only-if-needed', 'eager'], + help='Determines how dependency upgrading should be handled ' + '[default: %default]. ' + '"eager" - dependencies are upgraded regardless of ' + 'whether the currently installed version satisfies the ' + 'requirements of the upgraded package(s). ' + '"only-if-needed" - are upgraded only when they do not ' + 'satisfy the requirements of the upgraded package(s).' + ) + + cmd_opts.add_option( + '--force-reinstall', + dest='force_reinstall', + action='store_true', + help='Reinstall all packages even if they are already ' + 'up-to-date.') + + cmd_opts.add_option( + '-I', '--ignore-installed', + dest='ignore_installed', + action='store_true', + help='Ignore the installed packages (reinstalling instead).') + + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + + cmd_opts.add_option(cmdoptions.install_options()) + cmd_opts.add_option(cmdoptions.global_options()) + + cmd_opts.add_option( + "--compile", + action="store_true", + dest="compile", + default=True, + help="Compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-compile", + action="store_false", + dest="compile", + help="Do not compile Python source files to bytecode", + ) + + cmd_opts.add_option( + "--no-warn-script-location", + action="store_false", + dest="warn_script_location", + default=True, + help="Do not warn when installing scripts outside PATH", + ) + cmd_opts.add_option( + "--no-warn-conflicts", + action="store_false", + dest="warn_about_conflicts", + default=True, + help="Do not warn about broken dependencies", + ) + + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.prefer_binary()) + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + upgrade_strategy = "to-satisfy-only" + if options.upgrade: + upgrade_strategy = options.upgrade_strategy + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + cmdoptions.check_dist_restriction(options, check_target=True) + + if options.python_version: + python_versions = [options.python_version] + else: + python_versions = None + + options.src_dir = os.path.abspath(options.src_dir) + install_options = options.install_options or [] + if options.use_user_site: + if options.prefix_path: + raise CommandError( + "Can not combine '--user' and '--prefix' as they imply " + "different installation locations" + ) + if virtualenv_no_global(): + raise InstallationError( + "Can not perform a '--user' install. User site-packages " + "are not visible in this virtualenv." + ) + install_options.append('--user') + install_options.append('--prefix=') + + target_temp_dir = TempDirectory(kind="target") + if options.target_dir: + options.ignore_installed = True + options.target_dir = os.path.abspath(options.target_dir) + if (os.path.exists(options.target_dir) and not + os.path.isdir(options.target_dir)): + raise CommandError( + "Target path exists but is not a directory, will not " + "continue." + ) + + # Create a target directory for using with the target option + target_temp_dir.create() + install_options.append('--home=' + target_temp_dir.path) + + global_options = options.global_options or [] + + with self._build_session(options) as session: + finder = self._build_package_finder( + options=options, + session=session, + platform=options.platform, + python_versions=python_versions, + abi=options.abi, + implementation=options.implementation, + ) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + if options.cache_dir and not check_path_owner(options.cache_dir): + logger.warning( + "The directory '%s' or its parent directory is not owned " + "by the current user and caching wheels has been " + "disabled. check the permissions and owner of that " + "directory. If executing pip with sudo, you may want " + "sudo's -H flag.", + options.cache_dir, + ) + options.cache_dir = None + + with RequirementTracker() as req_tracker, TempDirectory( + options.build_dir, delete=build_delete, kind="install" + ) as directory: + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + check_supported_wheels=not options.target_dir, + ) + + try: + self.populate_requirement_set( + requirement_set, args, options, finder, session, + self.name, wheel_cache + ) + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=None, + wheel_download_dir=None, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + req_tracker=req_tracker, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=wheel_cache, + use_user_site=options.use_user_site, + upgrade_strategy=upgrade_strategy, + force_reinstall=options.force_reinstall, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=options.ignore_requires_python, + ignore_installed=options.ignore_installed, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + protect_pip_from_modification_on_windows( + modifying_pip=requirement_set.has_requirement("pip") + ) + + # If caching is disabled or wheel is not installed don't + # try to build wheels. + if wheel and options.cache_dir: + # build wheels before install. + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=[], global_options=[], + ) + # Ignore the result: a failed wheel will be + # installed from the sdist/vcs whatever. + wb.build( + requirement_set.requirements.values(), + session=session, autobuilding=True + ) + + to_install = resolver.get_installation_order( + requirement_set + ) + + # Consistency Checking of the package set we're installing. + should_warn_about_conflicts = ( + not options.ignore_dependencies and + options.warn_about_conflicts + ) + if should_warn_about_conflicts: + self._warn_about_conflicts(to_install) + + # Don't warn about script install locations if + # --target has been specified + warn_script_location = options.warn_script_location + if options.target_dir: + warn_script_location = False + + installed = install_given_reqs( + to_install, + install_options, + global_options, + root=options.root_path, + home=target_temp_dir.path, + prefix=options.prefix_path, + pycompile=options.compile, + warn_script_location=warn_script_location, + use_user_site=options.use_user_site, + ) + + lib_locations = get_lib_location_guesses( + user=options.use_user_site, + home=target_temp_dir.path, + root=options.root_path, + prefix=options.prefix_path, + isolated=options.isolated_mode, + ) + working_set = pkg_resources.WorkingSet(lib_locations) + + reqs = sorted(installed, key=operator.attrgetter('name')) + items = [] + for req in reqs: + item = req.name + try: + installed_version = get_installed_version( + req.name, working_set=working_set + ) + if installed_version: + item += '-' + installed_version + except Exception: + pass + items.append(item) + installed = ' '.join(items) + if installed: + logger.info('Successfully installed %s', installed) + except EnvironmentError as error: + show_traceback = (self.verbosity >= 1) + + message = create_env_error_message( + error, show_traceback, options.use_user_site, + ) + logger.error(message, exc_info=show_traceback) + + return ERROR + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + # Clean up + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() + + if options.target_dir: + self._handle_target_dir( + options.target_dir, target_temp_dir, options.upgrade + ) + return requirement_set + + def _handle_target_dir(self, target_dir, target_temp_dir, upgrade): + ensure_dir(target_dir) + + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + lib_dir_list = [] + + with target_temp_dir: + # Checking both purelib and platlib directories for installed + # packages to be moved to target directory + scheme = distutils_scheme('', home=target_temp_dir.path) + purelib_dir = scheme['purelib'] + platlib_dir = scheme['platlib'] + data_dir = scheme['data'] + + if os.path.exists(purelib_dir): + lib_dir_list.append(purelib_dir) + if os.path.exists(platlib_dir) and platlib_dir != purelib_dir: + lib_dir_list.append(platlib_dir) + if os.path.exists(data_dir): + lib_dir_list.append(data_dir) + + for lib_dir in lib_dir_list: + for item in os.listdir(lib_dir): + if lib_dir == data_dir: + ddir = os.path.join(data_dir, item) + if any(s.startswith(ddir) for s in lib_dir_list[:-1]): + continue + target_item_dir = os.path.join(target_dir, item) + if os.path.exists(target_item_dir): + if not upgrade: + logger.warning( + 'Target directory %s already exists. Specify ' + '--upgrade to force replacement.', + target_item_dir + ) + continue + if os.path.islink(target_item_dir): + logger.warning( + 'Target directory %s already exists and is ' + 'a link. Pip will not automatically replace ' + 'links, please remove if replacement is ' + 'desired.', + target_item_dir + ) + continue + if os.path.isdir(target_item_dir): + shutil.rmtree(target_item_dir) + else: + os.remove(target_item_dir) + + shutil.move( + os.path.join(lib_dir, item), + target_item_dir + ) + + def _warn_about_conflicts(self, to_install): + package_set, _dep_info = check_install_conflicts(to_install) + missing, conflicting = _dep_info + + # NOTE: There is some duplication here from pip check + for project_name in missing: + version = package_set[project_name][0] + for dependency in missing[project_name]: + logger.critical( + "%s %s requires %s, which is not installed.", + project_name, version, dependency[1], + ) + + for project_name in conflicting: + version = package_set[project_name][0] + for dep_name, dep_version, req in conflicting[project_name]: + logger.critical( + "%s %s has requirement %s, but you'll have %s %s which is " + "incompatible.", + project_name, version, req, dep_name, dep_version, + ) + + +def get_lib_location_guesses(*args, **kwargs): + scheme = distutils_scheme('', *args, **kwargs) + return [scheme['purelib'], scheme['platlib']] + + +def create_env_error_message(error, show_traceback, using_user_site): + """Format an error message for an EnvironmentError + + It may occur anytime during the execution of the install command. + """ + parts = [] + + # Mention the error if we are not going to show a traceback + parts.append("Could not install packages due to an EnvironmentError") + if not show_traceback: + parts.append(": ") + parts.append(str(error)) + else: + parts.append(".") + + # Spilt the error indication from a helper message (if any) + parts[-1] += "\n" + + # Suggest useful actions to the user: + # (1) using user site-packages or (2) verifying the permissions + if error.errno == errno.EACCES: + user_option_part = "Consider using the `--user` option" + permissions_part = "Check the permissions" + + if not using_user_site: + parts.extend([ + user_option_part, " or ", + permissions_part.lower(), + ]) + else: + parts.append(permissions_part) + parts.append(".\n") + + return "".join(parts).strip() + "\n" diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/list.py b/env/lib/python3.7/site-packages/pip/_internal/commands/list.py new file mode 100644 index 0000000..c6eeca7 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/list.py @@ -0,0 +1,306 @@ +from __future__ import absolute_import + +import json +import logging + +from pip._vendor import six +from pip._vendor.six.moves import zip_longest + +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import Command +from pip._internal.exceptions import CommandError +from pip._internal.index import PackageFinder +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, +) +from pip._internal.utils.packaging import get_installer + +logger = logging.getLogger(__name__) + + +class ListCommand(Command): + """ + List installed packages, including editables. + + Packages are listed in a case-insensitive sorted order. + """ + name = 'list' + usage = """ + %prog [options]""" + summary = 'List installed packages.' + + def __init__(self, *args, **kw): + super(ListCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-o', '--outdated', + action='store_true', + default=False, + help='List outdated packages') + cmd_opts.add_option( + '-u', '--uptodate', + action='store_true', + default=False, + help='List uptodate packages') + cmd_opts.add_option( + '-e', '--editable', + action='store_true', + default=False, + help='List editable projects.') + cmd_opts.add_option( + '-l', '--local', + action='store_true', + default=False, + help=('If in a virtualenv that has global access, do not list ' + 'globally-installed packages.'), + ) + self.cmd_opts.add_option( + '--user', + dest='user', + action='store_true', + default=False, + help='Only output packages installed in user-site.') + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option( + '--format', + action='store', + dest='list_format', + default="columns", + choices=('columns', 'freeze', 'json'), + help="Select the output format among: columns (default), freeze, " + "or json", + ) + + cmd_opts.add_option( + '--not-required', + action='store_true', + dest='not_required', + help="List packages that are not dependencies of " + "installed packages.", + ) + + cmd_opts.add_option( + '--exclude-editable', + action='store_false', + dest='include_editable', + help='Exclude editable package from output.', + ) + cmd_opts.add_option( + '--include-editable', + action='store_true', + dest='include_editable', + help='Include editable package from output.', + default=True, + ) + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, self.parser + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def _build_package_finder(self, options, index_urls, session): + """ + Create a package finder appropriate to this list command. + """ + return PackageFinder( + find_links=options.find_links, + index_urls=index_urls, + allow_all_prereleases=options.pre, + trusted_hosts=options.trusted_hosts, + process_dependency_links=options.process_dependency_links, + session=session, + ) + + def run(self, options, args): + if options.outdated and options.uptodate: + raise CommandError( + "Options --outdated and --uptodate cannot be combined.") + + packages = get_installed_distributions( + local_only=options.local, + user_only=options.user, + editables_only=options.editable, + include_editables=options.include_editable, + ) + + if options.outdated: + packages = self.get_outdated(packages, options) + elif options.uptodate: + packages = self.get_uptodate(packages, options) + + if options.not_required: + packages = self.get_not_required(packages, options) + + self.output_package_listing(packages, options) + + def get_outdated(self, packages, options): + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version > dist.parsed_version + ] + + def get_uptodate(self, packages, options): + return [ + dist for dist in self.iter_packages_latest_infos(packages, options) + if dist.latest_version == dist.parsed_version + ] + + def get_not_required(self, packages, options): + dep_keys = set() + for dist in packages: + dep_keys.update(requirement.key for requirement in dist.requires()) + return {pkg for pkg in packages if pkg.key not in dep_keys} + + def iter_packages_latest_infos(self, packages, options): + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + dependency_links = [] + for dist in packages: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend( + dist.get_metadata_lines('dependency_links.txt'), + ) + + with self._build_session(options) as session: + finder = self._build_package_finder(options, index_urls, session) + finder.add_dependency_links(dependency_links) + + for dist in packages: + typ = 'unknown' + all_candidates = finder.find_all_candidates(dist.key) + if not options.pre: + # Remove prereleases + all_candidates = [candidate for candidate in all_candidates + if not candidate.version.is_prerelease] + + if not all_candidates: + continue + best_candidate = max(all_candidates, + key=finder._candidate_sort_key) + remote_version = best_candidate.version + if best_candidate.location.is_wheel: + typ = 'wheel' + else: + typ = 'sdist' + # This is dirty but makes the rest of the code much cleaner + dist.latest_version = remote_version + dist.latest_filetype = typ + yield dist + + def output_package_listing(self, packages, options): + packages = sorted( + packages, + key=lambda dist: dist.project_name.lower(), + ) + if options.list_format == 'columns' and packages: + data, header = format_for_columns(packages, options) + self.output_package_listing_columns(data, header) + elif options.list_format == 'freeze': + for dist in packages: + if options.verbose >= 1: + logger.info("%s==%s (%s)", dist.project_name, + dist.version, dist.location) + else: + logger.info("%s==%s", dist.project_name, dist.version) + elif options.list_format == 'json': + logger.info(format_for_json(packages, options)) + + def output_package_listing_columns(self, data, header): + # insert the header first: we need to know the size of column names + if len(data) > 0: + data.insert(0, header) + + pkg_strings, sizes = tabulate(data) + + # Create and add a separator. + if len(data) > 0: + pkg_strings.insert(1, " ".join(map(lambda x: '-' * x, sizes))) + + for val in pkg_strings: + logger.info(val) + + +def tabulate(vals): + # From pfmoore on GitHub: + # https://github.com/pypa/pip/issues/3651#issuecomment-216932564 + assert len(vals) > 0 + + sizes = [0] * max(len(x) for x in vals) + for row in vals: + sizes = [max(s, len(str(c))) for s, c in zip_longest(sizes, row)] + + result = [] + for row in vals: + display = " ".join([str(c).ljust(s) if c is not None else '' + for s, c in zip_longest(sizes, row)]) + result.append(display) + + return result, sizes + + +def format_for_columns(pkgs, options): + """ + Convert the package data into something usable + by output_package_listing_columns. + """ + running_outdated = options.outdated + # Adjust the header for the `pip list --outdated` case. + if running_outdated: + header = ["Package", "Version", "Latest", "Type"] + else: + header = ["Package", "Version"] + + data = [] + if options.verbose >= 1 or any(dist_is_editable(x) for x in pkgs): + header.append("Location") + if options.verbose >= 1: + header.append("Installer") + + for proj in pkgs: + # if we're working on the 'outdated' list, separate out the + # latest_version and type + row = [proj.project_name, proj.version] + + if running_outdated: + row.append(proj.latest_version) + row.append(proj.latest_filetype) + + if options.verbose >= 1 or dist_is_editable(proj): + row.append(proj.location) + if options.verbose >= 1: + row.append(get_installer(proj)) + + data.append(row) + + return data, header + + +def format_for_json(packages, options): + data = [] + for dist in packages: + info = { + 'name': dist.project_name, + 'version': six.text_type(dist.version), + } + if options.verbose >= 1: + info['location'] = dist.location + info['installer'] = get_installer(dist) + if options.outdated: + info['latest_version'] = six.text_type(dist.latest_version) + info['latest_filetype'] = dist.latest_filetype + data.append(info) + return json.dumps(data) diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/search.py b/env/lib/python3.7/site-packages/pip/_internal/commands/search.py new file mode 100644 index 0000000..c157a31 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/search.py @@ -0,0 +1,135 @@ +from __future__ import absolute_import + +import logging +import sys +import textwrap +from collections import OrderedDict + +from pip._vendor import pkg_resources +from pip._vendor.packaging.version import parse as parse_version +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import NO_MATCHES_FOUND, SUCCESS +from pip._internal.download import PipXmlrpcTransport +from pip._internal.exceptions import CommandError +from pip._internal.models.index import PyPI +from pip._internal.utils.compat import get_terminal_size +from pip._internal.utils.logging import indent_log + +logger = logging.getLogger(__name__) + + +class SearchCommand(Command): + """Search for PyPI packages whose name or summary contains .""" + name = 'search' + usage = """ + %prog [options] """ + summary = 'Search PyPI for packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(SearchCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-i', '--index', + dest='index', + metavar='URL', + default=PyPI.pypi_url, + help='Base URL of Python Package Index (default %default)') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + raise CommandError('Missing required argument (search query).') + query = args + pypi_hits = self.search(query, options) + hits = transform_hits(pypi_hits) + + terminal_width = None + if sys.stdout.isatty(): + terminal_width = get_terminal_size()[0] + + print_results(hits, terminal_width=terminal_width) + if pypi_hits: + return SUCCESS + return NO_MATCHES_FOUND + + def search(self, query, options): + index_url = options.index + with self._build_session(options) as session: + transport = PipXmlrpcTransport(index_url, session) + pypi = xmlrpc_client.ServerProxy(index_url, transport) + hits = pypi.search({'name': query, 'summary': query}, 'or') + return hits + + +def transform_hits(hits): + """ + The list from pypi is really a list of versions. We want a list of + packages with the list of versions stored inline. This converts the + list from pypi into one we can use. + """ + packages = OrderedDict() + for hit in hits: + name = hit['name'] + summary = hit['summary'] + version = hit['version'] + + if name not in packages.keys(): + packages[name] = { + 'name': name, + 'summary': summary, + 'versions': [version], + } + else: + packages[name]['versions'].append(version) + + # if this is the highest version, replace summary and score + if version == highest_version(packages[name]['versions']): + packages[name]['summary'] = summary + + return list(packages.values()) + + +def print_results(hits, name_column_width=None, terminal_width=None): + if not hits: + return + if name_column_width is None: + name_column_width = max([ + len(hit['name']) + len(highest_version(hit.get('versions', ['-']))) + for hit in hits + ]) + 4 + + installed_packages = [p.project_name for p in pkg_resources.working_set] + for hit in hits: + name = hit['name'] + summary = hit['summary'] or '' + latest = highest_version(hit.get('versions', ['-'])) + if terminal_width is not None: + target_width = terminal_width - name_column_width - 5 + if target_width > 10: + # wrap and indent summary to fit terminal + summary = textwrap.wrap(summary, target_width) + summary = ('\n' + ' ' * (name_column_width + 3)).join(summary) + + line = '%-*s - %s' % (name_column_width, + '%s (%s)' % (name, latest), summary) + try: + logger.info(line) + if name in installed_packages: + dist = pkg_resources.get_distribution(name) + with indent_log(): + if dist.version == latest: + logger.info('INSTALLED: %s (latest)', dist.version) + else: + logger.info('INSTALLED: %s', dist.version) + logger.info('LATEST: %s', latest) + except UnicodeEncodeError: + pass + + +def highest_version(versions): + return max(versions, key=parse_version) diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/show.py b/env/lib/python3.7/site-packages/pip/_internal/commands/show.py new file mode 100644 index 0000000..f92c9bc --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/show.py @@ -0,0 +1,168 @@ +from __future__ import absolute_import + +import logging +import os +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cli.base_command import Command +from pip._internal.cli.status_codes import ERROR, SUCCESS + +logger = logging.getLogger(__name__) + + +class ShowCommand(Command): + """ + Show information about one or more installed packages. + + The output is in RFC-compliant mail header format. + """ + name = 'show' + usage = """ + %prog [options] ...""" + summary = 'Show information about installed packages.' + ignore_require_venv = True + + def __init__(self, *args, **kw): + super(ShowCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-f', '--files', + dest='files', + action='store_true', + default=False, + help='Show the full list of installed files for each package.') + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + if not args: + logger.warning('ERROR: Please provide a package name or names.') + return ERROR + query = args + + results = search_packages_info(query) + if not print_results( + results, list_files=options.files, verbose=options.verbose): + return ERROR + return SUCCESS + + +def search_packages_info(query): + """ + Gather details from installed distributions. Print distribution name, + version, location, and installed files. Installed files requires a + pip generated 'installed-files.txt' in the distributions '.egg-info' + directory. + """ + installed = {} + for p in pkg_resources.working_set: + installed[canonicalize_name(p.project_name)] = p + + query_names = [canonicalize_name(name) for name in query] + + for dist in [installed[pkg] for pkg in query_names if pkg in installed]: + package = { + 'name': dist.project_name, + 'version': dist.version, + 'location': dist.location, + 'requires': [dep.project_name for dep in dist.requires()], + } + file_list = None + metadata = None + if isinstance(dist, pkg_resources.DistInfoDistribution): + # RECORDs should be part of .dist-info metadatas + if dist.has_metadata('RECORD'): + lines = dist.get_metadata_lines('RECORD') + paths = [l.split(',')[0] for l in lines] + paths = [os.path.join(dist.location, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('METADATA'): + metadata = dist.get_metadata('METADATA') + else: + # Otherwise use pip's log for .egg-info's + if dist.has_metadata('installed-files.txt'): + paths = dist.get_metadata_lines('installed-files.txt') + paths = [os.path.join(dist.egg_info, p) for p in paths] + file_list = [os.path.relpath(p, dist.location) for p in paths] + + if dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + + if dist.has_metadata('entry_points.txt'): + entry_points = dist.get_metadata_lines('entry_points.txt') + package['entry_points'] = entry_points + + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + package['installer'] = line.strip() + break + + # @todo: Should pkg_resources.Distribution have a + # `get_pkg_info` method? + feed_parser = FeedParser() + feed_parser.feed(metadata) + pkg_info_dict = feed_parser.close() + for key in ('metadata-version', 'summary', + 'home-page', 'author', 'author-email', 'license'): + package[key] = pkg_info_dict.get(key) + + # It looks like FeedParser cannot deal with repeated headers + classifiers = [] + for line in metadata.splitlines(): + if line.startswith('Classifier: '): + classifiers.append(line[len('Classifier: '):]) + package['classifiers'] = classifiers + + if file_list: + package['files'] = sorted(file_list) + yield package + + +def print_results(distributions, list_files=False, verbose=False): + """ + Print the informations from installed distributions found. + """ + results_printed = False + for i, dist in enumerate(distributions): + results_printed = True + if i > 0: + logger.info("---") + + name = dist.get('name', '') + required_by = [ + pkg.project_name for pkg in pkg_resources.working_set + if name in [required.name for required in pkg.requires()] + ] + + logger.info("Name: %s", name) + logger.info("Version: %s", dist.get('version', '')) + logger.info("Summary: %s", dist.get('summary', '')) + logger.info("Home-page: %s", dist.get('home-page', '')) + logger.info("Author: %s", dist.get('author', '')) + logger.info("Author-email: %s", dist.get('author-email', '')) + logger.info("License: %s", dist.get('license', '')) + logger.info("Location: %s", dist.get('location', '')) + logger.info("Requires: %s", ', '.join(dist.get('requires', []))) + logger.info("Required-by: %s", ', '.join(required_by)) + + if verbose: + logger.info("Metadata-Version: %s", + dist.get('metadata-version', '')) + logger.info("Installer: %s", dist.get('installer', '')) + logger.info("Classifiers:") + for classifier in dist.get('classifiers', []): + logger.info(" %s", classifier) + logger.info("Entry-points:") + for entry in dist.get('entry_points', []): + logger.info(" %s", entry.strip()) + if list_files: + logger.info("Files:") + for line in dist.get('files', []): + logger.info(" %s", line.strip()) + if "files" not in dist: + logger.info("Cannot locate installed-files.txt") + return results_printed diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py b/env/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py new file mode 100644 index 0000000..0cd6f54 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/uninstall.py @@ -0,0 +1,78 @@ +from __future__ import absolute_import + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.cli.base_command import Command +from pip._internal.exceptions import InstallationError +from pip._internal.req import parse_requirements +from pip._internal.req.constructors import install_req_from_line +from pip._internal.utils.misc import protect_pip_from_modification_on_windows + + +class UninstallCommand(Command): + """ + Uninstall packages. + + pip is able to uninstall most installed packages. Known exceptions are: + + - Pure distutils packages installed with ``python setup.py install``, which + leave behind no metadata to determine what files were installed. + - Script wrappers installed by ``python setup.py develop``. + """ + name = 'uninstall' + usage = """ + %prog [options] ... + %prog [options] -r ...""" + summary = 'Uninstall packages.' + + def __init__(self, *args, **kw): + super(UninstallCommand, self).__init__(*args, **kw) + self.cmd_opts.add_option( + '-r', '--requirement', + dest='requirements', + action='append', + default=[], + metavar='file', + help='Uninstall all the packages listed in the given requirements ' + 'file. This option can be used multiple times.', + ) + self.cmd_opts.add_option( + '-y', '--yes', + dest='yes', + action='store_true', + help="Don't ask for confirmation of uninstall deletions.") + + self.parser.insert_option_group(0, self.cmd_opts) + + def run(self, options, args): + with self._build_session(options) as session: + reqs_to_uninstall = {} + for name in args: + req = install_req_from_line( + name, isolated=options.isolated_mode, + ) + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + for filename in options.requirements: + for req in parse_requirements( + filename, + options=options, + session=session): + if req.name: + reqs_to_uninstall[canonicalize_name(req.name)] = req + if not reqs_to_uninstall: + raise InstallationError( + 'You must give at least one requirement to %(name)s (see ' + '"pip help %(name)s")' % dict(name=self.name) + ) + + protect_pip_from_modification_on_windows( + modifying_pip="pip" in reqs_to_uninstall + ) + + for req in reqs_to_uninstall.values(): + uninstall_pathset = req.uninstall( + auto_confirm=options.yes, verbose=self.verbosity > 0, + ) + if uninstall_pathset: + uninstall_pathset.commit() diff --git a/env/lib/python3.7/site-packages/pip/_internal/commands/wheel.py b/env/lib/python3.7/site-packages/pip/_internal/commands/wheel.py new file mode 100644 index 0000000..9c1f149 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/commands/wheel.py @@ -0,0 +1,183 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import + +import logging +import os + +from pip._internal.cache import WheelCache +from pip._internal.cli import cmdoptions +from pip._internal.cli.base_command import RequirementCommand +from pip._internal.exceptions import CommandError, PreviousBuildDirError +from pip._internal.operations.prepare import RequirementPreparer +from pip._internal.req import RequirementSet +from pip._internal.req.req_tracker import RequirementTracker +from pip._internal.resolve import Resolver +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.wheel import WheelBuilder + +logger = logging.getLogger(__name__) + + +class WheelCommand(RequirementCommand): + """ + Build Wheel archives for your requirements and dependencies. + + Wheel is a built-package format, and offers the advantage of not + recompiling your software during every install. For more details, see the + wheel docs: https://wheel.readthedocs.io/en/latest/ + + Requirements: setuptools>=0.8, and wheel. + + 'pip wheel' uses the bdist_wheel setuptools extension from the wheel + package to build individual wheels. + + """ + + name = 'wheel' + usage = """ + %prog [options] ... + %prog [options] -r ... + %prog [options] [-e] ... + %prog [options] [-e] ... + %prog [options] ...""" + + summary = 'Build wheels from your requirements.' + + def __init__(self, *args, **kw): + super(WheelCommand, self).__init__(*args, **kw) + + cmd_opts = self.cmd_opts + + cmd_opts.add_option( + '-w', '--wheel-dir', + dest='wheel_dir', + metavar='dir', + default=os.curdir, + help=("Build wheels into , where the default is the " + "current working directory."), + ) + cmd_opts.add_option(cmdoptions.no_binary()) + cmd_opts.add_option(cmdoptions.only_binary()) + cmd_opts.add_option(cmdoptions.prefer_binary()) + cmd_opts.add_option( + '--build-option', + dest='build_options', + metavar='options', + action='append', + help="Extra arguments to be supplied to 'setup.py bdist_wheel'.", + ) + cmd_opts.add_option(cmdoptions.no_build_isolation()) + cmd_opts.add_option(cmdoptions.constraints()) + cmd_opts.add_option(cmdoptions.editable()) + cmd_opts.add_option(cmdoptions.requirements()) + cmd_opts.add_option(cmdoptions.src()) + cmd_opts.add_option(cmdoptions.ignore_requires_python()) + cmd_opts.add_option(cmdoptions.no_deps()) + cmd_opts.add_option(cmdoptions.build_dir()) + cmd_opts.add_option(cmdoptions.progress_bar()) + + cmd_opts.add_option( + '--global-option', + dest='global_options', + action='append', + metavar='options', + help="Extra global options to be supplied to the setup.py " + "call before the 'bdist_wheel' command.") + + cmd_opts.add_option( + '--pre', + action='store_true', + default=False, + help=("Include pre-release and development versions. By default, " + "pip only finds stable versions."), + ) + + cmd_opts.add_option(cmdoptions.no_clean()) + cmd_opts.add_option(cmdoptions.require_hashes()) + + index_opts = cmdoptions.make_option_group( + cmdoptions.index_group, + self.parser, + ) + + self.parser.insert_option_group(0, index_opts) + self.parser.insert_option_group(0, cmd_opts) + + def run(self, options, args): + cmdoptions.check_install_build_global(options) + + index_urls = [options.index_url] + options.extra_index_urls + if options.no_index: + logger.debug('Ignoring indexes: %s', ','.join(index_urls)) + index_urls = [] + + if options.build_dir: + options.build_dir = os.path.abspath(options.build_dir) + + options.src_dir = os.path.abspath(options.src_dir) + + with self._build_session(options) as session: + finder = self._build_package_finder(options, session) + build_delete = (not (options.no_clean or options.build_dir)) + wheel_cache = WheelCache(options.cache_dir, options.format_control) + + with RequirementTracker() as req_tracker, TempDirectory( + options.build_dir, delete=build_delete, kind="wheel" + ) as directory: + + requirement_set = RequirementSet( + require_hashes=options.require_hashes, + ) + + try: + self.populate_requirement_set( + requirement_set, args, options, finder, session, + self.name, wheel_cache + ) + + preparer = RequirementPreparer( + build_dir=directory.path, + src_dir=options.src_dir, + download_dir=None, + wheel_download_dir=options.wheel_dir, + progress_bar=options.progress_bar, + build_isolation=options.build_isolation, + req_tracker=req_tracker, + ) + + resolver = Resolver( + preparer=preparer, + finder=finder, + session=session, + wheel_cache=wheel_cache, + use_user_site=False, + upgrade_strategy="to-satisfy-only", + force_reinstall=False, + ignore_dependencies=options.ignore_dependencies, + ignore_requires_python=options.ignore_requires_python, + ignore_installed=True, + isolated=options.isolated_mode, + ) + resolver.resolve(requirement_set) + + # build wheels + wb = WheelBuilder( + finder, preparer, wheel_cache, + build_options=options.build_options or [], + global_options=options.global_options or [], + no_clean=options.no_clean, + ) + wheels_built_successfully = wb.build( + requirement_set.requirements.values(), session=session, + ) + if not wheels_built_successfully: + raise CommandError( + "Failed to build one or more wheels" + ) + except PreviousBuildDirError: + options.no_clean = True + raise + finally: + if not options.no_clean: + requirement_set.cleanup_files() + wheel_cache.cleanup() diff --git a/env/lib/python3.7/site-packages/pip/_internal/configuration.py b/env/lib/python3.7/site-packages/pip/_internal/configuration.py new file mode 100644 index 0000000..fe6df9b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/configuration.py @@ -0,0 +1,387 @@ +"""Configuration management setup + +Some terminology: +- name + As written in config files. +- value + Value associated with a name +- key + Name combined with it's section (section.name) +- variant + A single word describing where the configuration key-value pair came from +""" + +import locale +import logging +import os + +from pip._vendor import six +from pip._vendor.six.moves import configparser + +from pip._internal.exceptions import ( + ConfigurationError, ConfigurationFileCouldNotBeLoaded, +) +from pip._internal.locations import ( + legacy_config_file, new_config_file, running_under_virtualenv, + site_config_files, venv_config_file, +) +from pip._internal.utils.misc import ensure_dir, enum +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import ( # noqa: F401 + Any, Dict, Iterable, List, NewType, Optional, Tuple + ) + + RawConfigParser = configparser.RawConfigParser # Shorthand + Kind = NewType("Kind", str) + +logger = logging.getLogger(__name__) + + +# NOTE: Maybe use the optionx attribute to normalize keynames. +def _normalize_name(name): + # type: (str) -> str + """Make a name consistent regardless of source (environment or file) + """ + name = name.lower().replace('_', '-') + if name.startswith('--'): + name = name[2:] # only prefer long opts + return name + + +def _disassemble_key(name): + # type: (str) -> List[str] + return name.split(".", 1) + + +# The kinds of configurations there are. +kinds = enum( + USER="user", # User Specific + GLOBAL="global", # System Wide + VENV="venv", # Virtual Environment Specific + ENV="env", # from PIP_CONFIG_FILE + ENV_VAR="env-var", # from Environment Variables +) + + +class Configuration(object): + """Handles management of configuration. + + Provides an interface to accessing and managing configuration files. + + This class converts provides an API that takes "section.key-name" style + keys and stores the value associated with it as "key-name" under the + section "section". + + This allows for a clean interface wherein the both the section and the + key-name are preserved in an easy to manage form in the configuration files + and the data stored is also nice. + """ + + def __init__(self, isolated, load_only=None): + # type: (bool, Kind) -> None + super(Configuration, self).__init__() + + _valid_load_only = [kinds.USER, kinds.GLOBAL, kinds.VENV, None] + if load_only not in _valid_load_only: + raise ConfigurationError( + "Got invalid value for load_only - should be one of {}".format( + ", ".join(map(repr, _valid_load_only[:-1])) + ) + ) + self.isolated = isolated # type: bool + self.load_only = load_only # type: Optional[Kind] + + # The order here determines the override order. + self._override_order = [ + kinds.GLOBAL, kinds.USER, kinds.VENV, kinds.ENV, kinds.ENV_VAR + ] + + self._ignore_env_names = ["version", "help"] + + # Because we keep track of where we got the data from + self._parsers = { + variant: [] for variant in self._override_order + } # type: Dict[Kind, List[Tuple[str, RawConfigParser]]] + self._config = { + variant: {} for variant in self._override_order + } # type: Dict[Kind, Dict[str, Any]] + self._modified_parsers = [] # type: List[Tuple[str, RawConfigParser]] + + def load(self): + # type: () -> None + """Loads configuration from configuration files and environment + """ + self._load_config_files() + if not self.isolated: + self._load_environment_vars() + + def get_file_to_edit(self): + # type: () -> Optional[str] + """Returns the file with highest priority in configuration + """ + assert self.load_only is not None, \ + "Need to be specified a file to be editing" + + try: + return self._get_parser_to_modify()[0] + except IndexError: + return None + + def items(self): + # type: () -> Iterable[Tuple[str, Any]] + """Returns key-value pairs like dict.items() representing the loaded + configuration + """ + return self._dictionary.items() + + def get_value(self, key): + # type: (str) -> Any + """Get a value from the configuration. + """ + try: + return self._dictionary[key] + except KeyError: + raise ConfigurationError("No such key - {}".format(key)) + + def set_value(self, key, value): + # type: (str, Any) -> None + """Modify a value in the configuration. + """ + self._ensure_have_load_only() + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Modify the parser and the configuration + if not parser.has_section(section): + parser.add_section(section) + parser.set(section, name, value) + + self._config[self.load_only][key] = value + self._mark_as_modified(fname, parser) + + def unset_value(self, key): + # type: (str) -> None + """Unset a value in the configuration. + """ + self._ensure_have_load_only() + + if key not in self._config[self.load_only]: + raise ConfigurationError("No such key - {}".format(key)) + + fname, parser = self._get_parser_to_modify() + + if parser is not None: + section, name = _disassemble_key(key) + + # Remove the key in the parser + modified_something = False + if parser.has_section(section): + # Returns whether the option was removed or not + modified_something = parser.remove_option(section, name) + + if modified_something: + # name removed from parser, section may now be empty + section_iter = iter(parser.items(section)) + try: + val = six.next(section_iter) + except StopIteration: + val = None + + if val is None: + parser.remove_section(section) + + self._mark_as_modified(fname, parser) + else: + raise ConfigurationError( + "Fatal Internal error [id=1]. Please report as a bug." + ) + + del self._config[self.load_only][key] + + def save(self): + # type: () -> None + """Save the currentin-memory state. + """ + self._ensure_have_load_only() + + for fname, parser in self._modified_parsers: + logger.info("Writing to %s", fname) + + # Ensure directory exists. + ensure_dir(os.path.dirname(fname)) + + with open(fname, "w") as f: + parser.write(f) # type: ignore + + # + # Private routines + # + + def _ensure_have_load_only(self): + # type: () -> None + if self.load_only is None: + raise ConfigurationError("Needed a specific file to be modifying.") + logger.debug("Will be working with %s variant only", self.load_only) + + @property + def _dictionary(self): + # type: () -> Dict[str, Any] + """A dictionary representing the loaded configuration. + """ + # NOTE: Dictionaries are not populated if not loaded. So, conditionals + # are not needed here. + retval = {} + + for variant in self._override_order: + retval.update(self._config[variant]) + + return retval + + def _load_config_files(self): + # type: () -> None + """Loads configuration from configuration files + """ + config_files = dict(self._iter_config_files()) + if config_files[kinds.ENV][0:1] == [os.devnull]: + logger.debug( + "Skipping loading configuration files due to " + "environment's PIP_CONFIG_FILE being os.devnull" + ) + return + + for variant, files in config_files.items(): + for fname in files: + # If there's specific variant set in `load_only`, load only + # that variant, not the others. + if self.load_only is not None and variant != self.load_only: + logger.debug( + "Skipping file '%s' (variant: %s)", fname, variant + ) + continue + + parser = self._load_file(variant, fname) + + # Keeping track of the parsers used + self._parsers[variant].append((fname, parser)) + + def _load_file(self, variant, fname): + # type: (Kind, str) -> RawConfigParser + logger.debug("For variant '%s', will try loading '%s'", variant, fname) + parser = self._construct_parser(fname) + + for section in parser.sections(): + items = parser.items(section) + self._config[variant].update(self._normalized_keys(section, items)) + + return parser + + def _construct_parser(self, fname): + # type: (str) -> RawConfigParser + parser = configparser.RawConfigParser() + # If there is no such file, don't bother reading it but create the + # parser anyway, to hold the data. + # Doing this is useful when modifying and saving files, where we don't + # need to construct a parser. + if os.path.exists(fname): + try: + parser.read(fname) + except UnicodeDecodeError: + # See https://github.com/pypa/pip/issues/4963 + raise ConfigurationFileCouldNotBeLoaded( + reason="contains invalid {} characters".format( + locale.getpreferredencoding(False) + ), + fname=fname, + ) + except configparser.Error as error: + # See https://github.com/pypa/pip/issues/4893 + raise ConfigurationFileCouldNotBeLoaded(error=error) + return parser + + def _load_environment_vars(self): + # type: () -> None + """Loads configuration from environment variables + """ + self._config[kinds.ENV_VAR].update( + self._normalized_keys(":env:", self._get_environ_vars()) + ) + + def _normalized_keys(self, section, items): + # type: (str, Iterable[Tuple[str, Any]]) -> Dict[str, Any] + """Normalizes items to construct a dictionary with normalized keys. + + This routine is where the names become keys and are made the same + regardless of source - configuration files or environment. + """ + normalized = {} + for name, val in items: + key = section + "." + _normalize_name(name) + normalized[key] = val + return normalized + + def _get_environ_vars(self): + # type: () -> Iterable[Tuple[str, str]] + """Returns a generator with all environmental vars with prefix PIP_""" + for key, val in os.environ.items(): + should_be_yielded = ( + key.startswith("PIP_") and + key[4:].lower() not in self._ignore_env_names + ) + if should_be_yielded: + yield key[4:].lower(), val + + # XXX: This is patched in the tests. + def _iter_config_files(self): + # type: () -> Iterable[Tuple[Kind, List[str]]] + """Yields variant and configuration files associated with it. + + This should be treated like items of a dictionary. + """ + # SMELL: Move the conditions out of this function + + # environment variables have the lowest priority + config_file = os.environ.get('PIP_CONFIG_FILE', None) + if config_file is not None: + yield kinds.ENV, [config_file] + else: + yield kinds.ENV, [] + + # at the base we have any global configuration + yield kinds.GLOBAL, list(site_config_files) + + # per-user configuration next + should_load_user_config = not self.isolated and not ( + config_file and os.path.exists(config_file) + ) + if should_load_user_config: + # The legacy config file is overridden by the new config file + yield kinds.USER, [legacy_config_file, new_config_file] + + # finally virtualenv configuration first trumping others + if running_under_virtualenv(): + yield kinds.VENV, [venv_config_file] + + def _get_parser_to_modify(self): + # type: () -> Tuple[str, RawConfigParser] + # Determine which parser to modify + parsers = self._parsers[self.load_only] + if not parsers: + # This should not happen if everything works correctly. + raise ConfigurationError( + "Fatal Internal error [id=2]. Please report as a bug." + ) + + # Use the highest priority parser. + return parsers[-1] + + # XXX: This is patched in the tests. + def _mark_as_modified(self, fname, parser): + # type: (str, RawConfigParser) -> None + file_parser_tuple = (fname, parser) + if file_parser_tuple not in self._modified_parsers: + self._modified_parsers.append(file_parser_tuple) diff --git a/env/lib/python3.7/site-packages/pip/_internal/download.py b/env/lib/python3.7/site-packages/pip/_internal/download.py new file mode 100644 index 0000000..96f3b65 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/download.py @@ -0,0 +1,921 @@ +from __future__ import absolute_import + +import cgi +import email.utils +import getpass +import json +import logging +import mimetypes +import os +import platform +import re +import shutil +import sys + +from pip._vendor import requests, six, urllib3 +from pip._vendor.cachecontrol import CacheControlAdapter +from pip._vendor.cachecontrol.caches import FileCache +from pip._vendor.lockfile import LockError +from pip._vendor.requests.adapters import BaseAdapter, HTTPAdapter +from pip._vendor.requests.auth import AuthBase, HTTPBasicAuth +from pip._vendor.requests.models import CONTENT_CHUNK_SIZE, Response +from pip._vendor.requests.structures import CaseInsensitiveDict +from pip._vendor.requests.utils import get_netrc_auth +# NOTE: XMLRPC Client is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import +from pip._vendor.six.moves import xmlrpc_client # type: ignore +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request +from pip._vendor.six.moves.urllib.parse import unquote as urllib_unquote +from pip._vendor.urllib3.util import IS_PYOPENSSL + +import pip +from pip._internal.exceptions import HashMismatch, InstallationError +from pip._internal.locations import write_delete_marker_file +from pip._internal.models.index import PyPI +from pip._internal.utils.encoding import auto_decode +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.glibc import libc_ver +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, ask_path_exists, backup_dir, call_subprocess, consume, + display_path, format_size, get_installed_version, rmtree, splitext, + unpack_file, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import DownloadProgressProvider +from pip._internal.vcs import vcs + +try: + import ssl # noqa +except ImportError: + ssl = None + +HAS_TLS = (ssl is not None) or IS_PYOPENSSL + +__all__ = ['get_file_content', + 'is_url', 'url_to_path', 'path_to_url', + 'is_archive_file', 'unpack_vcs_link', + 'unpack_file_url', 'is_vcs_url', 'is_file_url', + 'unpack_http_url', 'unpack_url'] + + +logger = logging.getLogger(__name__) + + +def user_agent(): + """ + Return a string representing the user agent. + """ + data = { + "installer": {"name": "pip", "version": pip.__version__}, + "python": platform.python_version(), + "implementation": { + "name": platform.python_implementation(), + }, + } + + if data["implementation"]["name"] == 'CPython': + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'PyPy': + if sys.pypy_version_info.releaselevel == 'final': + pypy_version_info = sys.pypy_version_info[:3] + else: + pypy_version_info = sys.pypy_version_info + data["implementation"]["version"] = ".".join( + [str(x) for x in pypy_version_info] + ) + elif data["implementation"]["name"] == 'Jython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + elif data["implementation"]["name"] == 'IronPython': + # Complete Guess + data["implementation"]["version"] = platform.python_version() + + if sys.platform.startswith("linux"): + from pip._vendor import distro + distro_infos = dict(filter( + lambda x: x[1], + zip(["name", "version", "id"], distro.linux_distribution()), + )) + libc = dict(filter( + lambda x: x[1], + zip(["lib", "version"], libc_ver()), + )) + if libc: + distro_infos["libc"] = libc + if distro_infos: + data["distro"] = distro_infos + + if sys.platform.startswith("darwin") and platform.mac_ver()[0]: + data["distro"] = {"name": "macOS", "version": platform.mac_ver()[0]} + + if platform.system(): + data.setdefault("system", {})["name"] = platform.system() + + if platform.release(): + data.setdefault("system", {})["release"] = platform.release() + + if platform.machine(): + data["cpu"] = platform.machine() + + if HAS_TLS: + data["openssl_version"] = ssl.OPENSSL_VERSION + + setuptools_version = get_installed_version("setuptools") + if setuptools_version is not None: + data["setuptools_version"] = setuptools_version + + return "{data[installer][name]}/{data[installer][version]} {json}".format( + data=data, + json=json.dumps(data, separators=(",", ":"), sort_keys=True), + ) + + +class MultiDomainBasicAuth(AuthBase): + + def __init__(self, prompting=True): + self.prompting = prompting + self.passwords = {} + + def __call__(self, req): + parsed = urllib_parse.urlparse(req.url) + + # Get the netloc without any embedded credentials + netloc = parsed.netloc.rsplit("@", 1)[-1] + + # Set the url of the request to the url without any credentials + req.url = urllib_parse.urlunparse(parsed[:1] + (netloc,) + parsed[2:]) + + # Use any stored credentials that we have for this netloc + username, password = self.passwords.get(netloc, (None, None)) + + # Extract credentials embedded in the url if we have none stored + if username is None: + username, password = self.parse_credentials(parsed.netloc) + + # Get creds from netrc if we still don't have them + if username is None and password is None: + netrc_auth = get_netrc_auth(req.url) + username, password = netrc_auth if netrc_auth else (None, None) + + if username or password: + # Store the username and password + self.passwords[netloc] = (username, password) + + # Send the basic auth with this request + req = HTTPBasicAuth(username or "", password or "")(req) + + # Attach a hook to handle 401 responses + req.register_hook("response", self.handle_401) + + return req + + def handle_401(self, resp, **kwargs): + # We only care about 401 responses, anything else we want to just + # pass through the actual response + if resp.status_code != 401: + return resp + + # We are not able to prompt the user so simply return the response + if not self.prompting: + return resp + + parsed = urllib_parse.urlparse(resp.url) + + # Prompt the user for a new username and password + username = six.moves.input("User for %s: " % parsed.netloc) + password = getpass.getpass("Password: ") + + # Store the new username and password to use for future requests + if username or password: + self.passwords[parsed.netloc] = (username, password) + + # Consume content and release the original connection to allow our new + # request to reuse the same one. + resp.content + resp.raw.release_conn() + + # Add our new username and password to the request + req = HTTPBasicAuth(username or "", password or "")(resp.request) + + # Send our new request + new_resp = resp.connection.send(req, **kwargs) + new_resp.history.append(resp) + + return new_resp + + def parse_credentials(self, netloc): + if "@" in netloc: + userinfo = netloc.rsplit("@", 1)[0] + if ":" in userinfo: + user, pwd = userinfo.split(":", 1) + return (urllib_unquote(user), urllib_unquote(pwd)) + return urllib_unquote(userinfo), None + return None, None + + +class LocalFSAdapter(BaseAdapter): + + def send(self, request, stream=None, timeout=None, verify=None, cert=None, + proxies=None): + pathname = url_to_path(request.url) + + resp = Response() + resp.status_code = 200 + resp.url = request.url + + try: + stats = os.stat(pathname) + except OSError as exc: + resp.status_code = 404 + resp.raw = exc + else: + modified = email.utils.formatdate(stats.st_mtime, usegmt=True) + content_type = mimetypes.guess_type(pathname)[0] or "text/plain" + resp.headers = CaseInsensitiveDict({ + "Content-Type": content_type, + "Content-Length": stats.st_size, + "Last-Modified": modified, + }) + + resp.raw = open(pathname, "rb") + resp.close = resp.raw.close + + return resp + + def close(self): + pass + + +class SafeFileCache(FileCache): + """ + A file based cache which is safe to use even when the target directory may + not be accessible or writable. + """ + + def __init__(self, *args, **kwargs): + super(SafeFileCache, self).__init__(*args, **kwargs) + + # Check to ensure that the directory containing our cache directory + # is owned by the user current executing pip. If it does not exist + # we will check the parent directory until we find one that does exist. + # If it is not owned by the user executing pip then we will disable + # the cache and log a warning. + if not check_path_owner(self.directory): + logger.warning( + "The directory '%s' or its parent directory is not owned by " + "the current user and the cache has been disabled. Please " + "check the permissions and owner of that directory. If " + "executing pip with sudo, you may want sudo's -H flag.", + self.directory, + ) + + # Set our directory to None to disable the Cache + self.directory = None + + def get(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).get(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + def set(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).set(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + def delete(self, *args, **kwargs): + # If we don't have a directory, then the cache should be a no-op. + if self.directory is None: + return + + try: + return super(SafeFileCache, self).delete(*args, **kwargs) + except (LockError, OSError, IOError): + # We intentionally silence this error, if we can't access the cache + # then we can just skip caching and process the request as if + # caching wasn't enabled. + pass + + +class InsecureHTTPAdapter(HTTPAdapter): + + def cert_verify(self, conn, url, verify, cert): + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + + +class PipSession(requests.Session): + + timeout = None + + def __init__(self, *args, **kwargs): + retries = kwargs.pop("retries", 0) + cache = kwargs.pop("cache", None) + insecure_hosts = kwargs.pop("insecure_hosts", []) + + super(PipSession, self).__init__(*args, **kwargs) + + # Attach our User Agent to the request + self.headers["User-Agent"] = user_agent() + + # Attach our Authentication handler to the session + self.auth = MultiDomainBasicAuth() + + # Create our urllib3.Retry instance which will allow us to customize + # how we handle retries. + retries = urllib3.Retry( + # Set the total number of retries that a particular request can + # have. + total=retries, + + # A 503 error from PyPI typically means that the Fastly -> Origin + # connection got interrupted in some way. A 503 error in general + # is typically considered a transient error so we'll go ahead and + # retry it. + # A 500 may indicate transient error in Amazon S3 + # A 520 or 527 - may indicate transient error in CloudFlare + status_forcelist=[500, 503, 520, 527], + + # Add a small amount of back off between failed requests in + # order to prevent hammering the service. + backoff_factor=0.25, + ) + + # We want to _only_ cache responses on securely fetched origins. We do + # this because we can't validate the response of an insecurely fetched + # origin, and we don't want someone to be able to poison the cache and + # require manual eviction from the cache to fix it. + if cache: + secure_adapter = CacheControlAdapter( + cache=SafeFileCache(cache, use_dir_lock=True), + max_retries=retries, + ) + else: + secure_adapter = HTTPAdapter(max_retries=retries) + + # Our Insecure HTTPAdapter disables HTTPS validation. It does not + # support caching (see above) so we'll use it for all http:// URLs as + # well as any https:// host that we've marked as ignoring TLS errors + # for. + insecure_adapter = InsecureHTTPAdapter(max_retries=retries) + + self.mount("https://", secure_adapter) + self.mount("http://", insecure_adapter) + + # Enable file:// urls + self.mount("file://", LocalFSAdapter()) + + # We want to use a non-validating adapter for any requests which are + # deemed insecure. + for host in insecure_hosts: + self.mount("https://{}/".format(host), insecure_adapter) + + def request(self, method, url, *args, **kwargs): + # Allow setting a default timeout on a session + kwargs.setdefault("timeout", self.timeout) + + # Dispatch the actual request + return super(PipSession, self).request(method, url, *args, **kwargs) + + +def get_file_content(url, comes_from=None, session=None): + """Gets the content of a file; it may be a filename, file: URL, or + http: URL. Returns (location, content). Content is unicode. + + :param url: File path or url. + :param comes_from: Origin description of requirements. + :param session: Instance of pip.download.PipSession. + """ + if session is None: + raise TypeError( + "get_file_content() missing 1 required keyword argument: 'session'" + ) + + match = _scheme_re.search(url) + if match: + scheme = match.group(1).lower() + if (scheme == 'file' and comes_from and + comes_from.startswith('http')): + raise InstallationError( + 'Requirements file %s references URL %s, which is local' + % (comes_from, url)) + if scheme == 'file': + path = url.split(':', 1)[1] + path = path.replace('\\', '/') + match = _url_slash_drive_re.match(path) + if match: + path = match.group(1) + ':' + path.split('|', 1)[1] + path = urllib_parse.unquote(path) + if path.startswith('/'): + path = '/' + path.lstrip('/') + url = path + else: + # FIXME: catch some errors + resp = session.get(url) + resp.raise_for_status() + return resp.url, resp.text + try: + with open(url, 'rb') as f: + content = auto_decode(f.read()) + except IOError as exc: + raise InstallationError( + 'Could not open requirements file: %s' % str(exc) + ) + return url, content + + +_scheme_re = re.compile(r'^(http|https|file):', re.I) +_url_slash_drive_re = re.compile(r'/*([a-z])\|', re.I) + + +def is_url(name): + """Returns true if the name looks like a URL""" + if ':' not in name: + return False + scheme = name.split(':', 1)[0].lower() + return scheme in ['http', 'https', 'file', 'ftp'] + vcs.all_schemes + + +def url_to_path(url): + """ + Convert a file: URL to a path. + """ + assert url.startswith('file:'), ( + "You can only turn file: urls into filenames (not %r)" % url) + + _, netloc, path, _, _ = urllib_parse.urlsplit(url) + + # if we have a UNC path, prepend UNC share notation + if netloc: + netloc = '\\\\' + netloc + + path = urllib_request.url2pathname(netloc + path) + return path + + +def path_to_url(path): + """ + Convert a path to a file: URL. The path will be made absolute and have + quoted path parts. + """ + path = os.path.normpath(os.path.abspath(path)) + url = urllib_parse.urljoin('file:', urllib_request.pathname2url(path)) + return url + + +def is_archive_file(name): + """Return True if `name` is a considered as an archive file.""" + ext = splitext(name)[1].lower() + if ext in ARCHIVE_EXTENSIONS: + return True + return False + + +def unpack_vcs_link(link, location): + vcs_backend = _get_used_vcs_backend(link) + vcs_backend.unpack(location) + + +def _get_used_vcs_backend(link): + for backend in vcs.backends: + if link.scheme in backend.schemes: + vcs_backend = backend(link.url) + return vcs_backend + + +def is_vcs_url(link): + return bool(_get_used_vcs_backend(link)) + + +def is_file_url(link): + return link.url.lower().startswith('file:') + + +def is_dir_url(link): + """Return whether a file:// Link points to a directory. + + ``link`` must not have any other scheme but file://. Call is_file_url() + first. + + """ + link_path = url_to_path(link.url_without_fragment) + return os.path.isdir(link_path) + + +def _progress_indicator(iterable, *args, **kwargs): + return iterable + + +def _download_url(resp, link, content_file, hashes, progress_bar): + try: + total_length = int(resp.headers['content-length']) + except (ValueError, KeyError, TypeError): + total_length = 0 + + cached_resp = getattr(resp, "from_cache", False) + if logger.getEffectiveLevel() > logging.INFO: + show_progress = False + elif cached_resp: + show_progress = False + elif total_length > (40 * 1000): + show_progress = True + elif not total_length: + show_progress = True + else: + show_progress = False + + show_url = link.show_url + + def resp_read(chunk_size): + try: + # Special case for urllib3. + for chunk in resp.raw.stream( + chunk_size, + # We use decode_content=False here because we don't + # want urllib3 to mess with the raw bytes we get + # from the server. If we decompress inside of + # urllib3 then we cannot verify the checksum + # because the checksum will be of the compressed + # file. This breakage will only occur if the + # server adds a Content-Encoding header, which + # depends on how the server was configured: + # - Some servers will notice that the file isn't a + # compressible file and will leave the file alone + # and with an empty Content-Encoding + # - Some servers will notice that the file is + # already compressed and will leave the file + # alone and will add a Content-Encoding: gzip + # header + # - Some servers won't notice anything at all and + # will take a file that's already been compressed + # and compress it again and set the + # Content-Encoding: gzip header + # + # By setting this not to decode automatically we + # hope to eliminate problems with the second case. + decode_content=False): + yield chunk + except AttributeError: + # Standard file-like object. + while True: + chunk = resp.raw.read(chunk_size) + if not chunk: + break + yield chunk + + def written_chunks(chunks): + for chunk in chunks: + content_file.write(chunk) + yield chunk + + progress_indicator = _progress_indicator + + if link.netloc == PyPI.netloc: + url = show_url + else: + url = link.url_without_fragment + + if show_progress: # We don't show progress on cached responses + progress_indicator = DownloadProgressProvider(progress_bar, + max=total_length) + if total_length: + logger.info("Downloading %s (%s)", url, format_size(total_length)) + else: + logger.info("Downloading %s", url) + elif cached_resp: + logger.info("Using cached %s", url) + else: + logger.info("Downloading %s", url) + + logger.debug('Downloading from URL %s', link) + + downloaded_chunks = written_chunks( + progress_indicator( + resp_read(CONTENT_CHUNK_SIZE), + CONTENT_CHUNK_SIZE + ) + ) + if hashes: + hashes.check_against_chunks(downloaded_chunks) + else: + consume(downloaded_chunks) + + +def _copy_file(filename, location, link): + copy = True + download_location = os.path.join(location, link.filename) + if os.path.exists(download_location): + response = ask_path_exists( + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)abort' % + display_path(download_location), ('i', 'w', 'b', 'a')) + if response == 'i': + copy = False + elif response == 'w': + logger.warning('Deleting %s', display_path(download_location)) + os.remove(download_location) + elif response == 'b': + dest_file = backup_dir(download_location) + logger.warning( + 'Backing up %s to %s', + display_path(download_location), + display_path(dest_file), + ) + shutil.move(download_location, dest_file) + elif response == 'a': + sys.exit(-1) + if copy: + shutil.copy(filename, download_location) + logger.info('Saved %s', display_path(download_location)) + + +def unpack_http_url(link, location, download_dir=None, + session=None, hashes=None, progress_bar="on"): + if session is None: + raise TypeError( + "unpack_http_url() missing 1 required keyword argument: 'session'" + ) + + with TempDirectory(kind="unpack") as temp_dir: + # If a download dir is specified, is the file already downloaded there? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir(link, + download_dir, + hashes) + + if already_downloaded_path: + from_path = already_downloaded_path + content_type = mimetypes.guess_type(from_path)[0] + else: + # let's download to a tmp dir + from_path, content_type = _download_http_url(link, + session, + temp_dir.path, + hashes, + progress_bar) + + # unpack the archive to the build dir location. even when only + # downloading archives, they have to be unpacked to parse dependencies + unpack_file(from_path, location, content_type, link) + + # a download dir is specified; let's copy the archive there + if download_dir and not already_downloaded_path: + _copy_file(from_path, download_dir, link) + + if not already_downloaded_path: + os.unlink(from_path) + + +def unpack_file_url(link, location, download_dir=None, hashes=None): + """Unpack link into location. + + If download_dir is provided and link points to a file, make a copy + of the link file inside download_dir. + """ + link_path = url_to_path(link.url_without_fragment) + + # If it's a url to a local directory + if is_dir_url(link): + if os.path.isdir(location): + rmtree(location) + shutil.copytree(link_path, location, symlinks=True) + if download_dir: + logger.info('Link is a directory, ignoring download_dir') + return + + # If --require-hashes is off, `hashes` is either empty, the + # link's embedded hash, or MissingHashes; it is required to + # match. If --require-hashes is on, we are satisfied by any + # hash in `hashes` matching: a URL-based or an option-based + # one; no internet-sourced hash will be in `hashes`. + if hashes: + hashes.check_against_path(link_path) + + # If a download dir is specified, is the file already there and valid? + already_downloaded_path = None + if download_dir: + already_downloaded_path = _check_download_dir(link, + download_dir, + hashes) + + if already_downloaded_path: + from_path = already_downloaded_path + else: + from_path = link_path + + content_type = mimetypes.guess_type(from_path)[0] + + # unpack the archive to the build dir location. even when only downloading + # archives, they have to be unpacked to parse dependencies + unpack_file(from_path, location, content_type, link) + + # a download dir is specified and not already downloaded + if download_dir and not already_downloaded_path: + _copy_file(from_path, download_dir, link) + + +def _copy_dist_from_dir(link_path, location): + """Copy distribution files in `link_path` to `location`. + + Invoked when user requests to install a local directory. E.g.: + + pip install . + pip install ~/dev/git-repos/python-prompt-toolkit + + """ + + # Note: This is currently VERY SLOW if you have a lot of data in the + # directory, because it copies everything with `shutil.copytree`. + # What it should really do is build an sdist and install that. + # See https://github.com/pypa/pip/issues/2195 + + if os.path.isdir(location): + rmtree(location) + + # build an sdist + setup_py = 'setup.py' + sdist_args = [sys.executable] + sdist_args.append('-c') + sdist_args.append(SETUPTOOLS_SHIM % setup_py) + sdist_args.append('sdist') + sdist_args += ['--dist-dir', location] + logger.info('Running setup.py sdist for %s', link_path) + + with indent_log(): + call_subprocess(sdist_args, cwd=link_path, show_stdout=False) + + # unpack sdist into `location` + sdist = os.path.join(location, os.listdir(location)[0]) + logger.info('Unpacking sdist %s into %s', sdist, location) + unpack_file(sdist, location, content_type=None, link=None) + + +class PipXmlrpcTransport(xmlrpc_client.Transport): + """Provide a `xmlrpclib.Transport` implementation via a `PipSession` + object. + """ + + def __init__(self, index_url, session, use_datetime=False): + xmlrpc_client.Transport.__init__(self, use_datetime) + index_parts = urllib_parse.urlparse(index_url) + self._scheme = index_parts.scheme + self._session = session + + def request(self, host, handler, request_body, verbose=False): + parts = (self._scheme, host, handler, None, None, None) + url = urllib_parse.urlunparse(parts) + try: + headers = {'Content-Type': 'text/xml'} + response = self._session.post(url, data=request_body, + headers=headers, stream=True) + response.raise_for_status() + self.verbose = verbose + return self.parse_response(response.raw) + except requests.HTTPError as exc: + logger.critical( + "HTTP error %s while getting %s", + exc.response.status_code, url, + ) + raise + + +def unpack_url(link, location, download_dir=None, + only_download=False, session=None, hashes=None, + progress_bar="on"): + """Unpack link. + If link is a VCS link: + if only_download, export into download_dir and ignore location + else unpack into location + for other types of link: + - unpack into location + - if download_dir, copy the file into download_dir + - if only_download, mark location for deletion + + :param hashes: A Hashes object, one of whose embedded hashes must match, + or HashMismatch will be raised. If the Hashes is empty, no matches are + required, and unhashable types of requirements (like VCS ones, which + would ordinarily raise HashUnsupported) are allowed. + """ + # non-editable vcs urls + if is_vcs_url(link): + unpack_vcs_link(link, location) + + # file urls + elif is_file_url(link): + unpack_file_url(link, location, download_dir, hashes=hashes) + + # http urls + else: + if session is None: + session = PipSession() + + unpack_http_url( + link, + location, + download_dir, + session, + hashes=hashes, + progress_bar=progress_bar + ) + if only_download: + write_delete_marker_file(location) + + +def _download_http_url(link, session, temp_dir, hashes, progress_bar): + """Download link url into temp_dir using provided session""" + target_url = link.url.split('#', 1)[0] + try: + resp = session.get( + target_url, + # We use Accept-Encoding: identity here because requests + # defaults to accepting compressed responses. This breaks in + # a variety of ways depending on how the server is configured. + # - Some servers will notice that the file isn't a compressible + # file and will leave the file alone and with an empty + # Content-Encoding + # - Some servers will notice that the file is already + # compressed and will leave the file alone and will add a + # Content-Encoding: gzip header + # - Some servers won't notice anything at all and will take + # a file that's already been compressed and compress it again + # and set the Content-Encoding: gzip header + # By setting this to request only the identity encoding We're + # hoping to eliminate the third case. Hopefully there does not + # exist a server which when given a file will notice it is + # already compressed and that you're not asking for a + # compressed file and will then decompress it before sending + # because if that's the case I don't think it'll ever be + # possible to make this work. + headers={"Accept-Encoding": "identity"}, + stream=True, + ) + resp.raise_for_status() + except requests.HTTPError as exc: + logger.critical( + "HTTP error %s while getting %s", exc.response.status_code, link, + ) + raise + + content_type = resp.headers.get('content-type', '') + filename = link.filename # fallback + # Have a look at the Content-Disposition header for a better guess + content_disposition = resp.headers.get('content-disposition') + if content_disposition: + type, params = cgi.parse_header(content_disposition) + # We use ``or`` here because we don't want to use an "empty" value + # from the filename param. + filename = params.get('filename') or filename + ext = splitext(filename)[1] + if not ext: + ext = mimetypes.guess_extension(content_type) + if ext: + filename += ext + if not ext and link.url != resp.url: + ext = os.path.splitext(resp.url)[1] + if ext: + filename += ext + file_path = os.path.join(temp_dir, filename) + with open(file_path, 'wb') as content_file: + _download_url(resp, link, content_file, hashes, progress_bar) + return file_path, content_type + + +def _check_download_dir(link, download_dir, hashes): + """ Check download_dir for previously downloaded file with correct hash + If a correct file is found return its path else None + """ + download_path = os.path.join(download_dir, link.filename) + if os.path.exists(download_path): + # If already downloaded, does its hash match? + logger.info('File was already downloaded %s', download_path) + if hashes: + try: + hashes.check_against_path(download_path) + except HashMismatch: + logger.warning( + 'Previously-downloaded file %s has bad hash. ' + 'Re-downloading.', + download_path + ) + os.unlink(download_path) + return None + return download_path + return None diff --git a/env/lib/python3.7/site-packages/pip/_internal/exceptions.py b/env/lib/python3.7/site-packages/pip/_internal/exceptions.py new file mode 100644 index 0000000..f1ca6f3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/exceptions.py @@ -0,0 +1,268 @@ +"""Exceptions used throughout package""" +from __future__ import absolute_import + +from itertools import chain, groupby, repeat + +from pip._vendor.six import iteritems + + +class PipError(Exception): + """Base pip exception""" + + +class ConfigurationError(PipError): + """General exception in configuration""" + + +class InstallationError(PipError): + """General exception during installation""" + + +class UninstallationError(PipError): + """General exception during uninstallation""" + + +class DistributionNotFound(InstallationError): + """Raised when a distribution cannot be found to satisfy a requirement""" + + +class RequirementsFileParseError(InstallationError): + """Raised when a general error occurs parsing a requirements file line.""" + + +class BestVersionAlreadyInstalled(PipError): + """Raised when the most up-to-date version of a package is already + installed.""" + + +class BadCommand(PipError): + """Raised when virtualenv or a command is not found""" + + +class CommandError(PipError): + """Raised when there is an error in command-line arguments""" + + +class PreviousBuildDirError(PipError): + """Raised when there's a previous conflicting build directory""" + + +class InvalidWheelFilename(InstallationError): + """Invalid wheel filename.""" + + +class UnsupportedWheel(InstallationError): + """Unsupported wheel.""" + + +class HashErrors(InstallationError): + """Multiple HashError instances rolled into one for reporting""" + + def __init__(self): + self.errors = [] + + def append(self, error): + self.errors.append(error) + + def __str__(self): + lines = [] + self.errors.sort(key=lambda e: e.order) + for cls, errors_of_cls in groupby(self.errors, lambda e: e.__class__): + lines.append(cls.head) + lines.extend(e.body() for e in errors_of_cls) + if lines: + return '\n'.join(lines) + + def __nonzero__(self): + return bool(self.errors) + + def __bool__(self): + return self.__nonzero__() + + +class HashError(InstallationError): + """ + A failure to verify a package against known-good hashes + + :cvar order: An int sorting hash exception classes by difficulty of + recovery (lower being harder), so the user doesn't bother fretting + about unpinned packages when he has deeper issues, like VCS + dependencies, to deal with. Also keeps error reports in a + deterministic order. + :cvar head: A section heading for display above potentially many + exceptions of this kind + :ivar req: The InstallRequirement that triggered this error. This is + pasted on after the exception is instantiated, because it's not + typically available earlier. + + """ + req = None + head = '' + + def body(self): + """Return a summary of me for display under the heading. + + This default implementation simply prints a description of the + triggering requirement. + + :param req: The InstallRequirement that provoked this error, with + populate_link() having already been called + + """ + return ' %s' % self._requirement_name() + + def __str__(self): + return '%s\n%s' % (self.head, self.body()) + + def _requirement_name(self): + """Return a description of the requirement that triggered me. + + This default implementation returns long description of the req, with + line numbers + + """ + return str(self.req) if self.req else 'unknown package' + + +class VcsHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 0 + head = ("Can't verify hashes for these requirements because we don't " + "have a way to hash version control repositories:") + + +class DirectoryUrlHashUnsupported(HashError): + """A hash was provided for a version-control-system-based requirement, but + we don't have a method for hashing those.""" + + order = 1 + head = ("Can't verify hashes for these file:// requirements because they " + "point to directories:") + + +class HashMissing(HashError): + """A hash was needed for a requirement but is absent.""" + + order = 2 + head = ('Hashes are required in --require-hashes mode, but they are ' + 'missing from some requirements. Here is a list of those ' + 'requirements along with the hashes their downloaded archives ' + 'actually had. Add lines like these to your requirements files to ' + 'prevent tampering. (If you did not enable --require-hashes ' + 'manually, note that it turns on automatically when any package ' + 'has a hash.)') + + def __init__(self, gotten_hash): + """ + :param gotten_hash: The hash of the (possibly malicious) archive we + just downloaded + """ + self.gotten_hash = gotten_hash + + def body(self): + # Dodge circular import. + from pip._internal.utils.hashes import FAVORITE_HASH + + package = None + if self.req: + # In the case of URL-based requirements, display the original URL + # seen in the requirements file rather than the package name, + # so the output can be directly copied into the requirements file. + package = (self.req.original_link if self.req.original_link + # In case someone feeds something downright stupid + # to InstallRequirement's constructor. + else getattr(self.req, 'req', None)) + return ' %s --hash=%s:%s' % (package or 'unknown package', + FAVORITE_HASH, + self.gotten_hash) + + +class HashUnpinned(HashError): + """A requirement had a hash specified but was not pinned to a specific + version.""" + + order = 3 + head = ('In --require-hashes mode, all requirements must have their ' + 'versions pinned with ==. These do not:') + + +class HashMismatch(HashError): + """ + Distribution file hash values don't match. + + :ivar package_name: The name of the package that triggered the hash + mismatch. Feel free to write to this after the exception is raise to + improve its error message. + + """ + order = 4 + head = ('THESE PACKAGES DO NOT MATCH THE HASHES FROM THE REQUIREMENTS ' + 'FILE. If you have updated the package versions, please update ' + 'the hashes. Otherwise, examine the package contents carefully; ' + 'someone may have tampered with them.') + + def __init__(self, allowed, gots): + """ + :param allowed: A dict of algorithm names pointing to lists of allowed + hex digests + :param gots: A dict of algorithm names pointing to hashes we + actually got from the files under suspicion + """ + self.allowed = allowed + self.gots = gots + + def body(self): + return ' %s:\n%s' % (self._requirement_name(), + self._hash_comparison()) + + def _hash_comparison(self): + """ + Return a comparison of actual and expected hash values. + + Example:: + + Expected sha256 abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde + or 123451234512345123451234512345123451234512345 + Got bcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdefbcdef + + """ + def hash_then_or(hash_name): + # For now, all the decent hashes have 6-char names, so we can get + # away with hard-coding space literals. + return chain([hash_name], repeat(' or')) + + lines = [] + for hash_name, expecteds in iteritems(self.allowed): + prefix = hash_then_or(hash_name) + lines.extend((' Expected %s %s' % (next(prefix), e)) + for e in expecteds) + lines.append(' Got %s\n' % + self.gots[hash_name].hexdigest()) + prefix = ' or' + return '\n'.join(lines) + + +class UnsupportedPythonVersion(InstallationError): + """Unsupported python version according to Requires-Python package + metadata.""" + + +class ConfigurationFileCouldNotBeLoaded(ConfigurationError): + """When there are errors while loading a configuration file + """ + + def __init__(self, reason="could not be loaded", fname=None, error=None): + super(ConfigurationFileCouldNotBeLoaded, self).__init__(error) + self.reason = reason + self.fname = fname + self.error = error + + def __str__(self): + if self.fname is not None: + message_part = " in {}.".format(self.fname) + else: + assert self.error is not None + message_part = ".\n{}\n".format(self.error.message) + return "Configuration file {}{}".format(self.reason, message_part) diff --git a/env/lib/python3.7/site-packages/pip/_internal/index.py b/env/lib/python3.7/site-packages/pip/_internal/index.py new file mode 100644 index 0000000..8c2f24f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/index.py @@ -0,0 +1,899 @@ +"""Routines related to PyPI, indexes""" +from __future__ import absolute_import + +import cgi +import itertools +import logging +import mimetypes +import os +import posixpath +import re +import sys +from collections import namedtuple + +from pip._vendor import html5lib, requests, six +from pip._vendor.distlib.compat import unescape +from pip._vendor.packaging import specifiers +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.requests.exceptions import SSLError +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request + +from pip._internal.download import HAS_TLS, is_url, path_to_url, url_to_path +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, InvalidWheelFilename, + UnsupportedWheel, +) +from pip._internal.models.candidate import InstallationCandidate +from pip._internal.models.format_control import FormatControl +from pip._internal.models.index import PyPI +from pip._internal.models.link import Link +from pip._internal.pep425tags import get_supported +from pip._internal.utils.compat import ipaddress +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + ARCHIVE_EXTENSIONS, SUPPORTED_EXTENSIONS, normalize_path, + remove_auth_from_url, +) +from pip._internal.utils.packaging import check_requires_python +from pip._internal.wheel import Wheel, wheel_ext + +__all__ = ['FormatControl', 'PackageFinder'] + + +SECURE_ORIGINS = [ + # protocol, hostname, port + # Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC) + ("https", "*", "*"), + ("*", "localhost", "*"), + ("*", "127.0.0.0/8", "*"), + ("*", "::1/128", "*"), + ("file", "*", None), + # ssh is always secure. + ("ssh", "*", "*"), +] + + +logger = logging.getLogger(__name__) + + +def _get_content_type(url, session): + """Get the Content-Type of the given url, using a HEAD request""" + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(url) + if scheme not in {'http', 'https'}: + # FIXME: some warning or something? + # assertion error? + return '' + + resp = session.head(url, allow_redirects=True) + resp.raise_for_status() + + return resp.headers.get("Content-Type", "") + + +def _handle_get_page_fail(link, reason, url, meth=None): + if meth is None: + meth = logger.debug + meth("Could not fetch URL %s: %s - skipping", link, reason) + + +def _get_html_page(link, session=None): + if session is None: + raise TypeError( + "_get_html_page() missing 1 required keyword argument: 'session'" + ) + + url = link.url + url = url.split('#', 1)[0] + + # Check for VCS schemes that do not support lookup as web pages. + from pip._internal.vcs import VcsSupport + for scheme in VcsSupport.schemes: + if url.lower().startswith(scheme) and url[len(scheme)] in '+:': + logger.debug('Cannot look at %s URL %s', scheme, link) + return None + + try: + filename = link.filename + for bad_ext in ARCHIVE_EXTENSIONS: + if filename.endswith(bad_ext): + content_type = _get_content_type(url, session=session) + if content_type.lower().startswith('text/html'): + break + else: + logger.debug( + 'Skipping page %s because of Content-Type: %s', + link, + content_type, + ) + return + + logger.debug('Getting page %s', url) + + # Tack index.html onto file:// URLs that point to directories + (scheme, netloc, path, params, query, fragment) = \ + urllib_parse.urlparse(url) + if (scheme == 'file' and + os.path.isdir(urllib_request.url2pathname(path))): + # add trailing slash if not present so urljoin doesn't trim + # final segment + if not url.endswith('/'): + url += '/' + url = urllib_parse.urljoin(url, 'index.html') + logger.debug(' file: URL is directory, getting %s', url) + + resp = session.get( + url, + headers={ + "Accept": "text/html", + # We don't want to blindly returned cached data for + # /simple/, because authors generally expecting that + # twine upload && pip install will function, but if + # they've done a pip install in the last ~10 minutes + # it won't. Thus by setting this to zero we will not + # blindly use any cached data, however the benefit of + # using max-age=0 instead of no-cache, is that we will + # still support conditional requests, so we will still + # minimize traffic sent in cases where the page hasn't + # changed at all, we will just always incur the round + # trip for the conditional GET now instead of only + # once per 10 minutes. + # For more information, please see pypa/pip#5670. + "Cache-Control": "max-age=0", + }, + ) + resp.raise_for_status() + + # The check for archives above only works if the url ends with + # something that looks like an archive. However that is not a + # requirement of an url. Unless we issue a HEAD request on every + # url we cannot know ahead of time for sure if something is HTML + # or not. However we can check after we've downloaded it. + content_type = resp.headers.get('Content-Type', 'unknown') + if not content_type.lower().startswith("text/html"): + logger.debug( + 'Skipping page %s because of Content-Type: %s', + link, + content_type, + ) + return + + inst = HTMLPage(resp.content, resp.url, resp.headers) + except requests.HTTPError as exc: + _handle_get_page_fail(link, exc, url) + except SSLError as exc: + reason = "There was a problem confirming the ssl certificate: " + reason += str(exc) + _handle_get_page_fail(link, reason, url, meth=logger.info) + except requests.ConnectionError as exc: + _handle_get_page_fail(link, "connection error: %s" % exc, url) + except requests.Timeout: + _handle_get_page_fail(link, "timed out", url) + else: + return inst + + +class PackageFinder(object): + """This finds packages. + + This is meant to match easy_install's technique for looking for + packages, by reading pages and looking for appropriate links. + """ + + def __init__(self, find_links, index_urls, allow_all_prereleases=False, + trusted_hosts=None, process_dependency_links=False, + session=None, format_control=None, platform=None, + versions=None, abi=None, implementation=None, + prefer_binary=False): + """Create a PackageFinder. + + :param format_control: A FormatControl object or None. Used to control + the selection of source packages / binary packages when consulting + the index and links. + :param platform: A string or None. If None, searches for packages + that are supported by the current system. Otherwise, will find + packages that can be built on the platform passed in. These + packages will only be downloaded for distribution: they will + not be built locally. + :param versions: A list of strings or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param abi: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + :param implementation: A string or None. This is passed directly + to pep425tags.py in the get_supported() method. + """ + if session is None: + raise TypeError( + "PackageFinder() missing 1 required keyword argument: " + "'session'" + ) + + # Build find_links. If an argument starts with ~, it may be + # a local file relative to a home directory. So try normalizing + # it and if it exists, use the normalized version. + # This is deliberately conservative - it might be fine just to + # blindly normalize anything starting with a ~... + self.find_links = [] + for link in find_links: + if link.startswith('~'): + new_link = normalize_path(link) + if os.path.exists(new_link): + link = new_link + self.find_links.append(link) + + self.index_urls = index_urls + self.dependency_links = [] + + # These are boring links that have already been logged somehow: + self.logged_links = set() + + self.format_control = format_control or FormatControl(set(), set()) + + # Domains that we won't emit warnings for when not using HTTPS + self.secure_origins = [ + ("*", host, "*") + for host in (trusted_hosts if trusted_hosts else []) + ] + + # Do we want to allow _all_ pre-releases? + self.allow_all_prereleases = allow_all_prereleases + + # Do we process dependency links? + self.process_dependency_links = process_dependency_links + + # The Session we'll use to make requests + self.session = session + + # The valid tags to check potential found wheel candidates against + self.valid_tags = get_supported( + versions=versions, + platform=platform, + abi=abi, + impl=implementation, + ) + + # Do we prefer old, but valid, binary dist over new source dist + self.prefer_binary = prefer_binary + + # If we don't have TLS enabled, then WARN if anyplace we're looking + # relies on TLS. + if not HAS_TLS: + for link in itertools.chain(self.index_urls, self.find_links): + parsed = urllib_parse.urlparse(link) + if parsed.scheme == "https": + logger.warning( + "pip is configured with locations that require " + "TLS/SSL, however the ssl module in Python is not " + "available." + ) + break + + def get_formatted_locations(self): + lines = [] + if self.index_urls and self.index_urls != [PyPI.simple_url]: + lines.append( + "Looking in indexes: {}".format(", ".join( + remove_auth_from_url(url) for url in self.index_urls)) + ) + if self.find_links: + lines.append( + "Looking in links: {}".format(", ".join(self.find_links)) + ) + return "\n".join(lines) + + def add_dependency_links(self, links): + # FIXME: this shouldn't be global list this, it should only + # apply to requirements of the package that specifies the + # dependency_links value + # FIXME: also, we should track comes_from (i.e., use Link) + if self.process_dependency_links: + deprecated( + "Dependency Links processing has been deprecated and will be " + "removed in a future release.", + replacement="PEP 508 URL dependencies", + gone_in="18.2", + issue=4187, + ) + self.dependency_links.extend(links) + + @staticmethod + def _sort_locations(locations, expand_dir=False): + """ + Sort locations into "files" (archives) and "urls", and return + a pair of lists (files,urls) + """ + files = [] + urls = [] + + # puts the url for the given file path into the appropriate list + def sort_path(path): + url = path_to_url(path) + if mimetypes.guess_type(url, strict=False)[0] == 'text/html': + urls.append(url) + else: + files.append(url) + + for url in locations: + + is_local_path = os.path.exists(url) + is_file_url = url.startswith('file:') + + if is_local_path or is_file_url: + if is_local_path: + path = url + else: + path = url_to_path(url) + if os.path.isdir(path): + if expand_dir: + path = os.path.realpath(path) + for item in os.listdir(path): + sort_path(os.path.join(path, item)) + elif is_file_url: + urls.append(url) + elif os.path.isfile(path): + sort_path(path) + else: + logger.warning( + "Url '%s' is ignored: it is neither a file " + "nor a directory.", url, + ) + elif is_url(url): + # Only add url with clear scheme + urls.append(url) + else: + logger.warning( + "Url '%s' is ignored. It is either a non-existing " + "path or lacks a specific scheme.", url, + ) + + return files, urls + + def _candidate_sort_key(self, candidate): + """ + Function used to generate link sort key for link tuples. + The greater the return value, the more preferred it is. + If not finding wheels, then sorted by version only. + If finding wheels, then the sort order is by version, then: + 1. existing installs + 2. wheels ordered via Wheel.support_index_min(self.valid_tags) + 3. source archives + If prefer_binary was set, then all wheels are sorted above sources. + Note: it was considered to embed this logic into the Link + comparison operators, but then different sdist links + with the same version, would have to be considered equal + """ + support_num = len(self.valid_tags) + build_tag = tuple() + binary_preference = 0 + if candidate.location.is_wheel: + # can raise InvalidWheelFilename + wheel = Wheel(candidate.location.filename) + if not wheel.supported(self.valid_tags): + raise UnsupportedWheel( + "%s is not a supported wheel for this platform. It " + "can't be sorted." % wheel.filename + ) + if self.prefer_binary: + binary_preference = 1 + pri = -(wheel.support_index_min(self.valid_tags)) + if wheel.build_tag is not None: + match = re.match(r'^(\d+)(.*)$', wheel.build_tag) + build_tag_groups = match.groups() + build_tag = (int(build_tag_groups[0]), build_tag_groups[1]) + else: # sdist + pri = -(support_num) + return (binary_preference, candidate.version, build_tag, pri) + + def _validate_secure_origin(self, logger, location): + # Determine if this url used a secure transport mechanism + parsed = urllib_parse.urlparse(str(location)) + origin = (parsed.scheme, parsed.hostname, parsed.port) + + # The protocol to use to see if the protocol matches. + # Don't count the repository type as part of the protocol: in + # cases such as "git+ssh", only use "ssh". (I.e., Only verify against + # the last scheme.) + protocol = origin[0].rsplit('+', 1)[-1] + + # Determine if our origin is a secure origin by looking through our + # hardcoded list of secure origins, as well as any additional ones + # configured on this PackageFinder instance. + for secure_origin in (SECURE_ORIGINS + self.secure_origins): + if protocol != secure_origin[0] and secure_origin[0] != "*": + continue + + try: + # We need to do this decode dance to ensure that we have a + # unicode object, even on Python 2.x. + addr = ipaddress.ip_address( + origin[1] + if ( + isinstance(origin[1], six.text_type) or + origin[1] is None + ) + else origin[1].decode("utf8") + ) + network = ipaddress.ip_network( + secure_origin[1] + if isinstance(secure_origin[1], six.text_type) + else secure_origin[1].decode("utf8") + ) + except ValueError: + # We don't have both a valid address or a valid network, so + # we'll check this origin against hostnames. + if (origin[1] and + origin[1].lower() != secure_origin[1].lower() and + secure_origin[1] != "*"): + continue + else: + # We have a valid address and network, so see if the address + # is contained within the network. + if addr not in network: + continue + + # Check to see if the port patches + if (origin[2] != secure_origin[2] and + secure_origin[2] != "*" and + secure_origin[2] is not None): + continue + + # If we've gotten here, then this origin matches the current + # secure origin and we should return True + return True + + # If we've gotten to this point, then the origin isn't secure and we + # will not accept it as a valid location to search. We will however + # log a warning that we are ignoring it. + logger.warning( + "The repository located at %s is not a trusted or secure host and " + "is being ignored. If this repository is available via HTTPS we " + "recommend you use HTTPS instead, otherwise you may silence " + "this warning and allow it anyway with '--trusted-host %s'.", + parsed.hostname, + parsed.hostname, + ) + + return False + + def _get_index_urls_locations(self, project_name): + """Returns the locations found via self.index_urls + + Checks the url_name on the main (first in the list) index and + use this url_name to produce all locations + """ + + def mkurl_pypi_url(url): + loc = posixpath.join( + url, + urllib_parse.quote(canonicalize_name(project_name))) + # For maximum compatibility with easy_install, ensure the path + # ends in a trailing slash. Although this isn't in the spec + # (and PyPI can handle it without the slash) some other index + # implementations might break if they relied on easy_install's + # behavior. + if not loc.endswith('/'): + loc = loc + '/' + return loc + + return [mkurl_pypi_url(url) for url in self.index_urls] + + def find_all_candidates(self, project_name): + """Find all available InstallationCandidate for project_name + + This checks index_urls, find_links and dependency_links. + All versions found are returned as an InstallationCandidate list. + + See _link_package_versions for details on which files are accepted + """ + index_locations = self._get_index_urls_locations(project_name) + index_file_loc, index_url_loc = self._sort_locations(index_locations) + fl_file_loc, fl_url_loc = self._sort_locations( + self.find_links, expand_dir=True, + ) + dep_file_loc, dep_url_loc = self._sort_locations(self.dependency_links) + + file_locations = (Link(url) for url in itertools.chain( + index_file_loc, fl_file_loc, dep_file_loc, + )) + + # We trust every url that the user has given us whether it was given + # via --index-url or --find-links + # We explicitly do not trust links that came from dependency_links + # We want to filter out any thing which does not have a secure origin. + url_locations = [ + link for link in itertools.chain( + (Link(url) for url in index_url_loc), + (Link(url) for url in fl_url_loc), + (Link(url) for url in dep_url_loc), + ) + if self._validate_secure_origin(logger, link) + ] + + logger.debug('%d location(s) to search for versions of %s:', + len(url_locations), project_name) + + for location in url_locations: + logger.debug('* %s', location) + + canonical_name = canonicalize_name(project_name) + formats = self.format_control.get_allowed_formats(canonical_name) + search = Search(project_name, canonical_name, formats) + find_links_versions = self._package_versions( + # We trust every directly linked archive in find_links + (Link(url, '-f') for url in self.find_links), + search + ) + + page_versions = [] + for page in self._get_pages(url_locations, project_name): + logger.debug('Analyzing links from page %s', page.url) + with indent_log(): + page_versions.extend( + self._package_versions(page.iter_links(), search) + ) + + dependency_versions = self._package_versions( + (Link(url) for url in self.dependency_links), search + ) + if dependency_versions: + logger.debug( + 'dependency_links found: %s', + ', '.join([ + version.location.url for version in dependency_versions + ]) + ) + + file_versions = self._package_versions(file_locations, search) + if file_versions: + file_versions.sort(reverse=True) + logger.debug( + 'Local files found: %s', + ', '.join([ + url_to_path(candidate.location.url) + for candidate in file_versions + ]) + ) + + # This is an intentional priority ordering + return ( + file_versions + find_links_versions + page_versions + + dependency_versions + ) + + def find_requirement(self, req, upgrade): + """Try to find a Link matching req + + Expects req, an InstallRequirement and upgrade, a boolean + Returns a Link if found, + Raises DistributionNotFound or BestVersionAlreadyInstalled otherwise + """ + all_candidates = self.find_all_candidates(req.name) + + # Filter out anything which doesn't match our specifier + compatible_versions = set( + req.specifier.filter( + # We turn the version object into a str here because otherwise + # when we're debundled but setuptools isn't, Python will see + # packaging.version.Version and + # pkg_resources._vendor.packaging.version.Version as different + # types. This way we'll use a str as a common data interchange + # format. If we stop using the pkg_resources provided specifier + # and start using our own, we can drop the cast to str(). + [str(c.version) for c in all_candidates], + prereleases=( + self.allow_all_prereleases + if self.allow_all_prereleases else None + ), + ) + ) + applicable_candidates = [ + # Again, converting to str to deal with debundling. + c for c in all_candidates if str(c.version) in compatible_versions + ] + + if applicable_candidates: + best_candidate = max(applicable_candidates, + key=self._candidate_sort_key) + else: + best_candidate = None + + if req.satisfied_by is not None: + installed_version = parse_version(req.satisfied_by.version) + else: + installed_version = None + + if installed_version is None and best_candidate is None: + logger.critical( + 'Could not find a version that satisfies the requirement %s ' + '(from versions: %s)', + req, + ', '.join( + sorted( + {str(c.version) for c in all_candidates}, + key=parse_version, + ) + ) + ) + + raise DistributionNotFound( + 'No matching distribution found for %s' % req + ) + + best_installed = False + if installed_version and ( + best_candidate is None or + best_candidate.version <= installed_version): + best_installed = True + + if not upgrade and installed_version is not None: + if best_installed: + logger.debug( + 'Existing installed version (%s) is most up-to-date and ' + 'satisfies requirement', + installed_version, + ) + else: + logger.debug( + 'Existing installed version (%s) satisfies requirement ' + '(most up-to-date version is %s)', + installed_version, + best_candidate.version, + ) + return None + + if best_installed: + # We have an existing version, and its the best version + logger.debug( + 'Installed version (%s) is most up-to-date (past versions: ' + '%s)', + installed_version, + ', '.join(sorted(compatible_versions, key=parse_version)) or + "none", + ) + raise BestVersionAlreadyInstalled + + logger.debug( + 'Using version %s (newest of versions: %s)', + best_candidate.version, + ', '.join(sorted(compatible_versions, key=parse_version)) + ) + return best_candidate.location + + def _get_pages(self, locations, project_name): + """ + Yields (page, page_url) from the given locations, skipping + locations that have errors. + """ + seen = set() + for location in locations: + if location in seen: + continue + seen.add(location) + + page = self._get_page(location) + if page is None: + continue + + yield page + + _py_version_re = re.compile(r'-py([123]\.?[0-9]?)$') + + def _sort_links(self, links): + """ + Returns elements of links in order, non-egg links first, egg links + second, while eliminating duplicates + """ + eggs, no_eggs = [], [] + seen = set() + for link in links: + if link not in seen: + seen.add(link) + if link.egg_fragment: + eggs.append(link) + else: + no_eggs.append(link) + return no_eggs + eggs + + def _package_versions(self, links, search): + result = [] + for link in self._sort_links(links): + v = self._link_package_versions(link, search) + if v is not None: + result.append(v) + return result + + def _log_skipped_link(self, link, reason): + if link not in self.logged_links: + logger.debug('Skipping link %s; %s', link, reason) + self.logged_links.add(link) + + def _link_package_versions(self, link, search): + """Return an InstallationCandidate or None""" + version = None + if link.egg_fragment: + egg_info = link.egg_fragment + ext = link.ext + else: + egg_info, ext = link.splitext() + if not ext: + self._log_skipped_link(link, 'not a file') + return + if ext not in SUPPORTED_EXTENSIONS: + self._log_skipped_link( + link, 'unsupported archive format: %s' % ext, + ) + return + if "binary" not in search.formats and ext == wheel_ext: + self._log_skipped_link( + link, 'No binaries permitted for %s' % search.supplied, + ) + return + if "macosx10" in link.path and ext == '.zip': + self._log_skipped_link(link, 'macosx10 one') + return + if ext == wheel_ext: + try: + wheel = Wheel(link.filename) + except InvalidWheelFilename: + self._log_skipped_link(link, 'invalid wheel filename') + return + if canonicalize_name(wheel.name) != search.canonical: + self._log_skipped_link( + link, 'wrong project name (not %s)' % search.supplied) + return + + if not wheel.supported(self.valid_tags): + self._log_skipped_link( + link, 'it is not compatible with this Python') + return + + version = wheel.version + + # This should be up by the search.ok_binary check, but see issue 2700. + if "source" not in search.formats and ext != wheel_ext: + self._log_skipped_link( + link, 'No sources permitted for %s' % search.supplied, + ) + return + + if not version: + version = egg_info_matches(egg_info, search.supplied, link) + if version is None: + self._log_skipped_link( + link, 'Missing project version for %s' % search.supplied) + return + + match = self._py_version_re.search(version) + if match: + version = version[:match.start()] + py_version = match.group(1) + if py_version != sys.version[:3]: + self._log_skipped_link( + link, 'Python version is incorrect') + return + try: + support_this_python = check_requires_python(link.requires_python) + except specifiers.InvalidSpecifier: + logger.debug("Package %s has an invalid Requires-Python entry: %s", + link.filename, link.requires_python) + support_this_python = True + + if not support_this_python: + logger.debug("The package %s is incompatible with the python" + "version in use. Acceptable python versions are:%s", + link, link.requires_python) + return + logger.debug('Found link %s, version: %s', link, version) + + return InstallationCandidate(search.supplied, version, link) + + def _get_page(self, link): + return _get_html_page(link, session=self.session) + + +def egg_info_matches( + egg_info, search_name, link, + _egg_info_re=re.compile(r'([a-z0-9_.]+)-([a-z0-9_.!+-]+)', re.I)): + """Pull the version part out of a string. + + :param egg_info: The string to parse. E.g. foo-2.1 + :param search_name: The name of the package this belongs to. None to + infer the name. Note that this cannot unambiguously parse strings + like foo-2-2 which might be foo, 2-2 or foo-2, 2. + :param link: The link the string came from, for logging on failure. + """ + match = _egg_info_re.search(egg_info) + if not match: + logger.debug('Could not parse version from link: %s', link) + return None + if search_name is None: + full_match = match.group(0) + return full_match.split('-', 1)[-1] + name = match.group(0).lower() + # To match the "safe" name that pkg_resources creates: + name = name.replace('_', '-') + # project name and version must be separated by a dash + look_for = search_name.lower() + "-" + if name.startswith(look_for): + return match.group(0)[len(look_for):] + else: + return None + + +def _determine_base_url(document, page_url): + """Determine the HTML document's base URL. + + This looks for a ```` tag in the HTML document. If present, its href + attribute denotes the base URL of anchor tags in the document. If there is + no such tag (or if it does not have a valid href attribute), the HTML + file's URL is used as the base URL. + + :param document: An HTML document representation. The current + implementation expects the result of ``html5lib.parse()``. + :param page_url: The URL of the HTML document. + """ + for base in document.findall(".//base"): + href = base.get("href") + if href is not None: + return href + return page_url + + +def _get_encoding_from_headers(headers): + """Determine if we have any encoding information in our headers. + """ + if headers and "Content-Type" in headers: + content_type, params = cgi.parse_header(headers["Content-Type"]) + if "charset" in params: + return params['charset'] + return None + + +_CLEAN_LINK_RE = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + +def _clean_link(url): + """Makes sure a link is fully encoded. That is, if a ' ' shows up in + the link, it will be rewritten to %20 (while not over-quoting + % or other characters).""" + return _CLEAN_LINK_RE.sub(lambda match: '%%%2x' % ord(match.group(0)), url) + + +class HTMLPage(object): + """Represents one page, along with its URL""" + + def __init__(self, content, url, headers=None): + self.content = content + self.url = url + self.headers = headers + + def __str__(self): + return self.url + + def iter_links(self): + """Yields all links in the page""" + document = html5lib.parse( + self.content, + transport_encoding=_get_encoding_from_headers(self.headers), + namespaceHTMLElements=False, + ) + base_url = _determine_base_url(document, self.url) + for anchor in document.findall(".//a"): + if anchor.get("href"): + href = anchor.get("href") + url = _clean_link(urllib_parse.urljoin(base_url, href)) + pyrequire = anchor.get('data-requires-python') + pyrequire = unescape(pyrequire) if pyrequire else None + yield Link(url, self.url, requires_python=pyrequire) + + +Search = namedtuple('Search', 'supplied canonical formats') +"""Capture key aspects of a search. + +:attribute supplied: The user supplied package. +:attribute canonical: The canonical package name. +:attribute formats: The formats allowed for this package. Should be a set + with 'binary' or 'source' or both in it. +""" diff --git a/env/lib/python3.7/site-packages/pip/_internal/locations.py b/env/lib/python3.7/site-packages/pip/_internal/locations.py new file mode 100644 index 0000000..183aaa3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/locations.py @@ -0,0 +1,194 @@ +"""Locations where we look for configs, install stuff, etc""" +from __future__ import absolute_import + +import os +import os.path +import platform +import site +import sys +import sysconfig +from distutils import sysconfig as distutils_sysconfig +from distutils.command.install import SCHEME_KEYS # type: ignore + +from pip._internal.utils import appdirs +from pip._internal.utils.compat import WINDOWS, expanduser + +# Application Directories +USER_CACHE_DIR = appdirs.user_cache_dir("pip") + + +DELETE_MARKER_MESSAGE = '''\ +This file is placed here by pip to indicate the source was put +here by pip. + +Once this package is successfully installed this source code will be +deleted (unless you remove this file). +''' +PIP_DELETE_MARKER_FILENAME = 'pip-delete-this-directory.txt' + + +def write_delete_marker_file(directory): + """ + Write the pip delete marker file into this directory. + """ + filepath = os.path.join(directory, PIP_DELETE_MARKER_FILENAME) + with open(filepath, 'w') as marker_fp: + marker_fp.write(DELETE_MARKER_MESSAGE) + + +def running_under_virtualenv(): + """ + Return True if we're running inside a virtualenv, False otherwise. + + """ + if hasattr(sys, 'real_prefix'): + return True + elif sys.prefix != getattr(sys, "base_prefix", sys.prefix): + return True + + return False + + +def virtualenv_no_global(): + """ + Return True if in a venv and no system site packages. + """ + # this mirrors the logic in virtualenv.py for locating the + # no-global-site-packages.txt file + site_mod_dir = os.path.dirname(os.path.abspath(site.__file__)) + no_global_file = os.path.join(site_mod_dir, 'no-global-site-packages.txt') + if running_under_virtualenv() and os.path.isfile(no_global_file): + return True + + +if running_under_virtualenv(): + src_prefix = os.path.join(sys.prefix, 'src') +else: + # FIXME: keep src in cwd for now (it is not a temporary folder) + try: + src_prefix = os.path.join(os.getcwd(), 'src') + except OSError: + # In case the current working directory has been renamed or deleted + sys.exit( + "The folder you are executing pip from can no longer be found." + ) + +# under macOS + virtualenv sys.prefix is not properly resolved +# it is something like /path/to/python/bin/.. +# Note: using realpath due to tmp dirs on OSX being symlinks +src_prefix = os.path.abspath(src_prefix) + +# FIXME doesn't account for venv linked to global site-packages + +site_packages = sysconfig.get_path("purelib") +# This is because of a bug in PyPy's sysconfig module, see +# https://bitbucket.org/pypy/pypy/issues/2506/sysconfig-returns-incorrect-paths +# for more information. +if platform.python_implementation().lower() == "pypy": + site_packages = distutils_sysconfig.get_python_lib() +try: + # Use getusersitepackages if this is present, as it ensures that the + # value is initialised properly. + user_site = site.getusersitepackages() +except AttributeError: + user_site = site.USER_SITE +user_dir = expanduser('~') +if WINDOWS: + bin_py = os.path.join(sys.prefix, 'Scripts') + bin_user = os.path.join(user_site, 'Scripts') + # buildout uses 'bin' on Windows too? + if not os.path.exists(bin_py): + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.ini' + + legacy_storage_dir = os.path.join(user_dir, 'pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) +else: + bin_py = os.path.join(sys.prefix, 'bin') + bin_user = os.path.join(user_site, 'bin') + + config_basename = 'pip.conf' + + legacy_storage_dir = os.path.join(user_dir, '.pip') + legacy_config_file = os.path.join( + legacy_storage_dir, + config_basename, + ) + # Forcing to use /usr/local/bin for standard macOS framework installs + # Also log to ~/Library/Logs/ for use with the Console.app log viewer + if sys.platform[:6] == 'darwin' and sys.prefix[:16] == '/System/Library/': + bin_py = '/usr/local/bin' + +site_config_files = [ + os.path.join(path, config_basename) + for path in appdirs.site_config_dirs('pip') +] + +venv_config_file = os.path.join(sys.prefix, config_basename) +new_config_file = os.path.join(appdirs.user_config_dir("pip"), config_basename) + + +def distutils_scheme(dist_name, user=False, home=None, root=None, + isolated=False, prefix=None): + """ + Return a distutils install scheme + """ + from distutils.dist import Distribution + + scheme = {} + + if isolated: + extra_dist_args = {"script_args": ["--no-user-cfg"]} + else: + extra_dist_args = {} + dist_args = {'name': dist_name} + dist_args.update(extra_dist_args) + + d = Distribution(dist_args) + d.parse_config_files() + i = d.get_command_obj('install', create=True) + # NOTE: setting user or home has the side-effect of creating the home dir + # or user base for installations during finalize_options() + # ideally, we'd prefer a scheme class that has no side-effects. + assert not (user and prefix), "user={} prefix={}".format(user, prefix) + i.user = user or i.user + if user: + i.prefix = "" + i.prefix = prefix or i.prefix + i.home = home or i.home + i.root = root or i.root + i.finalize_options() + for key in SCHEME_KEYS: + scheme[key] = getattr(i, 'install_' + key) + + # install_lib specified in setup.cfg should install *everything* + # into there (i.e. it takes precedence over both purelib and + # platlib). Note, i.install_lib is *always* set after + # finalize_options(); we only want to override here if the user + # has explicitly requested it hence going back to the config + if 'install_lib' in d.get_option_dict('install'): + scheme.update(dict(purelib=i.install_lib, platlib=i.install_lib)) + + if running_under_virtualenv(): + scheme['headers'] = os.path.join( + sys.prefix, + 'include', + 'site', + 'python' + sys.version[:3], + dist_name, + ) + + if root is not None: + path_no_drive = os.path.splitdrive( + os.path.abspath(scheme["headers"]))[1] + scheme["headers"] = os.path.join( + root, + path_no_drive[1:], + ) + + return scheme diff --git a/env/lib/python3.7/site-packages/pip/_internal/models/__init__.py b/env/lib/python3.7/site-packages/pip/_internal/models/__init__.py new file mode 100644 index 0000000..7855226 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/models/__init__.py @@ -0,0 +1,2 @@ +"""A package that contains models that represent entities. +""" diff --git a/env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4d9d47bd1995678b9dd754c91fd9f382acb4a62 GIT binary patch literal 217 zcmXwyy$*sf6om_mgoJnKWWoSl92^Y(Jb;TEF=-mwV6~J=uQB>E&b|_>Z{g$x;z_=9 z?>)o0yCjJTs(j6lYn-3q_$$C=gZKzdl9I^aK+^EJ+)^j1i>MWalK@(^7KFB*Hmy{~ zPhqEAr@XR25e-`TJl>~4KjU1s73Xi#g;+b^)=v literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/candidate.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/candidate.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20820e1334e8b305e7cbda05bf357bcaa9cc00a6 GIT binary patch literal 1052 zcmaJ=&2H2%5VjpByIt)Tgvtd86na37RI(Q?psJwufDobwxJ5{o6?>~}y-8|&ftKae zN!zV6>;DdI5Cs#wn$WrG?OpRcz(W_?2SeP0+M}s@b)JobAis zqNpJ=nlXx)nPA2#gX;+mfYS*XG{B#C~(4U*6%tfh4tz{X2`vL~HZ`_&B2 z^sC}SQRe8il3)qk7645$sz}BZ&4LRup^B;Cyq|H!Rd`Oa@PcrXMVP6%{i1YU8Y6vC zmHV<(g_2&MK7OrhtDP>ri)CC_9#A1oyqT|DHseWU zP=WO|(IpY$JNf-|>}U13F6xKNo*(A#56h`PeuRguLO`!=Db09RDQ(>NlB~2ou|o)o zfgJ)uBRZfF8_;!ndhgm9q^kmRiWfle8G`PEx(zUjenrNB&5pHiLCe)?vU6?3t&jKZ zr|tO4CcDsl1aq88|4;jN1R3m&OLG$tvSwj3guwI;i6oT&r-RNJrUVyDInzQk10jH( zxj{S>;&?92@=H$$RppQY8M3#)G^6DRa%~KJxU43jb{(CtsCJ$a0Eec}I2#Vyvx6kc z?!s_V*ojhAHmzlTBoASE(&cVg_-TplgURl+j;jf#b6*&jc5}42!fnK>0y@-jveWgm Mi}PtY8M0yU2X>SU*8l(j literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/format_control.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c1d76fe958114fcf66260aba5949ec08d3035591 GIT binary patch literal 2387 zcmai0&u<$=6rR~#uN}upn>G|7P+3r+7^RMcdI~>OXjKFUg9K753m9#8Cho`psV62(hdGqGIH}8G#jlWu2YBIFmpCA78M}x7y zX>ry9d^|um5eCU5&)AUnIA>oo=}G^XNnd$Ke$SV|53F5#0WQ|&Pq$$FmTkg_5n>6rHdS(D*0>(yjkHZX^BK{hehRYNYy)-gNc zy#=`>mqBaFYw|kgMd`tY8|BjDLJwp6u*j`0viLX7*q2dXWh14dB#VuSHVb@J+gX}# z(HaLp*Tpc}?WajU8pX+WyroPOYZaxrv2m6u*=a^--)u&4w3(_*Mkx-(nb}{9Qj0}? z*G5L!4zV~wbZ~bACpYdMIu6q>#yACKPyxCVH&>jPVCubBMMYy zoH9-pUA{78E!s^jY|i(it@OFd=VuBs2KU+}M~+8i@VRN{>Ycc5LXoFNvxoi=-K=4l z0t4F(y=>VL%e^U|GQp>wqrE?)d7y!U81ru1FMV9NT*wRYEX`xRUoMg*vjw&Tqq0q1 zgJ>OM_={;^o4tIrZil1wQ98Oe3+laOcPk&*o%=*|U8K2HI*+sUVIfs!)+>038Dcu4 z{jwpzlv*JcA=6NjFuuwsw=N*BbHbd7PgXB0Cx#2E$?4AFmFg3yKIN^ML%CkU_DriLjw^KL zN{Ac(rIQ#EB%EtBQvjUKTlkP1I@y2^5Xym%9-R8PxYwOD4-P*%K#m+7w%fHbtUO*W zKo}*g5abs^rx52MZFA?L%VvU8tC1Gs4QMnJbjAZ7qQ4%WigAugGInn8?^sOP35-7F zhyLDU=}rCZP=7!5PWUO~aNd0Oq<4y%IQ1p^iBBu(zsY{}K4&t(sk&|vZg*Nw*xts} zf5d+N{9GT8QXekNz&9pLo^R&eJETzi?Kq`;xCsYObohAP-N% z4b)n-(GJU+8D*(0Ye}YJUHY+d7mjc)I`w&lAf#Ib z9~e*3``?UO0dAbpRdr33`IKy~${y0{-HSH9#*GB;wp)4yhsvf9sH$UtNt7)ic7UfU zugf|rUy&er>EDPeMtYgPsNR$ZIof#Y6_)!>7tcD zMKAgZd^pN6LpfnM4=&LF`x%o6*Ss=1 zEz;|))bFK5#nMLAr-E^v@jVtK>o@{UaMGIHzfD?iHEl`UIS}`C zFYYa%J6V{ ixSz)#A+_^vrn^De#xIv(y~1ul_diL3jctOvgy28lrzqk8 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/models/__pycache__/link.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5d9011e8138a7ad7d5218fee8cb9becbe21e232a GIT binary patch literal 4719 zcmb_f-FMT-71v0ztvHT>0D(YuSA|W8x5R-!wk>7ZE$q@S$e}=cdc07fc*e03Su!&+ zAwEtY7S7qH{TJG#Z~d3_+9%%kiKqVVD3&pV)8(8h(e>5Low?t4?%bT3DjRqj|6F+V zk0XZhANm+RHjuCIswV*4;4Cy6*)MA_e4C-!u^Kj`F)J)|ijAVi?Xc8w8ji*b;Y6q0 zC~LeJPIfAd3NwCd@Dg`k8r%`(7gl46vj;|P;uW|UYc-Y@y1rBb$Yj?~+FlZSJsIND zQQa^|#PbCBi9d>+o4ykKR@?!(xEnkVB8*RLw}l8j5H)GL;X|s>qkaSs28rJ=Icr#a z@q44ixW(<46Ahaec=4stC}iR_ilW3Pc=@IAf;AlAlf0tw3E)$_s_`=LBmAhwC;2fx zjrA3b9p@+X*c9-Sd`9C{ab)i(Kef*q$1r-D&+5@>J$eSC$1!@A&*{+urDm z+e47-GdZ2G0eiuA0SAU>4opC6V9AAn6`7pA?4*zs2gVC?votU^&7{b!A4~*^2}y1L zU(7HxGhzteU&}uZ2Hd#iCT-zDk+>(D!tKUElnCx7vAfuoqBSHS#cKKLX510VBR$7= z3?h~I5w^j$zk7K1&OOo}fh2|IqOG&-E4LN*B7V`0rK=JdL>u*dXDOcc0!ZU^canA- zjc@-z6T8hgO8g+gI=$S_m?kB$63PcD#sw-7-x8v`)>taOhuJ6E&w9(Q~tffq>v3>jmVy*WQK|7K$N%Jfc5`W{O3w^mz zP0+xu2TWHlT^Z@zHy=G(tC^{_C3ey(7cH%u*9?87YED{)O=Y6CgQP7fL{bZ$Ov@u5 zq(_G09at?bs9sk{St4r3^RQpyc{Mw=l?YpM62r1WU@T%(o2xLP}bAUCO*=zli?&8oO2mZP?uWG5$ug)uXQD-N<@o#GbWTqgaq!z-lW=fJiHDy;$ z1IfT~8Y+1n2w+KkC^Db{iT6);J!X7>jmiLpnfGxyn}!Y z;zXp?-zX(y62#FrQpU1Y$Q;7Fv>1sbjGL*gx3FpXJH{Hy@;Q`O`b;)w*a=o<(?g>T zDRQHck0`UW(a8BDqj5Hy`AQN|&5~#EBhM0`hhek{DT<3 z`T)lA95~*5hihiFF|K)x%z&EI#Y_IS_8F1o;2bT%HFJ9brSY zC$!q+t}*sSkZ5aX>=TwT-?OuTq-+LzISVqlpQ?kLBk&Oc;vqii^^mV>f+VC)(D$j_n2FJvr;`{A5Y3+>TeOb@knw6@eUk<;iQMX3yHCZ7Qrg;t)A z_HF^A7S4EcU=3_;v$zU24UwS}b5!?RagNwD7bim2PyGl}KS|5c?~@6D~>)J-l! zuIvoH1nfX9d6`DvQtITPd-$Ln*Y1qg?oi_X%A#ufmj?hVD_7~~$}jcL%IfFzwR(AF z(BZ2!DDN+|E-n4)@y|cNr*dxOPks6#XBSB+8*NA1S8e$61N60NNjR=vnf0?8LUTVo z+76Q}i#EARmj3BZn9zFAQKR0Gtf~#46XfDi_U9$;Q+y1wo`Rp7`zE($k?|ajO@`}) zDByfOFG)&$*t}+6BL7EaPj@JVEcM^hD5!S4O?SLLNlF=MmvE$Qxx4&{K)m2NzV^mG|52=xVtFo8+F%r(KfI9 zVOXPkM$pQ)3zG5W=lpdvAXs>g_Qs_m47LQ8)1gI6efKZ79=K>bd}>KXZF|-cu+)0i zRJR`@MhI$ukl0Sk}>c);sYtq3TEx^r(_TQuj9L%(&}#yd8zH&$Ij1>G8>45`?PW z32>#O6SHyV&}n@!lGJ9U$HxhD(&)_6@{Wv".format( + self.project, self.version, self.location, + ) diff --git a/env/lib/python3.7/site-packages/pip/_internal/models/format_control.py b/env/lib/python3.7/site-packages/pip/_internal/models/format_control.py new file mode 100644 index 0000000..2748856 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/models/format_control.py @@ -0,0 +1,62 @@ +from pip._vendor.packaging.utils import canonicalize_name + + +class FormatControl(object): + """A helper class for controlling formats from which packages are installed. + If a field is falsy, it isn't set. If it is {':all:'}, it should match all + packages except those listed in the other field. Only one field can be set + to {':all:'} at a time. The rest of the time exact package name matches + are listed, with any given package only showing up in one field at a time. + """ + def __init__(self, no_binary=None, only_binary=None): + self.no_binary = set() if no_binary is None else no_binary + self.only_binary = set() if only_binary is None else only_binary + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + def __ne__(self, other): + return not self.__eq__(other) + + def __repr__(self): + return "{}({}, {})".format( + self.__class__.__name__, + self.no_binary, + self.only_binary + ) + + @staticmethod + def handle_mutual_excludes(value, target, other): + new = value.split(',') + while ':all:' in new: + other.clear() + target.clear() + target.add(':all:') + del new[:new.index(':all:') + 1] + # Without a none, we want to discard everything as :all: covers it + if ':none:' not in new: + return + for name in new: + if name == ':none:': + target.clear() + continue + name = canonicalize_name(name) + other.discard(name) + target.add(name) + + def get_allowed_formats(self, canonical_name): + result = {"binary", "source"} + if canonical_name in self.only_binary: + result.discard('source') + elif canonical_name in self.no_binary: + result.discard('binary') + elif ':all:' in self.only_binary: + result.discard('source') + elif ':all:' in self.no_binary: + result.discard('binary') + return frozenset(result) + + def disallow_binaries(self): + self.handle_mutual_excludes( + ':all:', self.no_binary, self.only_binary, + ) diff --git a/env/lib/python3.7/site-packages/pip/_internal/models/index.py b/env/lib/python3.7/site-packages/pip/_internal/models/index.py new file mode 100644 index 0000000..870a315 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/models/index.py @@ -0,0 +1,29 @@ +from pip._vendor.six.moves.urllib import parse as urllib_parse + + +class PackageIndex(object): + """Represents a Package Index and provides easier access to endpoints + """ + + def __init__(self, url, file_storage_domain): + super(PackageIndex, self).__init__() + self.url = url + self.netloc = urllib_parse.urlsplit(url).netloc + self.simple_url = self._url_for_path('simple') + self.pypi_url = self._url_for_path('pypi') + + # This is part of a temporary hack used to block installs of PyPI + # packages which depend on external urls only necessary until PyPI can + # block such packages themselves + self.file_storage_domain = file_storage_domain + + def _url_for_path(self, path): + return urllib_parse.urljoin(self.url, path) + + +PyPI = PackageIndex( + 'https://pypi.org/', file_storage_domain='files.pythonhosted.org' +) +TestPyPI = PackageIndex( + 'https://test.pypi.org/', file_storage_domain='test-files.pythonhosted.org' +) diff --git a/env/lib/python3.7/site-packages/pip/_internal/models/link.py b/env/lib/python3.7/site-packages/pip/_internal/models/link.py new file mode 100644 index 0000000..5decb7c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/models/link.py @@ -0,0 +1,141 @@ +import posixpath +import re + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import splitext +from pip._internal.utils.models import KeyBasedCompareMixin +from pip._internal.wheel import wheel_ext + + +class Link(KeyBasedCompareMixin): + """Represents a parsed link from a Package Index's simple URL + """ + + def __init__(self, url, comes_from=None, requires_python=None): + """ + url: + url of the resource pointed to (href of the link) + comes_from: + instance of HTMLPage where the link was found, or string. + requires_python: + String containing the `Requires-Python` metadata field, specified + in PEP 345. This may be specified by a data-requires-python + attribute in the HTML link tag, as described in PEP 503. + """ + + # url can be a UNC windows share + if url.startswith('\\\\'): + url = path_to_url(url) + + self.url = url + self.comes_from = comes_from + self.requires_python = requires_python if requires_python else None + + super(Link, self).__init__( + key=(self.url), + defining_class=Link + ) + + def __str__(self): + if self.requires_python: + rp = ' (requires-python:%s)' % self.requires_python + else: + rp = '' + if self.comes_from: + return '%s (from %s)%s' % (self.url, self.comes_from, rp) + else: + return str(self.url) + + def __repr__(self): + return '' % self + + @property + def filename(self): + _, netloc, path, _, _ = urllib_parse.urlsplit(self.url) + name = posixpath.basename(path.rstrip('/')) or netloc + name = urllib_parse.unquote(name) + assert name, ('URL %r produced no filename' % self.url) + return name + + @property + def scheme(self): + return urllib_parse.urlsplit(self.url)[0] + + @property + def netloc(self): + return urllib_parse.urlsplit(self.url)[1] + + @property + def path(self): + return urllib_parse.unquote(urllib_parse.urlsplit(self.url)[2]) + + def splitext(self): + return splitext(posixpath.basename(self.path.rstrip('/'))) + + @property + def ext(self): + return self.splitext()[1] + + @property + def url_without_fragment(self): + scheme, netloc, path, query, fragment = urllib_parse.urlsplit(self.url) + return urllib_parse.urlunsplit((scheme, netloc, path, query, None)) + + _egg_fragment_re = re.compile(r'[#&]egg=([^&]*)') + + @property + def egg_fragment(self): + match = self._egg_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _subdirectory_fragment_re = re.compile(r'[#&]subdirectory=([^&]*)') + + @property + def subdirectory_fragment(self): + match = self._subdirectory_fragment_re.search(self.url) + if not match: + return None + return match.group(1) + + _hash_re = re.compile( + r'(sha1|sha224|sha384|sha256|sha512|md5)=([a-f0-9]+)' + ) + + @property + def hash(self): + match = self._hash_re.search(self.url) + if match: + return match.group(2) + return None + + @property + def hash_name(self): + match = self._hash_re.search(self.url) + if match: + return match.group(1) + return None + + @property + def show_url(self): + return posixpath.basename(self.url.split('#', 1)[0].split('?', 1)[0]) + + @property + def is_wheel(self): + return self.ext == wheel_ext + + @property + def is_artifact(self): + """ + Determines if this points to an actual artifact (e.g. a tarball) or if + it points to an "abstract" thing like a path or a VCS location. + """ + from pip._internal.vcs import vcs + + if self.scheme in vcs.all_schemes: + return False + + return True diff --git a/env/lib/python3.7/site-packages/pip/_internal/operations/__init__.py b/env/lib/python3.7/site-packages/pip/_internal/operations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12f37c6bb4cf86e003d2ab403f8c2c0a437012bc GIT binary patch literal 153 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd2A!{dk~gW=VX!UP0w8 T4x8Nkl+v73JCNDMK+FID^6({p literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/check.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e58c9b0d9e10e5e67750c7c3b4b6a788b78cdafa GIT binary patch literal 3330 zcmZ`+OK;rB5oR|z91dqRdfJx!T3QJb53(L_lFj2FILXR!EbOi#*qbbt*nps>dn9Ve z;i#LkErB}8z$O8lYc2sIAM+>nm_v|Xz-vwm>@UbEU-eM0WWzxhyQ`n9`s%Bm4`yb3 z3s3mh?|i3l zJ`VC>Aml`jg&YqOsi{4Q2cvjLYX2)TV~msE+`kW zcqF5ETNf%G6p=`D0qw0FSwzWL7jc?OVYDjQKA?>?P5St=tx6lLnP=O z{tG`w`x7rAwAZZt)laRG!Sc@0 zPuKG?b}w`g2Pw{G%#ZiERf1$(GM^x<=F)o z?qVO^g|HeP^SQ(3n9r7(x(&_dfKvyaHcAs^9Yuc)Q8K|so|+?XyoM(V>%@ZnN!qXe zURv6($y5AEq# z_`jk4S+vVW(Gl(&Uh>jevr1R3Lg&^xn{);%ytIcLcxfK}d7Ug8Btt-=wq*df1&Iy@ zFgSdN=Ng6YWwU*-DASvp;U|V7(V8}#KQ0&GM?Z_I#ZvDTWD4@ zS5EpPnrb}Gj_w->UB*p+&46A%>R*}k37DciQBp~qN=u>>dn6BgGX!Z+gAFqoHb;Gn^im|R-ovT6$ELNyqTP@S4+@Y14 zS)z3^-l^IcJ4~@5H9BW-C-YUEdQ1d<)z#dkfm4kQ_A%DMxv-j?9^}7GHUB>bc|hiR zAHr&S%(GqQa-Wm*80Uy0+hY!5$%pJRZu^L=B@lXOaXhu#>!yV*u}*{k4JS`JoAIgcf2d?Lm~*?-9K~9oxJNIv}F; zayKa?5$z@Ld24B$ZHxF(N(-P^N4=?$>qA6muF@CSJDUSQ699USA*yO6(n)rZ64lj{ z4HHKBu$qr*4!k%6*}i92evzMzHjt_ojBTRr^F@FK`Z{d(eY}*3nH&G-jGtqK?m$>B zfMEMJXPl{@pncAwnM5)V#=DY9vi+~L)Jo`I$?X9T>FNBKfy(Y85>0dHMew5 zn{_^GfVcRmS2hf@b---IRQAya>v=XgD8MA-{W`;5zD?B5zU1f&Gt{I4kGaDHR}s}~ zse3r5B0^CsBnYDF9THa)oBB3%NP|QoQ){;BEfBXJRU?Wsv&J`2k@_L#6)4kObVPpg7EiXV$**g z26Rf38n&$c`=46--P(+7v)7n@IOXi=H=9G7k8G$Pla^R0oUf@yNAYlooDal&k2?D# z2s;;mSHu-xplDju;vV75Ly}PxY}G9!{(gkW z6uIh8H%GAcahFT=^!gE)5ogze{>8PR51O9Dplb4FwS0A$S)dOB9GII-b@Q9Li^B;v zQ-tI2&eZ{MZXe}5py;+xx%C8M2h}1$e-RYjCKQE=njt~A4>e2TK1AqmO|OZ#bA`>1 zr~Dqa*Dv@zY}Z=4dxo=@dW@pIPPzJ-)CXxX1u5NS4B?t^G;lJ;zT_a|Dihz{T9%80 mR6ZheYdVp`JM?4tfxkQKeuL^=aQqxJUE7=WA9~B);(q{@wqHR2 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/freeze.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bd9da23a32e39f78aaadfe3279715be56fddcce GIT binary patch literal 6285 zcma)AO>7%UcJ4ot%@#?K`j_nSw8uXqW=uIV*&HO%ORi5MUCY=8|ATU4kUYVUg1!yT?86A;-odm*g^+91~!WL%vrnlCr!3 zLZYgxU%je&_1>%ZzUuE*tCoUa`)_YP|JPMT`FDC5{mN*3j1vD66;qfRC|$L!s?^p3 zt*yzY-qz*QXdCibXczF*gJQSTE_KbeDfx|{+_l=4Y!`y5Zlzt3?P5^v*4j1ME(O!w zdb{3jv>Wo>3}(8s?OE9_2Xo!|_PlIc!9sVjz1Ur9FLjsO%c|n(!xit+soK8G8m!7{ zFV*&2f1t2wR)49mx_9M7Z@?{7SH9^a=o=JmMOaTAX< z^{mePIC1=VGR>tO4}^Rbk2%!O{jEL;5ob$Xci(efbYfb6B(>A$!GnKLI%H$|Eul=I zbWq~&=!zoLUU5ems7x7@g~2Z;%1{-?sk)~P%Ai|EtBJm6e4>1QWiTbCh6Sdcs(e*g z!y?{F^mYnQIau9Pj;;t5d<%mL(?n&z$RB~r6cyS32>lDPzlMHYR2G!a6pZU_D!wwP z9&IIMp)o_~tnj6dSso3hj_Zjv#G1l7)dsaqCA@AZNoC*Szfv($Rg&tk#vsMs^r@yQ zhhP0r3AJa6DDhv5+FqUi`rs>36IHYuca?*$HWi_~()fQRGbhSmI+-2LCG)51p#Dld z`g@^#qP$W+|H+_{EQrR5`bzz)KOfAX=f`43_9TN@F*{s51sDG!Zw;4N=@gvt7orU6 zV^J2fG!pN#=rgI0zeIcaRH4ygdcOq9J7RjcB4$Y^VwN=UN*pc(Dq<9c?;_mM3Gg$)CY6nN^&K6duX#7 z*41eAq)*K4HC}1)b?EXcn-&eMi2hSuYWFIulbj(ZE>VU28s8IjdRvAr<7d(W4bgag zb{ZYlM||*rhMeVA@(!#a$DXL97217HSywJ{lU6pBO+=tSR30nONJ}O>=)1|a;dKG2 z;3407t_|h~3&|z103FQi8<6g2QleQg&*p|VlAFm4^_`H9LZ(;R!Ot+`Jgs|lH@PXQ z!*@>=w!jt!*TUO=7pVO z2j_V|UQ3RWv~bPa*;!8ut!?{8%%^eCaF(qgLTGWKFgVVPc;D}3<$mmONl4$m7xe>X zhf!kpD9YI94)7gJ@{M|}SxL1PPphrgxjvBEX|2_AgG2W?ZuP^|?}4_RR$8rXKV&T_ z6exZ=)oOv@9kmb-AX*DyhDIj5A0ybbcB42+SBM-TCdRGF#?Izwv|8R#!rgPTXe}?b zKt79cUu)RuH|jbftmz}@QV`3g4tG5-a5`>h*UOZ2^9gp|^TQpR!k_Jj=XYvv`+;Zw z=tlgxy@ePE_1J#$ZY?d-cd-Ued0 zokVuB>)Ahe{5@*AFCw3T;K%l%%R>m#Oh0)%iI(R?=tN=SVhPNC%SMRBC@kK~r?xQx zS!*1MzgDsN^u6;_-H6fM3Hr=qcDElSeh<4#{H_xYxYx!w;csRbVzzR zXI;qXanHuKFvHfd-Sd0)Hut>LyVIfN=tob|`xBIyGQ3ds5Wr8#K~+k224%9WfZ09D zTk4T?NLhXJ@$IDByNzjKRGH0Mox`1QFFE)Y5oJNLNjx69!R@H$ahdJn+qn>Hz2nTh z8@Syq=6>|ov_6WGE}iw>l@1?&v^HYF>iWKS+-znV_p(wa>h@sotQfCM^}=(e$jUMq z%WPRBmSPa??07sYojE~Pf#2_WokZsS%pAEiUmooriO=VHk0W{e0 zj`#vm7l~T;j--!{F$Ql;n7eM$*#!)_5alw1R7o2T_p|Dm@8rIb=@2BF_PTxoDV?a7 zE36EvL&rPLs-vdUbD5`TuuQ`$)EfZo$gV>*DY?im1I2EcDowhCyKJd+h!>7{a_w##UntSsA> zH^nSACEFENVbzyP8*mvhq0RyR6{*1vxeop4NipOeN_-iWP=(?sLPMVtS)B+U!6BV#o zRnoa+YFGh$EuR94vI6n20-og`m!BzTz|>@geUtx_h$hUv>4BBh1%bWtzQ+GeSWI2UMGeK;FUJ3wG#FsAP`9-O_`;v6XZ_`61)yEo zn;FiEDeSj`_S{*!Dk=c0S40({^q;ZUc?lhBqK5aoqIRMT0oR2F=shi_!P%B_SA{v2 zyCz}Xvt$uIT3~ft$!5MZ&h|7b%mqd63#;(I5EVdT0Ng=6tg$%&FZs5h4CKg(*tH*w*25^Xbnm`|NiQc?0)3+YK3#Wzy%N?ed+zbU%9)f#a4v z3g5Tvv0qa1@40b|=Xj?7+sRg&Yu1?UDWL@^8MjTVGH0byUB5|EPyN3CQxk9iwGa7PQybZRidCA4+0uuiH2Hhc@LA*+j~F5vHq~ zIVihh<1$Y8iV~TPo{5m8en|NMQa*V2?9=;T9b@M)H=#XX%ZqtSDo}#IGZ=R#{r;2B zHpc#f0ZE?Xq0bmQfKn!N5MWEj8Z%&e{k5kC1i& z`jM4;f!mRv589=j2${_f+XX+4`(FAx*X)Nm>>>lY@k9*RF@{Ov?c>+Xe;n z9yBjyS_D9lC(saf?m*nEgl`==X=Ku@0UWnB#&BzJKu*bpZ&Fo3mDR}~$$NmGB>Lec z>iaFK-lOVW;;I3O;b@IMDgfuevN8X*?EC!~7a8&(>BLzHoG(!LJJf4BKyQ@Lv#E0{ zWfgiEiOK1ML{`}0QNIW9wX>58QUkR)lj)rx<`2;3_o@1VDw$6vJE0^b(@~}a&hRa~ zW~CP%k0Df6M#IUGj3s5s+f#6>(Z;h1y^O>m4D*8fG$&o&@=79&xjbVb-o*L$9rE9Q z1Wz2GQp^Qp{kl3sxgXh{kb|ZcwFTsVpaLL+B2WfBO(eN1=&OwXge?e{6g6OsoW}sZ z&Y4xEFX z-$K zR57YNRJbGs$gz2@%-x540;elMIP09zrGXA<%tUh8q9Z2Z=@5;WPCrn05x85cd|D|~ zOxf2gZ_w|-#)Dj9o8-)cFC-&F@Y|@e5?%2SSb3XBHj$=eFnobP7jb#r%&%CN&XL#h z#DH;Y_^67wLso4szs7O?<1v@l$)(q$EJBc%-+N>%ZC`o48*y|E9~WSxeg_FSp4QVzfo~;mK{`oUvpmH1Fol@ezTWn9@asf*bv{I)ycy|2nQg6?M+A41A|J`&)mk GX#Wei{MTOq literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/operations/__pycache__/prepare.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..621988ff7cd9ff96107bfd42c2c505b247fdcb13 GIT binary patch literal 9151 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 W=CTdM05qZ3mzG{#YAyAa8vhIZqN4l& literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/operations/check.py b/env/lib/python3.7/site-packages/pip/_internal/operations/check.py new file mode 100644 index 0000000..799257a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/operations/check.py @@ -0,0 +1,148 @@ +"""Validation of dependencies of packages +""" + +from collections import namedtuple + +from pip._vendor.packaging.utils import canonicalize_name + +from pip._internal.operations.prepare import make_abstract_dist +from pip._internal.utils.misc import get_installed_distributions +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from pip._internal.req.req_install import InstallRequirement # noqa: F401 + from typing import ( # noqa: F401 + Any, Callable, Dict, Iterator, Optional, Set, Tuple, List + ) + + # Shorthands + PackageSet = Dict[str, 'PackageDetails'] + Missing = Tuple[str, Any] + Conflicting = Tuple[str, str, Any] + + MissingDict = Dict[str, List[Missing]] + ConflictingDict = Dict[str, List[Conflicting]] + CheckResult = Tuple[MissingDict, ConflictingDict] + +PackageDetails = namedtuple('PackageDetails', ['version', 'requires']) + + +def create_package_set_from_installed(**kwargs): + # type: (**Any) -> PackageSet + """Converts a list of distributions into a PackageSet. + """ + # Default to using all packages installed on the system + if kwargs == {}: + kwargs = {"local_only": False, "skip": ()} + + package_set = {} + for dist in get_installed_distributions(**kwargs): + name = canonicalize_name(dist.project_name) + package_set[name] = PackageDetails(dist.version, dist.requires()) + return package_set + + +def check_package_set(package_set, should_ignore=None): + # type: (PackageSet, Optional[Callable[[str], bool]]) -> CheckResult + """Check if a package set is consistent + + If should_ignore is passed, it should be a callable that takes a + package name and returns a boolean. + """ + if should_ignore is None: + def should_ignore(name): + return False + + missing = dict() + conflicting = dict() + + for package_name in package_set: + # Info about dependencies of package_name + missing_deps = set() # type: Set[Missing] + conflicting_deps = set() # type: Set[Conflicting] + + if should_ignore(package_name): + continue + + for req in package_set[package_name].requires: + name = canonicalize_name(req.project_name) # type: str + + # Check if it's missing + if name not in package_set: + missed = True + if req.marker is not None: + missed = req.marker.evaluate() + if missed: + missing_deps.add((name, req)) + continue + + # Check if there's a conflict + version = package_set[name].version # type: str + if not req.specifier.contains(version, prereleases=True): + conflicting_deps.add((name, version, req)) + + if missing_deps: + missing[package_name] = sorted(missing_deps, key=str) + if conflicting_deps: + conflicting[package_name] = sorted(conflicting_deps, key=str) + + return missing, conflicting + + +def check_install_conflicts(to_install): + # type: (List[InstallRequirement]) -> Tuple[PackageSet, CheckResult] + """For checking if the dependency graph would be consistent after \ + installing given requirements + """ + # Start from the current state + package_set = create_package_set_from_installed() + # Install packages + would_be_installed = _simulate_installation_of(to_install, package_set) + + # Only warn about directly-dependent packages; create a whitelist of them + whitelist = _create_whitelist(would_be_installed, package_set) + + return ( + package_set, + check_package_set( + package_set, should_ignore=lambda name: name not in whitelist + ) + ) + + +# NOTE from @pradyunsg +# This required a minor update in dependency link handling logic over at +# operations.prepare.IsSDist.dist() to get it working +def _simulate_installation_of(to_install, package_set): + # type: (List[InstallRequirement], PackageSet) -> Set[str] + """Computes the version of packages after installing to_install. + """ + + # Keep track of packages that were installed + installed = set() + + # Modify it as installing requirement_set would (assuming no errors) + for inst_req in to_install: + dist = make_abstract_dist(inst_req).dist(finder=None) + name = canonicalize_name(dist.key) + package_set[name] = PackageDetails(dist.version, dist.requires()) + + installed.add(name) + + return installed + + +def _create_whitelist(would_be_installed, package_set): + # type: (Set[str], PackageSet) -> Set[str] + packages_affected = set(would_be_installed) + + for package_name in package_set: + if package_name in packages_affected: + continue + + for req in package_set[package_name].requires: + if canonicalize_name(req.name) in packages_affected: + packages_affected.add(package_name) + break + + return packages_affected diff --git a/env/lib/python3.7/site-packages/pip/_internal/operations/freeze.py b/env/lib/python3.7/site-packages/pip/_internal/operations/freeze.py new file mode 100644 index 0000000..beb2feb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/operations/freeze.py @@ -0,0 +1,264 @@ +from __future__ import absolute_import + +import collections +import logging +import os +import re + +from pip._vendor import pkg_resources, six +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.pkg_resources import RequirementParseError + +from pip._internal.exceptions import InstallationError +from pip._internal.req.constructors import ( + install_req_from_editable, install_req_from_line, +) +from pip._internal.req.req_file import COMMENT_RE +from pip._internal.utils.deprecation import deprecated +from pip._internal.utils.misc import ( + dist_is_editable, get_installed_distributions, make_vcs_requirement_url, +) + +logger = logging.getLogger(__name__) + + +def freeze( + requirement=None, + find_links=None, local_only=None, user_only=None, skip_regex=None, + isolated=False, + wheel_cache=None, + exclude_editable=False, + skip=()): + find_links = find_links or [] + skip_match = None + + if skip_regex: + skip_match = re.compile(skip_regex).search + + dependency_links = [] + + for dist in pkg_resources.working_set: + if dist.has_metadata('dependency_links.txt'): + dependency_links.extend( + dist.get_metadata_lines('dependency_links.txt') + ) + for link in find_links: + if '#egg=' in link: + dependency_links.append(link) + for link in find_links: + yield '-f %s' % link + installations = {} + for dist in get_installed_distributions(local_only=local_only, + skip=(), + user_only=user_only): + try: + req = FrozenRequirement.from_dist( + dist, + dependency_links + ) + except RequirementParseError: + logger.warning( + "Could not parse requirement: %s", + dist.project_name + ) + continue + if exclude_editable and req.editable: + continue + installations[req.name] = req + + if requirement: + # the options that don't get turned into an InstallRequirement + # should only be emitted once, even if the same option is in multiple + # requirements files, so we need to keep track of what has been emitted + # so that we don't emit it again if it's seen again + emitted_options = set() + # keep track of which files a requirement is in so that we can + # give an accurate warning if a requirement appears multiple times. + req_files = collections.defaultdict(list) + for req_file_path in requirement: + with open(req_file_path) as req_file: + for line in req_file: + if (not line.strip() or + line.strip().startswith('#') or + (skip_match and skip_match(line)) or + line.startswith(( + '-r', '--requirement', + '-Z', '--always-unzip', + '-f', '--find-links', + '-i', '--index-url', + '--pre', + '--trusted-host', + '--process-dependency-links', + '--extra-index-url'))): + line = line.rstrip() + if line not in emitted_options: + emitted_options.add(line) + yield line + continue + + if line.startswith('-e') or line.startswith('--editable'): + if line.startswith('-e'): + line = line[2:].strip() + else: + line = line[len('--editable'):].strip().lstrip('=') + line_req = install_req_from_editable( + line, + isolated=isolated, + wheel_cache=wheel_cache, + ) + else: + line_req = install_req_from_line( + COMMENT_RE.sub('', line).strip(), + isolated=isolated, + wheel_cache=wheel_cache, + ) + + if not line_req.name: + logger.info( + "Skipping line in requirement file [%s] because " + "it's not clear what it would install: %s", + req_file_path, line.strip(), + ) + logger.info( + " (add #egg=PackageName to the URL to avoid" + " this warning)" + ) + elif line_req.name not in installations: + # either it's not installed, or it is installed + # but has been processed already + if not req_files[line_req.name]: + logger.warning( + "Requirement file [%s] contains %s, but that " + "package is not installed", + req_file_path, + COMMENT_RE.sub('', line).strip(), + ) + else: + req_files[line_req.name].append(req_file_path) + else: + yield str(installations[line_req.name]).rstrip() + del installations[line_req.name] + req_files[line_req.name].append(req_file_path) + + # Warn about requirements that were included multiple times (in a + # single requirements file or in different requirements files). + for name, files in six.iteritems(req_files): + if len(files) > 1: + logger.warning("Requirement %s included multiple times [%s]", + name, ', '.join(sorted(set(files)))) + + yield( + '## The following requirements were added by ' + 'pip freeze:' + ) + for installation in sorted( + installations.values(), key=lambda x: x.name.lower()): + if canonicalize_name(installation.name) not in skip: + yield str(installation).rstrip() + + +class FrozenRequirement(object): + def __init__(self, name, req, editable, comments=()): + self.name = name + self.req = req + self.editable = editable + self.comments = comments + + _rev_re = re.compile(r'-r(\d+)$') + _date_re = re.compile(r'-(20\d\d\d\d\d\d)$') + + @classmethod + def _init_args_from_dist(cls, dist, dependency_links): + """ + Compute and return arguments (req, editable, comments) to pass to + FrozenRequirement.__init__(). + + This method is for use in FrozenRequirement.from_dist(). + """ + location = os.path.normcase(os.path.abspath(dist.location)) + comments = [] + from pip._internal.vcs import vcs, get_src_requirement + if dist_is_editable(dist) and vcs.get_backend_name(location): + editable = True + try: + req = get_src_requirement(dist, location) + except InstallationError as exc: + logger.warning( + "Error when trying to get requirement for VCS system %s, " + "falling back to uneditable format", exc + ) + req = None + if req is None: + logger.warning( + 'Could not determine repository location of %s', location + ) + comments.append( + '## !! Could not determine repository location' + ) + req = dist.as_requirement() + editable = False + else: + editable = False + req = dist.as_requirement() + specs = req.specs + assert len(specs) == 1 and specs[0][0] in ["==", "==="], \ + 'Expected 1 spec with == or ===; specs = %r; dist = %r' % \ + (specs, dist) + version = specs[0][1] + ver_match = cls._rev_re.search(version) + date_match = cls._date_re.search(version) + if ver_match or date_match: + svn_backend = vcs.get_backend('svn') + if svn_backend: + svn_location = svn_backend().get_location( + dist, + dependency_links, + ) + if not svn_location: + logger.warning( + 'Warning: cannot find svn location for %s', req, + ) + comments.append( + '## FIXME: could not find svn URL in dependency_links ' + 'for this package:' + ) + else: + deprecated( + "SVN editable detection based on dependency links " + "will be dropped in the future.", + replacement=None, + gone_in="18.2", + issue=4187, + ) + comments.append( + '# Installing as editable to satisfy requirement %s:' % + req + ) + if ver_match: + rev = ver_match.group(1) + else: + rev = '{%s}' % date_match.group(1) + editable = True + egg_name = cls.egg_name(dist) + req = make_vcs_requirement_url(svn_location, rev, egg_name) + + return (req, editable, comments) + + @classmethod + def from_dist(cls, dist, dependency_links): + args = cls._init_args_from_dist(dist, dependency_links) + return cls(dist.project_name, *args) + + @staticmethod + def egg_name(dist): + name = dist.egg_name() + match = re.search(r'-py\d\.\d$', name) + if match: + name = name[:match.start()] + return name + + def __str__(self): + req = self.req + if self.editable: + req = '-e %s' % req + return '\n'.join(list(self.comments) + [str(req)]) + '\n' diff --git a/env/lib/python3.7/site-packages/pip/_internal/operations/prepare.py b/env/lib/python3.7/site-packages/pip/_internal/operations/prepare.py new file mode 100644 index 0000000..104bea3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/operations/prepare.py @@ -0,0 +1,355 @@ +"""Prepares a distribution for installation +""" + +import logging +import os + +from pip._vendor import pkg_resources, requests + +from pip._internal.build_env import BuildEnvironment +from pip._internal.download import ( + is_dir_url, is_file_url, is_vcs_url, unpack_url, url_to_path, +) +from pip._internal.exceptions import ( + DirectoryUrlHashUnsupported, HashUnpinned, InstallationError, + PreviousBuildDirError, VcsHashUnsupported, +) +from pip._internal.utils.compat import expanduser +from pip._internal.utils.hashes import MissingHashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import display_path, normalize_path +from pip._internal.vcs import vcs + +logger = logging.getLogger(__name__) + + +def make_abstract_dist(req): + """Factory to make an abstract dist object. + + Preconditions: Either an editable req with a source_dir, or satisfied_by or + a wheel link, or a non-editable req with a source_dir. + + :return: A concrete DistAbstraction. + """ + if req.editable: + return IsSDist(req) + elif req.link and req.link.is_wheel: + return IsWheel(req) + else: + return IsSDist(req) + + +class DistAbstraction(object): + """Abstracts out the wheel vs non-wheel Resolver.resolve() logic. + + The requirements for anything installable are as follows: + - we must be able to determine the requirement name + (or we can't correctly handle the non-upgrade case). + - we must be able to generate a list of run-time dependencies + without installing any additional packages (or we would + have to either burn time by doing temporary isolated installs + or alternatively violate pips 'don't start installing unless + all requirements are available' rule - neither of which are + desirable). + - for packages with setup requirements, we must also be able + to determine their requirements without installing additional + packages (for the same reason as run-time dependencies) + - we must be able to create a Distribution object exposing the + above metadata. + """ + + def __init__(self, req): + self.req = req + + def dist(self, finder): + """Return a setuptools Dist object.""" + raise NotImplementedError(self.dist) + + def prep_for_dist(self, finder, build_isolation): + """Ensure that we can get a Dist for this requirement.""" + raise NotImplementedError(self.dist) + + +class IsWheel(DistAbstraction): + + def dist(self, finder): + return list(pkg_resources.find_distributions( + self.req.source_dir))[0] + + def prep_for_dist(self, finder, build_isolation): + # FIXME:https://github.com/pypa/pip/issues/1112 + pass + + +class IsSDist(DistAbstraction): + + def dist(self, finder): + dist = self.req.get_dist() + # FIXME: shouldn't be globally added. + if finder and dist.has_metadata('dependency_links.txt'): + finder.add_dependency_links( + dist.get_metadata_lines('dependency_links.txt') + ) + return dist + + def prep_for_dist(self, finder, build_isolation): + # Prepare for building. We need to: + # 1. Load pyproject.toml (if it exists) + # 2. Set up the build environment + + self.req.load_pyproject_toml() + should_isolate = self.req.use_pep517 and build_isolation + + if should_isolate: + # Isolate in a BuildEnvironment and install the build-time + # requirements. + self.req.build_env = BuildEnvironment() + self.req.build_env.install_requirements( + finder, self.req.pyproject_requires, + "Installing build dependencies" + ) + missing = [] + if self.req.requirements_to_check: + check = self.req.requirements_to_check + missing = self.req.build_env.missing_requirements(check) + if missing: + logger.warning( + "Missing build requirements in pyproject.toml for %s.", + self.req, + ) + logger.warning( + "The project does not specify a build backend, and pip " + "cannot fall back to setuptools without %s.", + " and ".join(map(repr, sorted(missing))) + ) + + self.req.run_egg_info() + self.req.assert_source_matches_version() + + +class Installed(DistAbstraction): + + def dist(self, finder): + return self.req.satisfied_by + + def prep_for_dist(self, finder, build_isolation): + pass + + +class RequirementPreparer(object): + """Prepares a Requirement + """ + + def __init__(self, build_dir, download_dir, src_dir, wheel_download_dir, + progress_bar, build_isolation, req_tracker): + super(RequirementPreparer, self).__init__() + + self.src_dir = src_dir + self.build_dir = build_dir + self.req_tracker = req_tracker + + # Where still packed archives should be written to. If None, they are + # not saved, and are deleted immediately after unpacking. + self.download_dir = download_dir + + # Where still-packed .whl files should be written to. If None, they are + # written to the download_dir parameter. Separate to download_dir to + # permit only keeping wheel archives for pip wheel. + if wheel_download_dir: + wheel_download_dir = normalize_path(wheel_download_dir) + self.wheel_download_dir = wheel_download_dir + + # NOTE + # download_dir and wheel_download_dir overlap semantically and may + # be combined if we're willing to have non-wheel archives present in + # the wheelhouse output by 'pip wheel'. + + self.progress_bar = progress_bar + + # Is build isolation allowed? + self.build_isolation = build_isolation + + @property + def _download_should_save(self): + # TODO: Modify to reduce indentation needed + if self.download_dir: + self.download_dir = expanduser(self.download_dir) + if os.path.exists(self.download_dir): + return True + else: + logger.critical('Could not find download directory') + raise InstallationError( + "Could not find or access download directory '%s'" + % display_path(self.download_dir)) + return False + + def prepare_linked_requirement(self, req, session, finder, + upgrade_allowed, require_hashes): + """Prepare a requirement that would be obtained from req.link + """ + # TODO: Breakup into smaller functions + if req.link and req.link.scheme == 'file': + path = url_to_path(req.link.url) + logger.info('Processing %s', display_path(path)) + else: + logger.info('Collecting %s', req) + + with indent_log(): + # @@ if filesystem packages are not marked + # editable in a req, a non deterministic error + # occurs when the script attempts to unpack the + # build directory + req.ensure_has_source_dir(self.build_dir) + # If a checkout exists, it's unwise to keep going. version + # inconsistencies are logged later, but do not fail the + # installation. + # FIXME: this won't upgrade when there's an existing + # package unpacked in `req.source_dir` + # package unpacked in `req.source_dir` + if os.path.exists(os.path.join(req.source_dir, 'setup.py')): + raise PreviousBuildDirError( + "pip can't proceed with requirements '%s' due to a" + " pre-existing build directory (%s). This is " + "likely due to a previous installation that failed" + ". pip is being responsible and not assuming it " + "can delete this. Please delete it and try again." + % (req, req.source_dir) + ) + req.populate_link(finder, upgrade_allowed, require_hashes) + + # We can't hit this spot and have populate_link return None. + # req.satisfied_by is None here (because we're + # guarded) and upgrade has no impact except when satisfied_by + # is not None. + # Then inside find_requirement existing_applicable -> False + # If no new versions are found, DistributionNotFound is raised, + # otherwise a result is guaranteed. + assert req.link + link = req.link + + # Now that we have the real link, we can tell what kind of + # requirements we have and raise some more informative errors + # than otherwise. (For example, we can raise VcsHashUnsupported + # for a VCS URL rather than HashMissing.) + if require_hashes: + # We could check these first 2 conditions inside + # unpack_url and save repetition of conditions, but then + # we would report less-useful error messages for + # unhashable requirements, complaining that there's no + # hash provided. + if is_vcs_url(link): + raise VcsHashUnsupported() + elif is_file_url(link) and is_dir_url(link): + raise DirectoryUrlHashUnsupported() + if not req.original_link and not req.is_pinned: + # Unpinned packages are asking for trouble when a new + # version is uploaded. This isn't a security check, but + # it saves users a surprising hash mismatch in the + # future. + # + # file:/// URLs aren't pinnable, so don't complain + # about them not being pinned. + raise HashUnpinned() + + hashes = req.hashes(trust_internet=not require_hashes) + if require_hashes and not hashes: + # Known-good hashes are missing for this requirement, so + # shim it with a facade object that will provoke hash + # computation and then raise a HashMissing exception + # showing the user what the hash should be. + hashes = MissingHashes() + + try: + download_dir = self.download_dir + # We always delete unpacked sdists after pip ran. + autodelete_unpacked = True + if req.link.is_wheel and self.wheel_download_dir: + # when doing 'pip wheel` we download wheels to a + # dedicated dir. + download_dir = self.wheel_download_dir + if req.link.is_wheel: + if download_dir: + # When downloading, we only unpack wheels to get + # metadata. + autodelete_unpacked = True + else: + # When installing a wheel, we use the unpacked + # wheel. + autodelete_unpacked = False + unpack_url( + req.link, req.source_dir, + download_dir, autodelete_unpacked, + session=session, hashes=hashes, + progress_bar=self.progress_bar + ) + except requests.HTTPError as exc: + logger.critical( + 'Could not install requirement %s because of error %s', + req, + exc, + ) + raise InstallationError( + 'Could not install requirement %s because of HTTP ' + 'error %s for URL %s' % + (req, exc, req.link) + ) + abstract_dist = make_abstract_dist(req) + with self.req_tracker.track(req): + abstract_dist.prep_for_dist(finder, self.build_isolation) + if self._download_should_save: + # Make a .zip of the source_dir we already created. + if req.link.scheme in vcs.all_schemes: + req.archive(self.download_dir) + return abstract_dist + + def prepare_editable_requirement(self, req, require_hashes, use_user_site, + finder): + """Prepare an editable requirement + """ + assert req.editable, "cannot prepare a non-editable req as editable" + + logger.info('Obtaining %s', req) + + with indent_log(): + if require_hashes: + raise InstallationError( + 'The editable requirement %s cannot be installed when ' + 'requiring hashes, because there is no single file to ' + 'hash.' % req + ) + req.ensure_has_source_dir(self.src_dir) + req.update_editable(not self._download_should_save) + + abstract_dist = make_abstract_dist(req) + with self.req_tracker.track(req): + abstract_dist.prep_for_dist(finder, self.build_isolation) + + if self._download_should_save: + req.archive(self.download_dir) + req.check_if_exists(use_user_site) + + return abstract_dist + + def prepare_installed_requirement(self, req, require_hashes, skip_reason): + """Prepare an already-installed requirement + """ + assert req.satisfied_by, "req should have been satisfied but isn't" + assert skip_reason is not None, ( + "did not get skip reason skipped but req.satisfied_by " + "is set to %r" % (req.satisfied_by,) + ) + logger.info( + 'Requirement %s: %s (%s)', + skip_reason, req, req.satisfied_by.version + ) + with indent_log(): + if require_hashes: + logger.debug( + 'Since it is already installed, we are trusting this ' + 'package without checking its hash. To ensure a ' + 'completely repeatable environment, install into an ' + 'empty virtualenv.' + ) + abstract_dist = Installed(req) + + return abstract_dist diff --git a/env/lib/python3.7/site-packages/pip/_internal/pep425tags.py b/env/lib/python3.7/site-packages/pip/_internal/pep425tags.py new file mode 100644 index 0000000..ab1a029 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/pep425tags.py @@ -0,0 +1,317 @@ +"""Generate and work with PEP 425 Compatibility Tags.""" +from __future__ import absolute_import + +import distutils.util +import logging +import platform +import re +import sys +import sysconfig +import warnings +from collections import OrderedDict + +import pip._internal.utils.glibc +from pip._internal.utils.compat import get_extension_suffixes + +logger = logging.getLogger(__name__) + +_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') + + +def get_config_var(var): + try: + return sysconfig.get_config_var(var) + except IOError as e: # Issue #1074 + warnings.warn("{}".format(e), RuntimeWarning) + return None + + +def get_abbr_impl(): + """Return abbreviated implementation name.""" + if hasattr(sys, 'pypy_version_info'): + pyimpl = 'pp' + elif sys.platform.startswith('java'): + pyimpl = 'jy' + elif sys.platform == 'cli': + pyimpl = 'ip' + else: + pyimpl = 'cp' + return pyimpl + + +def get_impl_ver(): + """Return implementation version.""" + impl_ver = get_config_var("py_version_nodot") + if not impl_ver or get_abbr_impl() == 'pp': + impl_ver = ''.join(map(str, get_impl_version_info())) + return impl_ver + + +def get_impl_version_info(): + """Return sys.version_info-like tuple for use in decrementing the minor + version.""" + if get_abbr_impl() == 'pp': + # as per https://github.com/pypa/pip/issues/2882 + return (sys.version_info[0], sys.pypy_version_info.major, + sys.pypy_version_info.minor) + else: + return sys.version_info[0], sys.version_info[1] + + +def get_impl_tag(): + """ + Returns the Tag for this specific implementation. + """ + return "{}{}".format(get_abbr_impl(), get_impl_ver()) + + +def get_flag(var, fallback, expected=True, warn=True): + """Use a fallback method for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + logger.debug("Config variable '%s' is unset, Python ABI tag may " + "be incorrect", var) + return fallback() + return val == expected + + +def get_abi_tag(): + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = get_abbr_impl() + if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + lambda: hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + lambda: impl == 'cp', + warn=(impl == 'cp')): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + u = 'u' + abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + +def _is_running_32bit(): + return sys.maxsize == 2147483647 + + +def get_platform(): + """Return our platform name 'win32', 'linux_x86_64'""" + if sys.platform == 'darwin': + # distutils.util.get_platform() returns the release based on the value + # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may + # be significantly older than the user's current machine. + release, _, machine = platform.mac_ver() + split_ver = release.split('.') + + if machine == "x86_64" and _is_running_32bit(): + machine = "i386" + elif machine == "ppc64" and _is_running_32bit(): + machine = "ppc" + + return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) + + # XXX remove distutils dependency + result = distutils.util.get_platform().replace('.', '_').replace('-', '_') + if result == "linux_x86_64" and _is_running_32bit(): + # 32 bit Python program (running on a 64 bit Linux): pip should only + # install and run 32 bit compiled extensions in that case. + result = "linux_i686" + + return result + + +def is_manylinux1_compatible(): + # Only Linux, and only x86-64 / i686 + if get_platform() not in {"linux_x86_64", "linux_i686"}: + return False + + # Check for presence of _manylinux module + try: + import _manylinux + return bool(_manylinux.manylinux1_compatible) + except (ImportError, AttributeError): + # Fall through to heuristic check below + pass + + # Check glibc version. CentOS 5 uses glibc 2.5. + return pip._internal.utils.glibc.have_compatible_glibc(2, 5) + + +def get_darwin_arches(major, minor, machine): + """Return a list of supported arches (including group arches) for + the given major, minor and machine architecture of an macOS machine. + """ + arches = [] + + def _supports_arch(major, minor, arch): + # Looking at the application support for macOS versions in the chart + # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears + # our timeline looks roughly like: + # + # 10.0 - Introduces ppc support. + # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 + # and x86_64 support is CLI only, and cannot be used for GUI + # applications. + # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. + # 10.6 - Drops support for ppc64 + # 10.7 - Drops support for ppc + # + # Given that we do not know if we're installing a CLI or a GUI + # application, we must be conservative and assume it might be a GUI + # application and behave as if ppc64 and x86_64 support did not occur + # until 10.5. + # + # Note: The above information is taken from the "Application support" + # column in the chart not the "Processor support" since I believe + # that we care about what instruction sets an application can use + # not which processors the OS supports. + if arch == 'ppc': + return (major, minor) <= (10, 5) + if arch == 'ppc64': + return (major, minor) == (10, 5) + if arch == 'i386': + return (major, minor) >= (10, 4) + if arch == 'x86_64': + return (major, minor) >= (10, 5) + if arch in groups: + for garch in groups[arch]: + if _supports_arch(major, minor, garch): + return True + return False + + groups = OrderedDict([ + ("fat", ("i386", "ppc")), + ("intel", ("x86_64", "i386")), + ("fat64", ("x86_64", "ppc64")), + ("fat32", ("x86_64", "i386", "ppc")), + ]) + + if _supports_arch(major, minor, machine): + arches.append(machine) + + for garch in groups: + if machine in groups[garch] and _supports_arch(major, minor, garch): + arches.append(garch) + + arches.append('universal') + + return arches + + +def get_supported(versions=None, noarch=False, platform=None, + impl=None, abi=None): + """Return a list of supported tags for each version specified in + `versions`. + + :param versions: a list of string versions, of the form ["33", "32"], + or None. The first version will be assumed to support our ABI. + :param platform: specify the exact platform you want valid + tags for, or None. If None, use the local system platform. + :param impl: specify the exact implementation you want valid + tags for, or None. If None, use the local interpreter impl. + :param abi: specify the exact abi you want valid + tags for, or None. If None, use the local interpreter abi. + """ + supported = [] + + # Versions must be given with respect to the preference + if versions is None: + versions = [] + version_info = get_impl_version_info() + major = version_info[:-1] + # Support all previous minor Python versions. + for minor in range(version_info[-1], -1, -1): + versions.append(''.join(map(str, major + (minor,)))) + + impl = impl or get_abbr_impl() + + abis = [] + + abi = abi or get_abi_tag() + if abi: + abis[0:0] = [abi] + + abi3s = set() + for suffix in get_extension_suffixes(): + if suffix.startswith('.abi'): + abi3s.add(suffix.split('.', 2)[1]) + + abis.extend(sorted(list(abi3s))) + + abis.append('none') + + if not noarch: + arch = platform or get_platform() + if arch.startswith('macosx'): + # support macosx-10.6-intel on macosx-10.9-x86_64 + match = _osx_arch_pat.match(arch) + if match: + name, major, minor, actual_arch = match.groups() + tpl = '{}_{}_%i_%s'.format(name, major) + arches = [] + for m in reversed(range(int(minor) + 1)): + for a in get_darwin_arches(int(major), m, actual_arch): + arches.append(tpl % (m, a)) + else: + # arch pattern didn't match (?!) + arches = [arch] + elif platform is None and is_manylinux1_compatible(): + arches = [arch.replace('linux', 'manylinux1'), arch] + else: + arches = [arch] + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in arches: + supported.append(('%s%s' % (impl, versions[0]), abi, arch)) + + # abi3 modules compatible with older version of Python + for version in versions[1:]: + # abi3 was introduced in Python 3.2 + if version in {'31', '30'}: + break + for abi in abi3s: # empty set if not Python 3 + for arch in arches: + supported.append(("%s%s" % (impl, version), abi, arch)) + + # Has binaries, does not use the Python API: + for arch in arches: + supported.append(('py%s' % (versions[0][0]), 'none', arch)) + + # No abi / arch, but requires our implementation: + supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) + # Tagged specifically as being cross-version compatible + # (with just the major version specified) + supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) + + # No abi / arch, generic Python + for i, version in enumerate(versions): + supported.append(('py%s' % (version,), 'none', 'any')) + if i == 0: + supported.append(('py%s' % (version[0]), 'none', 'any')) + + return supported + + +implementation_tag = get_impl_tag() diff --git a/env/lib/python3.7/site-packages/pip/_internal/pyproject.py b/env/lib/python3.7/site-packages/pip/_internal/pyproject.py new file mode 100644 index 0000000..f938a76 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/pyproject.py @@ -0,0 +1,144 @@ +from __future__ import absolute_import + +import io +import os + +from pip._vendor import pytoml, six + +from pip._internal.exceptions import InstallationError + + +def _is_list_of_str(obj): + return ( + isinstance(obj, list) and + all(isinstance(item, six.string_types) for item in obj) + ) + + +def load_pyproject_toml(use_pep517, pyproject_toml, setup_py, req_name): + """Load the pyproject.toml file. + + Parameters: + use_pep517 - Has the user requested PEP 517 processing? None + means the user hasn't explicitly specified. + pyproject_toml - Location of the project's pyproject.toml file + setup_py - Location of the project's setup.py file + req_name - The name of the requirement we're processing (for + error reporting) + + Returns: + None if we should use the legacy code path, otherwise a tuple + ( + requirements from pyproject.toml, + name of PEP 517 backend, + requirements we should check are installed after setting + up the build environment + ) + """ + has_pyproject = os.path.isfile(pyproject_toml) + has_setup = os.path.isfile(setup_py) + + if has_pyproject: + with io.open(pyproject_toml, encoding="utf-8") as f: + pp_toml = pytoml.load(f) + build_system = pp_toml.get("build-system") + else: + build_system = None + + # The following cases must use PEP 517 + # We check for use_pep517 equalling False because that + # means the user explicitly requested --no-use-pep517 + if has_pyproject and not has_setup: + if use_pep517 is False: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project does not have a setup.py" + ) + use_pep517 = True + elif build_system and "build-backend" in build_system: + if use_pep517 is False: + raise InstallationError( + "Disabling PEP 517 processing is invalid: " + "project specifies a build backend of {} " + "in pyproject.toml".format( + build_system["build-backend"] + ) + ) + use_pep517 = True + + # If we haven't worked out whether to use PEP 517 yet, + # and the user hasn't explicitly stated a preference, + # we do so if the project has a pyproject.toml file. + elif use_pep517 is None: + use_pep517 = has_pyproject + + # At this point, we know whether we're going to use PEP 517. + assert use_pep517 is not None + + # If we're using the legacy code path, there is nothing further + # for us to do here. + if not use_pep517: + return None + + if build_system is None: + # Either the user has a pyproject.toml with no build-system + # section, or the user has no pyproject.toml, but has opted in + # explicitly via --use-pep517. + # In the absence of any explicit backend specification, we + # assume the setuptools backend, and require wheel and a version + # of setuptools that supports that backend. + build_system = { + "requires": ["setuptools>=38.2.5", "wheel"], + "build-backend": "setuptools.build_meta", + } + + # If we're using PEP 517, we have build system information (either + # from pyproject.toml, or defaulted by the code above). + # Note that at this point, we do not know if the user has actually + # specified a backend, though. + assert build_system is not None + + # Ensure that the build-system section in pyproject.toml conforms + # to PEP 518. + error_template = ( + "{package} has a pyproject.toml file that does not comply " + "with PEP 518: {reason}" + ) + + # Specifying the build-system table but not the requires key is invalid + if "requires" not in build_system: + raise InstallationError( + error_template.format(package=req_name, reason=( + "it has a 'build-system' table but not " + "'build-system.requires' which is mandatory in the table" + )) + ) + + # Error out if requires is not a list of strings + requires = build_system["requires"] + if not _is_list_of_str(requires): + raise InstallationError(error_template.format( + package=req_name, + reason="'build-system.requires' is not a list of strings.", + )) + + backend = build_system.get("build-backend") + check = [] + if backend is None: + # If the user didn't specify a backend, we assume they want to use + # the setuptools backend. But we can't be sure they have included + # a version of setuptools which supplies the backend, or wheel + # (which is neede by the backend) in their requirements. So we + # make a note to check that those requirements are present once + # we have set up the environment. + # TODO: Review this - it's quite a lot of work to check for a very + # specific case. The problem is, that case is potentially quite + # common - projects that adopted PEP 518 early for the ability to + # specify requirements to execute setup.py, but never considered + # needing to mention the build tools themselves. The original PEP + # 518 code had a similar check (but implemented in a different + # way). + backend = "setuptools.build_meta" + check = ["setuptools>=38.2.5", "wheel"] + + return (requires, backend, check) diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/__init__.py b/env/lib/python3.7/site-packages/pip/_internal/req/__init__.py new file mode 100644 index 0000000..b270498 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/req/__init__.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import + +import logging + +from .req_install import InstallRequirement +from .req_set import RequirementSet +from .req_file import parse_requirements +from pip._internal.utils.logging import indent_log + + +__all__ = [ + "RequirementSet", "InstallRequirement", + "parse_requirements", "install_given_reqs", +] + +logger = logging.getLogger(__name__) + + +def install_given_reqs(to_install, install_options, global_options=(), + *args, **kwargs): + """ + Install everything in the given list. + + (to be called after having downloaded and unpacked the packages) + """ + + if to_install: + logger.info( + 'Installing collected packages: %s', + ', '.join([req.name for req in to_install]), + ) + + with indent_log(): + for requirement in to_install: + if requirement.conflicts_with: + logger.info( + 'Found existing installation: %s', + requirement.conflicts_with, + ) + with indent_log(): + uninstalled_pathset = requirement.uninstall( + auto_confirm=True + ) + try: + requirement.install( + install_options, + global_options, + *args, + **kwargs + ) + except Exception: + should_rollback = ( + requirement.conflicts_with and + not requirement.install_succeeded + ) + # if install did not succeed, rollback previous uninstall + if should_rollback: + uninstalled_pathset.rollback() + raise + else: + should_commit = ( + requirement.conflicts_with and + requirement.install_succeeded + ) + if should_commit: + uninstalled_pathset.commit() + requirement.remove_temporary_source() + + return to_install diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e3c7a3e1179cf97d49f170dfa58a11da4b55fc7 GIT binary patch literal 1521 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_file.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07a1afdd6aee6bac91e6fdf5baf7b5d87c7b9d5a GIT binary patch literal 8620 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 MI8%JPI9we0UyxUYH~;_u literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a34182b1c8c682c8cf76f137babf9684caf5257a GIT binary patch literal 22770 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/req/__pycache__/req_tracker.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8daa87c157a6de3be0fe5ccfed44d8d392b43a2b GIT binary patch literal 2845 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/constructors.py b/env/lib/python3.7/site-packages/pip/_internal/req/constructors.py new file mode 100644 index 0000000..4c4641d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/req/constructors.py @@ -0,0 +1,298 @@ +"""Backing implementation for InstallRequirement's various constructors + +The idea here is that these formed a major chunk of InstallRequirement's size +so, moving them and support code dedicated to them outside of that class +helps creates for better understandability for the rest of the code. + +These are meant to be used elsewhere within pip to create instances of +InstallRequirement. +""" + +import logging +import os +import re +import traceback + +from pip._vendor.packaging.markers import Marker +from pip._vendor.packaging.requirements import InvalidRequirement, Requirement +from pip._vendor.packaging.specifiers import Specifier +from pip._vendor.pkg_resources import RequirementParseError, parse_requirements + +from pip._internal.download import ( + is_archive_file, is_url, path_to_url, url_to_path, +) +from pip._internal.exceptions import InstallationError +from pip._internal.models.index import PyPI, TestPyPI +from pip._internal.models.link import Link +from pip._internal.req.req_install import InstallRequirement +from pip._internal.utils.misc import is_installable_dir +from pip._internal.vcs import vcs +from pip._internal.wheel import Wheel + +__all__ = [ + "install_req_from_editable", "install_req_from_line", + "parse_editable" +] + +logger = logging.getLogger(__name__) +operators = Specifier._operators.keys() + + +def _strip_extras(path): + m = re.match(r'^(.+)(\[[^\]]+\])$', path) + extras = None + if m: + path_no_extras = m.group(1) + extras = m.group(2) + else: + path_no_extras = path + + return path_no_extras, extras + + +def parse_editable(editable_req): + """Parses an editable requirement into: + - a requirement name + - an URL + - extras + - editable options + Accepted requirements: + svn+http://blahblah@rev#egg=Foobar[baz]&subdirectory=version_subdir + .[some_extra] + """ + + url = editable_req + + # If a file path is specified with extras, strip off the extras. + url_no_extras, extras = _strip_extras(url) + + if os.path.isdir(url_no_extras): + if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): + raise InstallationError( + "Directory %r is not installable. File 'setup.py' not found." % + url_no_extras + ) + # Treating it as code that has already been checked out + url_no_extras = path_to_url(url_no_extras) + + if url_no_extras.lower().startswith('file:'): + package_name = Link(url_no_extras).egg_fragment + if extras: + return ( + package_name, + url_no_extras, + Requirement("placeholder" + extras.lower()).extras, + ) + else: + return package_name, url_no_extras, None + + for version_control in vcs: + if url.lower().startswith('%s:' % version_control): + url = '%s+%s' % (version_control, url) + break + + if '+' not in url: + raise InstallationError( + '%s should either be a path to a local project or a VCS url ' + 'beginning with svn+, git+, hg+, or bzr+' % + editable_req + ) + + vc_type = url.split('+', 1)[0].lower() + + if not vcs.get_backend(vc_type): + error_message = 'For --editable=%s only ' % editable_req + \ + ', '.join([backend.name + '+URL' for backend in vcs.backends]) + \ + ' is currently supported' + raise InstallationError(error_message) + + package_name = Link(url).egg_fragment + if not package_name: + raise InstallationError( + "Could not detect requirement name for '%s', please specify one " + "with #egg=your_package_name" % editable_req + ) + return package_name, url, None + + +def deduce_helpful_msg(req): + """Returns helpful msg in case requirements file does not exist, + or cannot be parsed. + + :params req: Requirements file path + """ + msg = "" + if os.path.exists(req): + msg = " It does exist." + # Try to parse and check if it is a requirements file. + try: + with open(req, 'r') as fp: + # parse first line only + next(parse_requirements(fp.read())) + msg += " The argument you provided " + \ + "(%s) appears to be a" % (req) + \ + " requirements file. If that is the" + \ + " case, use the '-r' flag to install" + \ + " the packages specified within it." + except RequirementParseError: + logger.debug("Cannot parse '%s' as requirements \ + file" % (req), exc_info=1) + else: + msg += " File '%s' does not exist." % (req) + return msg + + +# ---- The actual constructors follow ---- + + +def install_req_from_editable( + editable_req, comes_from=None, isolated=False, options=None, + wheel_cache=None, constraint=False +): + name, url, extras_override = parse_editable(editable_req) + if url.startswith('file:'): + source_dir = url_to_path(url) + else: + source_dir = None + + if name is not None: + try: + req = Requirement(name) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % name) + else: + req = None + return InstallRequirement( + req, comes_from, source_dir=source_dir, + editable=True, + link=Link(url), + constraint=constraint, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + extras=extras_override or (), + ) + + +def install_req_from_line( + name, comes_from=None, isolated=False, options=None, wheel_cache=None, + constraint=False +): + """Creates an InstallRequirement from a name, which might be a + requirement, directory containing 'setup.py', filename, or URL. + """ + if is_url(name): + marker_sep = '; ' + else: + marker_sep = ';' + if marker_sep in name: + name, markers = name.split(marker_sep, 1) + markers = markers.strip() + if not markers: + markers = None + else: + markers = Marker(markers) + else: + markers = None + name = name.strip() + req = None + path = os.path.normpath(os.path.abspath(name)) + link = None + extras = None + + if is_url(name): + link = Link(name) + else: + p, extras = _strip_extras(path) + looks_like_dir = os.path.isdir(p) and ( + os.path.sep in name or + (os.path.altsep is not None and os.path.altsep in name) or + name.startswith('.') + ) + if looks_like_dir: + if not is_installable_dir(p): + raise InstallationError( + "Directory %r is not installable. Neither 'setup.py' " + "nor 'pyproject.toml' found." % name + ) + link = Link(path_to_url(p)) + elif is_archive_file(p): + if not os.path.isfile(p): + logger.warning( + 'Requirement %r looks like a filename, but the ' + 'file does not exist', + name + ) + link = Link(path_to_url(p)) + + # it's a local file, dir, or url + if link: + # Handle relative file URLs + if link.scheme == 'file' and re.search(r'\.\./', link.url): + link = Link( + path_to_url(os.path.normpath(os.path.abspath(link.path)))) + # wheel file + if link.is_wheel: + wheel = Wheel(link.filename) # can raise InvalidWheelFilename + req = "%s==%s" % (wheel.name, wheel.version) + else: + # set the req to the egg fragment. when it's not there, this + # will become an 'unnamed' requirement + req = link.egg_fragment + + # a requirement specifier + else: + req = name + + if extras: + extras = Requirement("placeholder" + extras.lower()).extras + else: + extras = () + if req is not None: + try: + req = Requirement(req) + except InvalidRequirement: + if os.path.sep in req: + add_msg = "It looks like a path." + add_msg += deduce_helpful_msg(req) + elif '=' in req and not any(op in req for op in operators): + add_msg = "= is not a valid operator. Did you mean == ?" + else: + add_msg = traceback.format_exc() + raise InstallationError( + "Invalid requirement: '%s'\n%s" % (req, add_msg) + ) + + return InstallRequirement( + req, comes_from, link=link, markers=markers, + isolated=isolated, + options=options if options else {}, + wheel_cache=wheel_cache, + constraint=constraint, + extras=extras, + ) + + +def install_req_from_req( + req, comes_from=None, isolated=False, wheel_cache=None +): + try: + req = Requirement(req) + except InvalidRequirement: + raise InstallationError("Invalid requirement: '%s'" % req) + + domains_not_allowed = [ + PyPI.file_storage_domain, + TestPyPI.file_storage_domain, + ] + if req.url and comes_from.link.netloc in domains_not_allowed: + # Explicitly disallow pypi packages that depend on external urls + raise InstallationError( + "Packages installed from PyPI cannot depend on packages " + "which are not also hosted on PyPI.\n" + "%s depends on %s " % (comes_from.name, req) + ) + + return InstallRequirement( + req, comes_from, isolated=isolated, wheel_cache=wheel_cache + ) diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/req_file.py b/env/lib/python3.7/site-packages/pip/_internal/req/req_file.py new file mode 100644 index 0000000..e7acf7c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/req/req_file.py @@ -0,0 +1,340 @@ +""" +Requirements file parsing +""" + +from __future__ import absolute_import + +import optparse +import os +import re +import shlex +import sys + +from pip._vendor.six.moves import filterfalse +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.cli import cmdoptions +from pip._internal.download import get_file_content +from pip._internal.exceptions import RequirementsFileParseError +from pip._internal.req.constructors import ( + install_req_from_editable, install_req_from_line, +) + +__all__ = ['parse_requirements'] + +SCHEME_RE = re.compile(r'^(http|https|file):', re.I) +COMMENT_RE = re.compile(r'(^|\s)+#.*$') + +# Matches environment variable-style values in '${MY_VARIABLE_1}' with the +# variable name consisting of only uppercase letters, digits or the '_' +# (underscore). This follows the POSIX standard defined in IEEE Std 1003.1, +# 2013 Edition. +ENV_VAR_RE = re.compile(r'(?P\$\{(?P[A-Z0-9_]+)\})') + +SUPPORTED_OPTIONS = [ + cmdoptions.constraints, + cmdoptions.editable, + cmdoptions.requirements, + cmdoptions.no_index, + cmdoptions.index_url, + cmdoptions.find_links, + cmdoptions.extra_index_url, + cmdoptions.always_unzip, + cmdoptions.no_binary, + cmdoptions.only_binary, + cmdoptions.pre, + cmdoptions.process_dependency_links, + cmdoptions.trusted_host, + cmdoptions.require_hashes, +] + +# options to be passed to requirements +SUPPORTED_OPTIONS_REQ = [ + cmdoptions.install_options, + cmdoptions.global_options, + cmdoptions.hash, +] + +# the 'dest' string values +SUPPORTED_OPTIONS_REQ_DEST = [o().dest for o in SUPPORTED_OPTIONS_REQ] + + +def parse_requirements(filename, finder=None, comes_from=None, options=None, + session=None, constraint=False, wheel_cache=None): + """Parse a requirements file and yield InstallRequirement instances. + + :param filename: Path or url of requirements file. + :param finder: Instance of pip.index.PackageFinder. + :param comes_from: Origin description of requirements. + :param options: cli options. + :param session: Instance of pip.download.PipSession. + :param constraint: If true, parsing a constraint file rather than + requirements file. + :param wheel_cache: Instance of pip.wheel.WheelCache + """ + if session is None: + raise TypeError( + "parse_requirements() missing 1 required keyword argument: " + "'session'" + ) + + _, content = get_file_content( + filename, comes_from=comes_from, session=session + ) + + lines_enum = preprocess(content, options) + + for line_number, line in lines_enum: + req_iter = process_line(line, filename, line_number, finder, + comes_from, options, session, wheel_cache, + constraint=constraint) + for req in req_iter: + yield req + + +def preprocess(content, options): + """Split, filter, and join lines, and return a line iterator + + :param content: the content of the requirements file + :param options: cli options + """ + lines_enum = enumerate(content.splitlines(), start=1) + lines_enum = join_lines(lines_enum) + lines_enum = ignore_comments(lines_enum) + lines_enum = skip_regex(lines_enum, options) + lines_enum = expand_env_variables(lines_enum) + return lines_enum + + +def process_line(line, filename, line_number, finder=None, comes_from=None, + options=None, session=None, wheel_cache=None, + constraint=False): + """Process a single requirements line; This can result in creating/yielding + requirements, or updating the finder. + + For lines that contain requirements, the only options that have an effect + are from SUPPORTED_OPTIONS_REQ, and they are scoped to the + requirement. Other options from SUPPORTED_OPTIONS may be present, but are + ignored. + + For lines that do not contain requirements, the only options that have an + effect are from SUPPORTED_OPTIONS. Options from SUPPORTED_OPTIONS_REQ may + be present, but are ignored. These lines may contain multiple options + (although our docs imply only one is supported), and all our parsed and + affect the finder. + + :param constraint: If True, parsing a constraints file. + :param options: OptionParser options that we may update + """ + parser = build_parser(line) + defaults = parser.get_default_values() + defaults.index_url = None + if finder: + # `finder.format_control` will be updated during parsing + defaults.format_control = finder.format_control + args_str, options_str = break_args_options(line) + if sys.version_info < (2, 7, 3): + # Prior to 2.7.3, shlex cannot deal with unicode entries + options_str = options_str.encode('utf8') + opts, _ = parser.parse_args(shlex.split(options_str), defaults) + + # preserve for the nested code path + line_comes_from = '%s %s (line %s)' % ( + '-c' if constraint else '-r', filename, line_number, + ) + + # yield a line requirement + if args_str: + isolated = options.isolated_mode if options else False + if options: + cmdoptions.check_install_build_global(options, opts) + # get the options that apply to requirements + req_options = {} + for dest in SUPPORTED_OPTIONS_REQ_DEST: + if dest in opts.__dict__ and opts.__dict__[dest]: + req_options[dest] = opts.__dict__[dest] + yield install_req_from_line( + args_str, line_comes_from, constraint=constraint, + isolated=isolated, options=req_options, wheel_cache=wheel_cache + ) + + # yield an editable requirement + elif opts.editables: + isolated = options.isolated_mode if options else False + yield install_req_from_editable( + opts.editables[0], comes_from=line_comes_from, + constraint=constraint, isolated=isolated, wheel_cache=wheel_cache + ) + + # parse a nested requirements file + elif opts.requirements or opts.constraints: + if opts.requirements: + req_path = opts.requirements[0] + nested_constraint = False + else: + req_path = opts.constraints[0] + nested_constraint = True + # original file is over http + if SCHEME_RE.search(filename): + # do a url join so relative paths work + req_path = urllib_parse.urljoin(filename, req_path) + # original file and nested file are paths + elif not SCHEME_RE.search(req_path): + # do a join so relative paths work + req_path = os.path.join(os.path.dirname(filename), req_path) + # TODO: Why not use `comes_from='-r {} (line {})'` here as well? + parser = parse_requirements( + req_path, finder, comes_from, options, session, + constraint=nested_constraint, wheel_cache=wheel_cache + ) + for req in parser: + yield req + + # percolate hash-checking option upward + elif opts.require_hashes: + options.require_hashes = opts.require_hashes + + # set finder options + elif finder: + if opts.index_url: + finder.index_urls = [opts.index_url] + if opts.no_index is True: + finder.index_urls = [] + if opts.extra_index_urls: + finder.index_urls.extend(opts.extra_index_urls) + if opts.find_links: + # FIXME: it would be nice to keep track of the source + # of the find_links: support a find-links local path + # relative to a requirements file. + value = opts.find_links[0] + req_dir = os.path.dirname(os.path.abspath(filename)) + relative_to_reqs_file = os.path.join(req_dir, value) + if os.path.exists(relative_to_reqs_file): + value = relative_to_reqs_file + finder.find_links.append(value) + if opts.pre: + finder.allow_all_prereleases = True + if opts.process_dependency_links: + finder.process_dependency_links = True + if opts.trusted_hosts: + finder.secure_origins.extend( + ("*", host, "*") for host in opts.trusted_hosts) + + +def break_args_options(line): + """Break up the line into an args and options string. We only want to shlex + (and then optparse) the options, not the args. args can contain markers + which are corrupted by shlex. + """ + tokens = line.split(' ') + args = [] + options = tokens[:] + for token in tokens: + if token.startswith('-') or token.startswith('--'): + break + else: + args.append(token) + options.pop(0) + return ' '.join(args), ' '.join(options) + + +def build_parser(line): + """ + Return a parser for parsing requirement lines + """ + parser = optparse.OptionParser(add_help_option=False) + + option_factories = SUPPORTED_OPTIONS + SUPPORTED_OPTIONS_REQ + for option_factory in option_factories: + option = option_factory() + parser.add_option(option) + + # By default optparse sys.exits on parsing errors. We want to wrap + # that in our own exception. + def parser_exit(self, msg): + # add offending line + msg = 'Invalid requirement: %s\n%s' % (line, msg) + raise RequirementsFileParseError(msg) + parser.exit = parser_exit + + return parser + + +def join_lines(lines_enum): + """Joins a line ending in '\' with the previous line (except when following + comments). The joined line takes on the index of the first line. + """ + primary_line_number = None + new_line = [] + for line_number, line in lines_enum: + if not line.endswith('\\') or COMMENT_RE.match(line): + if COMMENT_RE.match(line): + # this ensures comments are always matched later + line = ' ' + line + if new_line: + new_line.append(line) + yield primary_line_number, ''.join(new_line) + new_line = [] + else: + yield line_number, line + else: + if not new_line: + primary_line_number = line_number + new_line.append(line.strip('\\')) + + # last line contains \ + if new_line: + yield primary_line_number, ''.join(new_line) + + # TODO: handle space after '\'. + + +def ignore_comments(lines_enum): + """ + Strips comments and filter empty lines. + """ + for line_number, line in lines_enum: + line = COMMENT_RE.sub('', line) + line = line.strip() + if line: + yield line_number, line + + +def skip_regex(lines_enum, options): + """ + Skip lines that match '--skip-requirements-regex' pattern + + Note: the regex pattern is only built once + """ + skip_regex = options.skip_requirements_regex if options else None + if skip_regex: + pattern = re.compile(skip_regex) + lines_enum = filterfalse(lambda e: pattern.search(e[1]), lines_enum) + return lines_enum + + +def expand_env_variables(lines_enum): + """Replace all environment variables that can be retrieved via `os.getenv`. + + The only allowed format for environment variables defined in the + requirement file is `${MY_VARIABLE_1}` to ensure two things: + + 1. Strings that contain a `$` aren't accidentally (partially) expanded. + 2. Ensure consistency across platforms for requirement files. + + These points are the result of a discusssion on the `github pull + request #3514 `_. + + Valid characters in variable names follow the `POSIX standard + `_ and are limited + to uppercase letter, digits and the `_` (underscore). + """ + for line_number, line in lines_enum: + for env_var, var_name in ENV_VAR_RE.findall(line): + value = os.getenv(var_name) + if not value: + continue + + line = line.replace(env_var, value) + + yield line_number, line diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/req_install.py b/env/lib/python3.7/site-packages/pip/_internal/req/req_install.py new file mode 100644 index 0000000..c2624fe --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/req/req_install.py @@ -0,0 +1,860 @@ +from __future__ import absolute_import + +import logging +import os +import shutil +import sys +import sysconfig +import zipfile +from distutils.util import change_root + +from pip._vendor import pkg_resources, six +from pip._vendor.packaging.requirements import Requirement +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.packaging.version import Version +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.pep517.wrappers import Pep517HookCaller + +from pip._internal import wheel +from pip._internal.build_env import NoOpBuildEnvironment +from pip._internal.exceptions import InstallationError +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, running_under_virtualenv, +) +from pip._internal.models.link import Link +from pip._internal.pyproject import load_pyproject_toml +from pip._internal.req.req_uninstall import UninstallPathSet +from pip._internal.utils.compat import native_str +from pip._internal.utils.hashes import Hashes +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + _make_build_dir, ask_path_exists, backup_dir, call_subprocess, + display_path, dist_in_site_packages, dist_in_usersite, ensure_dir, + get_installed_version, rmtree, +) +from pip._internal.utils.packaging import get_metadata +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.ui import open_spinner +from pip._internal.vcs import vcs +from pip._internal.wheel import move_wheel_files + +logger = logging.getLogger(__name__) + + +class InstallRequirement(object): + """ + Represents something that may be installed later on, may have information + about where to fetch the relavant requirement and also contains logic for + installing the said requirement. + """ + + def __init__(self, req, comes_from, source_dir=None, editable=False, + link=None, update=True, markers=None, + isolated=False, options=None, wheel_cache=None, + constraint=False, extras=()): + assert req is None or isinstance(req, Requirement), req + self.req = req + self.comes_from = comes_from + self.constraint = constraint + if source_dir is not None: + self.source_dir = os.path.normpath(os.path.abspath(source_dir)) + else: + self.source_dir = None + self.editable = editable + + self._wheel_cache = wheel_cache + if link is not None: + self.link = self.original_link = link + else: + self.link = self.original_link = req and req.url and Link(req.url) + + if extras: + self.extras = extras + elif req: + self.extras = { + pkg_resources.safe_extra(extra) for extra in req.extras + } + else: + self.extras = set() + if markers is not None: + self.markers = markers + else: + self.markers = req and req.marker + self._egg_info_path = None + # This holds the pkg_resources.Distribution object if this requirement + # is already available: + self.satisfied_by = None + # This hold the pkg_resources.Distribution object if this requirement + # conflicts with another installed distribution: + self.conflicts_with = None + # Temporary build location + self._temp_build_dir = TempDirectory(kind="req-build") + # Used to store the global directory where the _temp_build_dir should + # have been created. Cf _correct_build_location method. + self._ideal_build_dir = None + # True if the editable should be updated: + self.update = update + # Set to True after successful installation + self.install_succeeded = None + # UninstallPathSet of uninstalled distribution (for possible rollback) + self.uninstalled_pathset = None + self.options = options if options else {} + # Set to True after successful preparation of this requirement + self.prepared = False + self.is_direct = False + + self.isolated = isolated + self.build_env = NoOpBuildEnvironment() + + # The static build requirements (from pyproject.toml) + self.pyproject_requires = None + + # Build requirements that we will check are available + # TODO: We don't do this for --no-build-isolation. Should we? + self.requirements_to_check = [] + + # The PEP 517 backend we should use to build the project + self.pep517_backend = None + + # Are we using PEP 517 for this requirement? + # After pyproject.toml has been loaded, the only valid values are True + # and False. Before loading, None is valid (meaning "use the default"). + # Setting an explicit value before loading pyproject.toml is supported, + # but after loading this flag should be treated as read only. + self.use_pep517 = None + + def __str__(self): + if self.req: + s = str(self.req) + if self.link: + s += ' from %s' % self.link.url + elif self.link: + s = self.link.url + else: + s = '' + if self.satisfied_by is not None: + s += ' in %s' % display_path(self.satisfied_by.location) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += ' (from %s)' % comes_from + return s + + def __repr__(self): + return '<%s object: %s editable=%r>' % ( + self.__class__.__name__, str(self), self.editable) + + def populate_link(self, finder, upgrade, require_hashes): + """Ensure that if a link can be found for this, that it is found. + + Note that self.link may still be None - if Upgrade is False and the + requirement is already installed. + + If require_hashes is True, don't use the wheel cache, because cached + wheels, always built locally, have different hashes than the files + downloaded from the index server and thus throw false hash mismatches. + Furthermore, cached wheels at present have undeterministic contents due + to file modification times. + """ + if self.link is None: + self.link = finder.find_requirement(self, upgrade) + if self._wheel_cache is not None and not require_hashes: + old_link = self.link + self.link = self._wheel_cache.get(self.link, self.name) + if old_link != self.link: + logger.debug('Using cached wheel link: %s', self.link) + + # Things that are valid for all kinds of requirements? + @property + def name(self): + if self.req is None: + return None + return native_str(pkg_resources.safe_name(self.req.name)) + + @property + def specifier(self): + return self.req.specifier + + @property + def is_pinned(self): + """Return whether I am pinned to an exact version. + + For example, some-package==1.2 is pinned; some-package>1.2 is not. + """ + specifiers = self.specifier + return (len(specifiers) == 1 and + next(iter(specifiers)).operator in {'==', '==='}) + + @property + def installed_version(self): + return get_installed_version(self.name) + + def match_markers(self, extras_requested=None): + if not extras_requested: + # Provide an extra to safely evaluate the markers + # without matching any extra + extras_requested = ('',) + if self.markers is not None: + return any( + self.markers.evaluate({'extra': extra}) + for extra in extras_requested) + else: + return True + + @property + def has_hash_options(self): + """Return whether any known-good hashes are specified as options. + + These activate --require-hashes mode; hashes specified as part of a + URL do not. + + """ + return bool(self.options.get('hashes', {})) + + def hashes(self, trust_internet=True): + """Return a hash-comparer that considers my option- and URL-based + hashes to be known-good. + + Hashes in URLs--ones embedded in the requirements file, not ones + downloaded from an index server--are almost peers with ones from + flags. They satisfy --require-hashes (whether it was implicitly or + explicitly activated) but do not activate it. md5 and sha224 are not + allowed in flags, which should nudge people toward good algos. We + always OR all hashes together, even ones from URLs. + + :param trust_internet: Whether to trust URL-based (#md5=...) hashes + downloaded from the internet, as by populate_link() + + """ + good_hashes = self.options.get('hashes', {}).copy() + link = self.link if trust_internet else self.original_link + if link and link.hash: + good_hashes.setdefault(link.hash_name, []).append(link.hash) + return Hashes(good_hashes) + + def from_path(self): + """Format a nice indicator to show where this "comes from" + """ + if self.req is None: + return None + s = str(self.req) + if self.comes_from: + if isinstance(self.comes_from, six.string_types): + comes_from = self.comes_from + else: + comes_from = self.comes_from.from_path() + if comes_from: + s += '->' + comes_from + return s + + def build_location(self, build_dir): + assert build_dir is not None + if self._temp_build_dir.path is not None: + return self._temp_build_dir.path + if self.req is None: + # for requirement via a path to a directory: the name of the + # package is not available yet so we create a temp directory + # Once run_egg_info will have run, we'll be able + # to fix it via _correct_build_location + # Some systems have /tmp as a symlink which confuses custom + # builds (such as numpy). Thus, we ensure that the real path + # is returned. + self._temp_build_dir.create() + self._ideal_build_dir = build_dir + + return self._temp_build_dir.path + if self.editable: + name = self.name.lower() + else: + name = self.name + # FIXME: Is there a better place to create the build_dir? (hg and bzr + # need this) + if not os.path.exists(build_dir): + logger.debug('Creating directory %s', build_dir) + _make_build_dir(build_dir) + return os.path.join(build_dir, name) + + def _correct_build_location(self): + """Move self._temp_build_dir to self._ideal_build_dir/self.req.name + + For some requirements (e.g. a path to a directory), the name of the + package is not available until we run egg_info, so the build_location + will return a temporary directory and store the _ideal_build_dir. + + This is only called by self.run_egg_info to fix the temporary build + directory. + """ + if self.source_dir is not None: + return + assert self.req is not None + assert self._temp_build_dir.path + assert self._ideal_build_dir.path + old_location = self._temp_build_dir.path + self._temp_build_dir.path = None + + new_location = self.build_location(self._ideal_build_dir) + if os.path.exists(new_location): + raise InstallationError( + 'A package already exists in %s; please remove it to continue' + % display_path(new_location)) + logger.debug( + 'Moving package %s from %s to new location %s', + self, display_path(old_location), display_path(new_location), + ) + shutil.move(old_location, new_location) + self._temp_build_dir.path = new_location + self._ideal_build_dir = None + self.source_dir = os.path.normpath(os.path.abspath(new_location)) + self._egg_info_path = None + + def remove_temporary_source(self): + """Remove the source files from this requirement, if they are marked + for deletion""" + if self.source_dir and os.path.exists( + os.path.join(self.source_dir, PIP_DELETE_MARKER_FILENAME)): + logger.debug('Removing source in %s', self.source_dir) + rmtree(self.source_dir) + self.source_dir = None + self._temp_build_dir.cleanup() + self.build_env.cleanup() + + def check_if_exists(self, use_user_site): + """Find an installed distribution that satisfies or conflicts + with this requirement, and set self.satisfied_by or + self.conflicts_with appropriately. + """ + if self.req is None: + return False + try: + # get_distribution() will resolve the entire list of requirements + # anyway, and we've already determined that we need the requirement + # in question, so strip the marker so that we don't try to + # evaluate it. + no_marker = Requirement(str(self.req)) + no_marker.marker = None + self.satisfied_by = pkg_resources.get_distribution(str(no_marker)) + if self.editable and self.satisfied_by: + self.conflicts_with = self.satisfied_by + # when installing editables, nothing pre-existing should ever + # satisfy + self.satisfied_by = None + return True + except pkg_resources.DistributionNotFound: + return False + except pkg_resources.VersionConflict: + existing_dist = pkg_resources.get_distribution( + self.req.name + ) + if use_user_site: + if dist_in_usersite(existing_dist): + self.conflicts_with = existing_dist + elif (running_under_virtualenv() and + dist_in_site_packages(existing_dist)): + raise InstallationError( + "Will not install to the user site because it will " + "lack sys.path precedence to %s in %s" % + (existing_dist.project_name, existing_dist.location) + ) + else: + self.conflicts_with = existing_dist + return True + + # Things valid for wheels + @property + def is_wheel(self): + return self.link and self.link.is_wheel + + def move_wheel_files(self, wheeldir, root=None, home=None, prefix=None, + warn_script_location=True, use_user_site=False, + pycompile=True): + move_wheel_files( + self.name, self.req, wheeldir, + user=use_user_site, + home=home, + root=root, + prefix=prefix, + pycompile=pycompile, + isolated=self.isolated, + warn_script_location=warn_script_location, + ) + + # Things valid for sdists + @property + def setup_py_dir(self): + return os.path.join( + self.source_dir, + self.link and self.link.subdirectory_fragment or '') + + @property + def setup_py(self): + assert self.source_dir, "No source dir for %s" % self + + setup_py = os.path.join(self.setup_py_dir, 'setup.py') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(setup_py, six.text_type): + setup_py = setup_py.encode(sys.getfilesystemencoding()) + + return setup_py + + @property + def pyproject_toml(self): + assert self.source_dir, "No source dir for %s" % self + + pp_toml = os.path.join(self.setup_py_dir, 'pyproject.toml') + + # Python2 __file__ should not be unicode + if six.PY2 and isinstance(pp_toml, six.text_type): + pp_toml = pp_toml.encode(sys.getfilesystemencoding()) + + return pp_toml + + def load_pyproject_toml(self): + """Load the pyproject.toml file. + + After calling this routine, all of the attributes related to PEP 517 + processing for this requirement have been set. In particular, the + use_pep517 attribute can be used to determine whether we should + follow the PEP 517 or legacy (setup.py) code path. + """ + pep517_data = load_pyproject_toml( + self.use_pep517, + self.pyproject_toml, + self.setup_py, + str(self) + ) + + if pep517_data is None: + self.use_pep517 = False + else: + self.use_pep517 = True + requires, backend, check = pep517_data + self.requirements_to_check = check + self.pyproject_requires = requires + self.pep517_backend = Pep517HookCaller(self.setup_py_dir, backend) + + def run_egg_info(self): + assert self.source_dir + if self.name: + logger.debug( + 'Running setup.py (path:%s) egg_info for package %s', + self.setup_py, self.name, + ) + else: + logger.debug( + 'Running setup.py (path:%s) egg_info for package from %s', + self.setup_py, self.link, + ) + + with indent_log(): + script = SETUPTOOLS_SHIM % self.setup_py + base_cmd = [sys.executable, '-c', script] + if self.isolated: + base_cmd += ["--no-user-cfg"] + egg_info_cmd = base_cmd + ['egg_info'] + # We can't put the .egg-info files at the root, because then the + # source code will be mistaken for an installed egg, causing + # problems + if self.editable: + egg_base_option = [] + else: + egg_info_dir = os.path.join(self.setup_py_dir, 'pip-egg-info') + ensure_dir(egg_info_dir) + egg_base_option = ['--egg-base', 'pip-egg-info'] + with self.build_env: + call_subprocess( + egg_info_cmd + egg_base_option, + cwd=self.setup_py_dir, + show_stdout=False, + command_desc='python setup.py egg_info') + + if not self.req: + if isinstance(parse_version(self.metadata["Version"]), Version): + op = "==" + else: + op = "===" + self.req = Requirement( + "".join([ + self.metadata["Name"], + op, + self.metadata["Version"], + ]) + ) + self._correct_build_location() + else: + metadata_name = canonicalize_name(self.metadata["Name"]) + if canonicalize_name(self.req.name) != metadata_name: + logger.warning( + 'Running setup.py (path:%s) egg_info for package %s ' + 'produced metadata for project name %s. Fix your ' + '#egg=%s fragments.', + self.setup_py, self.name, metadata_name, self.name + ) + self.req = Requirement(metadata_name) + + @property + def egg_info_path(self): + if self._egg_info_path is None: + if self.editable: + base = self.source_dir + else: + base = os.path.join(self.setup_py_dir, 'pip-egg-info') + filenames = os.listdir(base) + if self.editable: + filenames = [] + for root, dirs, files in os.walk(base): + for dir in vcs.dirnames: + if dir in dirs: + dirs.remove(dir) + # Iterate over a copy of ``dirs``, since mutating + # a list while iterating over it can cause trouble. + # (See https://github.com/pypa/pip/pull/462.) + for dir in list(dirs): + # Don't search in anything that looks like a virtualenv + # environment + if ( + os.path.lexists( + os.path.join(root, dir, 'bin', 'python') + ) or + os.path.exists( + os.path.join( + root, dir, 'Scripts', 'Python.exe' + ) + )): + dirs.remove(dir) + # Also don't search through tests + elif dir == 'test' or dir == 'tests': + dirs.remove(dir) + filenames.extend([os.path.join(root, dir) + for dir in dirs]) + filenames = [f for f in filenames if f.endswith('.egg-info')] + + if not filenames: + raise InstallationError( + "Files/directories not found in %s" % base + ) + # if we have more than one match, we pick the toplevel one. This + # can easily be the case if there is a dist folder which contains + # an extracted tarball for testing purposes. + if len(filenames) > 1: + filenames.sort( + key=lambda x: x.count(os.path.sep) + + (os.path.altsep and x.count(os.path.altsep) or 0) + ) + self._egg_info_path = os.path.join(base, filenames[0]) + return self._egg_info_path + + @property + def metadata(self): + if not hasattr(self, '_metadata'): + self._metadata = get_metadata(self.get_dist()) + + return self._metadata + + def get_dist(self): + """Return a pkg_resources.Distribution built from self.egg_info_path""" + egg_info = self.egg_info_path.rstrip(os.path.sep) + base_dir = os.path.dirname(egg_info) + metadata = pkg_resources.PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + return pkg_resources.Distribution( + os.path.dirname(egg_info), + project_name=dist_name, + metadata=metadata, + ) + + def assert_source_matches_version(self): + assert self.source_dir + version = self.metadata['version'] + if self.req.specifier and version not in self.req.specifier: + logger.warning( + 'Requested %s, but installing version %s', + self, + version, + ) + else: + logger.debug( + 'Source in %s has version %s, which satisfies requirement %s', + display_path(self.source_dir), + version, + self, + ) + + # For both source distributions and editables + def ensure_has_source_dir(self, parent_dir): + """Ensure that a source_dir is set. + + This will create a temporary build dir if the name of the requirement + isn't known yet. + + :param parent_dir: The ideal pip parent_dir for the source_dir. + Generally src_dir for editables and build_dir for sdists. + :return: self.source_dir + """ + if self.source_dir is None: + self.source_dir = self.build_location(parent_dir) + return self.source_dir + + # For editable installations + def install_editable(self, install_options, + global_options=(), prefix=None): + logger.info('Running setup.py develop for %s', self.name) + + if self.isolated: + global_options = list(global_options) + ["--no-user-cfg"] + + if prefix: + prefix_param = ['--prefix={}'.format(prefix)] + install_options = list(install_options) + prefix_param + + with indent_log(): + # FIXME: should we do --install-headers here too? + with self.build_env: + call_subprocess( + [ + sys.executable, + '-c', + SETUPTOOLS_SHIM % self.setup_py + ] + + list(global_options) + + ['develop', '--no-deps'] + + list(install_options), + + cwd=self.setup_py_dir, + show_stdout=False, + ) + + self.install_succeeded = True + + def update_editable(self, obtain=True): + if not self.link: + logger.debug( + "Cannot update repository at %s; repository location is " + "unknown", + self.source_dir, + ) + return + assert self.editable + assert self.source_dir + if self.link.scheme == 'file': + # Static paths don't get updated + return + assert '+' in self.link.url, "bad url: %r" % self.link.url + if not self.update: + return + vc_type, url = self.link.url.split('+', 1) + backend = vcs.get_backend(vc_type) + if backend: + vcs_backend = backend(self.link.url) + if obtain: + vcs_backend.obtain(self.source_dir) + else: + vcs_backend.export(self.source_dir) + else: + assert 0, ( + 'Unexpected version control type (in %s): %s' + % (self.link, vc_type)) + + # Top-level Actions + def uninstall(self, auto_confirm=False, verbose=False, + use_user_site=False): + """ + Uninstall the distribution currently satisfying this requirement. + + Prompts before removing or modifying files unless + ``auto_confirm`` is True. + + Refuses to delete or modify files outside of ``sys.prefix`` - + thus uninstallation within a virtual environment can only + modify that virtual environment, even if the virtualenv is + linked to global site-packages. + + """ + if not self.check_if_exists(use_user_site): + logger.warning("Skipping %s as it is not installed.", self.name) + return + dist = self.satisfied_by or self.conflicts_with + + uninstalled_pathset = UninstallPathSet.from_dist(dist) + uninstalled_pathset.remove(auto_confirm, verbose) + return uninstalled_pathset + + def _clean_zip_name(self, name, prefix): # only used by archive. + assert name.startswith(prefix + os.path.sep), ( + "name %r doesn't start with prefix %r" % (name, prefix) + ) + name = name[len(prefix) + 1:] + name = name.replace(os.path.sep, '/') + return name + + # TODO: Investigate if this should be kept in InstallRequirement + # Seems to be used only when VCS + downloads + def archive(self, build_dir): + assert self.source_dir + create_archive = True + archive_name = '%s-%s.zip' % (self.name, self.metadata["version"]) + archive_path = os.path.join(build_dir, archive_name) + if os.path.exists(archive_path): + response = ask_path_exists( + 'The file %s exists. (i)gnore, (w)ipe, (b)ackup, (a)bort ' % + display_path(archive_path), ('i', 'w', 'b', 'a')) + if response == 'i': + create_archive = False + elif response == 'w': + logger.warning('Deleting %s', display_path(archive_path)) + os.remove(archive_path) + elif response == 'b': + dest_file = backup_dir(archive_path) + logger.warning( + 'Backing up %s to %s', + display_path(archive_path), + display_path(dest_file), + ) + shutil.move(archive_path, dest_file) + elif response == 'a': + sys.exit(-1) + if create_archive: + zip = zipfile.ZipFile( + archive_path, 'w', zipfile.ZIP_DEFLATED, + allowZip64=True + ) + dir = os.path.normcase(os.path.abspath(self.setup_py_dir)) + for dirpath, dirnames, filenames in os.walk(dir): + if 'pip-egg-info' in dirnames: + dirnames.remove('pip-egg-info') + for dirname in dirnames: + dirname = os.path.join(dirpath, dirname) + name = self._clean_zip_name(dirname, dir) + zipdir = zipfile.ZipInfo(self.name + '/' + name + '/') + zipdir.external_attr = 0x1ED << 16 # 0o755 + zip.writestr(zipdir, '') + for filename in filenames: + if filename == PIP_DELETE_MARKER_FILENAME: + continue + filename = os.path.join(dirpath, filename) + name = self._clean_zip_name(filename, dir) + zip.write(filename, self.name + '/' + name) + zip.close() + logger.info('Saved %s', display_path(archive_path)) + + def install(self, install_options, global_options=None, root=None, + home=None, prefix=None, warn_script_location=True, + use_user_site=False, pycompile=True): + global_options = global_options if global_options is not None else [] + if self.editable: + self.install_editable( + install_options, global_options, prefix=prefix, + ) + return + if self.is_wheel: + version = wheel.wheel_version(self.source_dir) + wheel.check_compatibility(version, self.name) + + self.move_wheel_files( + self.source_dir, root=root, prefix=prefix, home=home, + warn_script_location=warn_script_location, + use_user_site=use_user_site, pycompile=pycompile, + ) + self.install_succeeded = True + return + + # Extend the list of global and install options passed on to + # the setup.py call with the ones from the requirements file. + # Options specified in requirements file override those + # specified on the command line, since the last option given + # to setup.py is the one that is used. + global_options = list(global_options) + \ + self.options.get('global_options', []) + install_options = list(install_options) + \ + self.options.get('install_options', []) + + if self.isolated: + global_options = global_options + ["--no-user-cfg"] + + with TempDirectory(kind="record") as temp_dir: + record_filename = os.path.join(temp_dir.path, 'install-record.txt') + install_args = self.get_install_args( + global_options, record_filename, root, prefix, pycompile, + ) + msg = 'Running setup.py install for %s' % (self.name,) + with open_spinner(msg) as spinner: + with indent_log(): + with self.build_env: + call_subprocess( + install_args + install_options, + cwd=self.setup_py_dir, + show_stdout=False, + spinner=spinner, + ) + + if not os.path.exists(record_filename): + logger.debug('Record file %s not found', record_filename) + return + self.install_succeeded = True + + def prepend_root(path): + if root is None or not os.path.isabs(path): + return path + else: + return change_root(root, path) + + with open(record_filename) as f: + for line in f: + directory = os.path.dirname(line) + if directory.endswith('.egg-info'): + egg_info_dir = prepend_root(directory) + break + else: + logger.warning( + 'Could not find .egg-info directory in install record' + ' for %s', + self, + ) + # FIXME: put the record somewhere + # FIXME: should this be an error? + return + new_lines = [] + with open(record_filename) as f: + for line in f: + filename = line.strip() + if os.path.isdir(filename): + filename += os.path.sep + new_lines.append( + os.path.relpath(prepend_root(filename), egg_info_dir) + ) + new_lines.sort() + ensure_dir(egg_info_dir) + inst_files_path = os.path.join(egg_info_dir, 'installed-files.txt') + with open(inst_files_path, 'w') as f: + f.write('\n'.join(new_lines) + '\n') + + def get_install_args(self, global_options, record_filename, root, prefix, + pycompile): + install_args = [sys.executable, "-u"] + install_args.append('-c') + install_args.append(SETUPTOOLS_SHIM % self.setup_py) + install_args += list(global_options) + \ + ['install', '--record', record_filename] + install_args += ['--single-version-externally-managed'] + + if root is not None: + install_args += ['--root', root] + if prefix is not None: + install_args += ['--prefix', prefix] + + if pycompile: + install_args += ["--compile"] + else: + install_args += ["--no-compile"] + + if running_under_virtualenv(): + py_ver_str = 'python' + sysconfig.get_python_version() + install_args += ['--install-headers', + os.path.join(sys.prefix, 'include', 'site', + py_ver_str, self.name)] + + return install_args diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/req_set.py b/env/lib/python3.7/site-packages/pip/_internal/req/req_set.py new file mode 100644 index 0000000..b198317 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/req/req_set.py @@ -0,0 +1,181 @@ +from __future__ import absolute_import + +import logging +from collections import OrderedDict + +from pip._internal.exceptions import InstallationError +from pip._internal.utils.logging import indent_log +from pip._internal.wheel import Wheel + +logger = logging.getLogger(__name__) + + +class RequirementSet(object): + + def __init__(self, require_hashes=False, check_supported_wheels=True): + """Create a RequirementSet. + """ + + self.requirements = OrderedDict() + self.require_hashes = require_hashes + self.check_supported_wheels = check_supported_wheels + + # Mapping of alias: real_name + self.requirement_aliases = {} + self.unnamed_requirements = [] + self.successfully_downloaded = [] + self.reqs_to_cleanup = [] + + def __str__(self): + reqs = [req for req in self.requirements.values() + if not req.comes_from] + reqs.sort(key=lambda req: req.name.lower()) + return ' '.join([str(req.req) for req in reqs]) + + def __repr__(self): + reqs = [req for req in self.requirements.values()] + reqs.sort(key=lambda req: req.name.lower()) + reqs_str = ', '.join([str(req.req) for req in reqs]) + return ('<%s object; %d requirement(s): %s>' + % (self.__class__.__name__, len(reqs), reqs_str)) + + def add_requirement(self, install_req, parent_req_name=None, + extras_requested=None): + """Add install_req as a requirement to install. + + :param parent_req_name: The name of the requirement that needed this + added. The name is used because when multiple unnamed requirements + resolve to the same name, we could otherwise end up with dependency + links that point outside the Requirements set. parent_req must + already be added. Note that None implies that this is a user + supplied requirement, vs an inferred one. + :param extras_requested: an iterable of extras used to evaluate the + environment markers. + :return: Additional requirements to scan. That is either [] if + the requirement is not applicable, or [install_req] if the + requirement is applicable and has just been added. + """ + name = install_req.name + + # If the markers do not match, ignore this requirement. + if not install_req.match_markers(extras_requested): + logger.info( + "Ignoring %s: markers '%s' don't match your environment", + name, install_req.markers, + ) + return [], None + + # If the wheel is not supported, raise an error. + # Should check this after filtering out based on environment markers to + # allow specifying different wheels based on the environment/OS, in a + # single requirements file. + if install_req.link and install_req.link.is_wheel: + wheel = Wheel(install_req.link.filename) + if self.check_supported_wheels and not wheel.supported(): + raise InstallationError( + "%s is not a supported wheel on this platform." % + wheel.filename + ) + + # This next bit is really a sanity check. + assert install_req.is_direct == (parent_req_name is None), ( + "a direct req shouldn't have a parent and also, " + "a non direct req should have a parent" + ) + + # Unnamed requirements are scanned again and the requirement won't be + # added as a dependency until after scanning. + if not name: + # url or path requirement w/o an egg fragment + self.unnamed_requirements.append(install_req) + return [install_req], None + + try: + existing_req = self.get_requirement(name) + except KeyError: + existing_req = None + + has_conflicting_requirement = ( + parent_req_name is None and + existing_req and + not existing_req.constraint and + existing_req.extras == install_req.extras and + existing_req.req.specifier != install_req.req.specifier + ) + if has_conflicting_requirement: + raise InstallationError( + "Double requirement given: %s (already in %s, name=%r)" + % (install_req, existing_req, name) + ) + + # When no existing requirement exists, add the requirement as a + # dependency and it will be scanned again after. + if not existing_req: + self.requirements[name] = install_req + # FIXME: what about other normalizations? E.g., _ vs. -? + if name.lower() != name: + self.requirement_aliases[name.lower()] = name + # We'd want to rescan this requirements later + return [install_req], install_req + + # Assume there's no need to scan, and that we've already + # encountered this for scanning. + if install_req.constraint or not existing_req.constraint: + return [], existing_req + + does_not_satisfy_constraint = ( + install_req.link and + not ( + existing_req.link and + install_req.link.path == existing_req.link.path + ) + ) + if does_not_satisfy_constraint: + self.reqs_to_cleanup.append(install_req) + raise InstallationError( + "Could not satisfy constraints for '%s': " + "installation from path or url cannot be " + "constrained to a version" % name, + ) + # If we're now installing a constraint, mark the existing + # object for real installation. + existing_req.constraint = False + existing_req.extras = tuple(sorted( + set(existing_req.extras) | set(install_req.extras) + )) + logger.debug( + "Setting %s extras to: %s", + existing_req, existing_req.extras, + ) + # Return the existing requirement for addition to the parent and + # scanning again. + return [existing_req], existing_req + + def has_requirement(self, project_name): + name = project_name.lower() + if (name in self.requirements and + not self.requirements[name].constraint or + name in self.requirement_aliases and + not self.requirements[self.requirement_aliases[name]].constraint): + return True + return False + + @property + def has_requirements(self): + return list(req for req in self.requirements.values() if not + req.constraint) or self.unnamed_requirements + + def get_requirement(self, project_name): + for name in project_name, project_name.lower(): + if name in self.requirements: + return self.requirements[name] + if name in self.requirement_aliases: + return self.requirements[self.requirement_aliases[name]] + raise KeyError("No project with the name %r" % project_name) + + def cleanup_files(self): + """Clean up files, remove builds.""" + logger.debug('Cleaning up...') + with indent_log(): + for req in self.reqs_to_cleanup: + req.remove_temporary_source() diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py b/env/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py new file mode 100644 index 0000000..0a86f4c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/req/req_tracker.py @@ -0,0 +1,76 @@ +from __future__ import absolute_import + +import contextlib +import errno +import hashlib +import logging +import os + +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +class RequirementTracker(object): + + def __init__(self): + self._root = os.environ.get('PIP_REQ_TRACKER') + if self._root is None: + self._temp_dir = TempDirectory(delete=False, kind='req-tracker') + self._temp_dir.create() + self._root = os.environ['PIP_REQ_TRACKER'] = self._temp_dir.path + logger.debug('Created requirements tracker %r', self._root) + else: + self._temp_dir = None + logger.debug('Re-using requirements tracker %r', self._root) + self._entries = set() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.cleanup() + + def _entry_path(self, link): + hashed = hashlib.sha224(link.url_without_fragment.encode()).hexdigest() + return os.path.join(self._root, hashed) + + def add(self, req): + link = req.link + info = str(req) + entry_path = self._entry_path(link) + try: + with open(entry_path) as fp: + # Error, these's already a build in progress. + raise LookupError('%s is already being built: %s' + % (link, fp.read())) + except IOError as e: + if e.errno != errno.ENOENT: + raise + assert req not in self._entries + with open(entry_path, 'w') as fp: + fp.write(info) + self._entries.add(req) + logger.debug('Added %s to build tracker %r', req, self._root) + + def remove(self, req): + link = req.link + self._entries.remove(req) + os.unlink(self._entry_path(link)) + logger.debug('Removed %s from build tracker %r', req, self._root) + + def cleanup(self): + for req in set(self._entries): + self.remove(req) + remove = self._temp_dir is not None + if remove: + self._temp_dir.cleanup() + logger.debug('%s build tracker %r', + 'Removed' if remove else 'Cleaned', + self._root) + + @contextlib.contextmanager + def track(self, req): + self.add(req) + yield + self.remove(req) diff --git a/env/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py b/env/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py new file mode 100644 index 0000000..a7d8230 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/req/req_uninstall.py @@ -0,0 +1,460 @@ +from __future__ import absolute_import + +import csv +import functools +import logging +import os +import sys +import sysconfig + +from pip._vendor import pkg_resources + +from pip._internal.exceptions import UninstallationError +from pip._internal.locations import bin_py, bin_user +from pip._internal.utils.compat import WINDOWS, cache_from_source, uses_pycache +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + FakeFile, ask, dist_in_usersite, dist_is_local, egg_link_path, is_local, + normalize_path, renames, +) +from pip._internal.utils.temp_dir import TempDirectory + +logger = logging.getLogger(__name__) + + +def _script_names(dist, script_name, is_gui): + """Create the fully qualified name of the files created by + {console,gui}_scripts for the given ``dist``. + Returns the list of file names + """ + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + exe_name = os.path.join(bin_dir, script_name) + paths_to_remove = [exe_name] + if WINDOWS: + paths_to_remove.append(exe_name + '.exe') + paths_to_remove.append(exe_name + '.exe.manifest') + if is_gui: + paths_to_remove.append(exe_name + '-script.pyw') + else: + paths_to_remove.append(exe_name + '-script.py') + return paths_to_remove + + +def _unique(fn): + @functools.wraps(fn) + def unique(*args, **kw): + seen = set() + for item in fn(*args, **kw): + if item not in seen: + seen.add(item) + yield item + return unique + + +@_unique +def uninstallation_paths(dist): + """ + Yield all the uninstallation paths for dist based on RECORD-without-.py[co] + + Yield paths to all the files in RECORD. For each .py file in RECORD, add + the .pyc and .pyo in the same directory. + + UninstallPathSet.add() takes care of the __pycache__ .py[co]. + """ + r = csv.reader(FakeFile(dist.get_metadata_lines('RECORD'))) + for row in r: + path = os.path.join(dist.location, row[0]) + yield path + if path.endswith('.py'): + dn, fn = os.path.split(path) + base = fn[:-3] + path = os.path.join(dn, base + '.pyc') + yield path + path = os.path.join(dn, base + '.pyo') + yield path + + +def compact(paths): + """Compact a path set to contain the minimal number of paths + necessary to contain all paths in the set. If /a/path/ and + /a/path/to/a/file.txt are both in the set, leave only the + shorter path.""" + + sep = os.path.sep + short_paths = set() + for path in sorted(paths, key=len): + should_add = any( + path.startswith(shortpath.rstrip("*")) and + path[len(shortpath.rstrip("*").rstrip(sep))] == sep + for shortpath in short_paths + ) + if not should_add: + short_paths.add(path) + return short_paths + + +def compress_for_output_listing(paths): + """Returns a tuple of 2 sets of which paths to display to user + + The first set contains paths that would be deleted. Files of a package + are not added and the top-level directory of the package has a '*' added + at the end - to signify that all it's contents are removed. + + The second set contains files that would have been skipped in the above + folders. + """ + + will_remove = list(paths) + will_skip = set() + + # Determine folders and files + folders = set() + files = set() + for path in will_remove: + if path.endswith(".pyc"): + continue + if path.endswith("__init__.py") or ".dist-info" in path: + folders.add(os.path.dirname(path)) + files.add(path) + + _normcased_files = set(map(os.path.normcase, files)) + + folders = compact(folders) + + # This walks the tree using os.walk to not miss extra folders + # that might get added. + for folder in folders: + for dirpath, _, dirfiles in os.walk(folder): + for fname in dirfiles: + if fname.endswith(".pyc"): + continue + + file_ = os.path.join(dirpath, fname) + if (os.path.isfile(file_) and + os.path.normcase(file_) not in _normcased_files): + # We are skipping this file. Add it to the set. + will_skip.add(file_) + + will_remove = files | { + os.path.join(folder, "*") for folder in folders + } + + return will_remove, will_skip + + +class UninstallPathSet(object): + """A set of file paths to be removed in the uninstallation of a + requirement.""" + def __init__(self, dist): + self.paths = set() + self._refuse = set() + self.pth = {} + self.dist = dist + self.save_dir = TempDirectory(kind="uninstall") + self._moved_paths = [] + + def _permitted(self, path): + """ + Return True if the given path is one we are permitted to + remove/modify, False otherwise. + + """ + return is_local(path) + + def add(self, path): + head, tail = os.path.split(path) + + # we normalize the head to resolve parent directory symlinks, but not + # the tail, since we only want to uninstall symlinks, not their targets + path = os.path.join(normalize_path(head), os.path.normcase(tail)) + + if not os.path.exists(path): + return + if self._permitted(path): + self.paths.add(path) + else: + self._refuse.add(path) + + # __pycache__ files can show up after 'installed-files.txt' is created, + # due to imports + if os.path.splitext(path)[1] == '.py' and uses_pycache: + self.add(cache_from_source(path)) + + def add_pth(self, pth_file, entry): + pth_file = normalize_path(pth_file) + if self._permitted(pth_file): + if pth_file not in self.pth: + self.pth[pth_file] = UninstallPthEntries(pth_file) + self.pth[pth_file].add(entry) + else: + self._refuse.add(pth_file) + + def _stash(self, path): + return os.path.join( + self.save_dir.path, os.path.splitdrive(path)[1].lstrip(os.path.sep) + ) + + def remove(self, auto_confirm=False, verbose=False): + """Remove paths in ``self.paths`` with confirmation (unless + ``auto_confirm`` is True).""" + + if not self.paths: + logger.info( + "Can't uninstall '%s'. No files were found to uninstall.", + self.dist.project_name, + ) + return + + dist_name_version = ( + self.dist.project_name + "-" + self.dist.version + ) + logger.info('Uninstalling %s:', dist_name_version) + + with indent_log(): + if auto_confirm or self._allowed_to_proceed(verbose): + self.save_dir.create() + + for path in sorted(compact(self.paths)): + new_path = self._stash(path) + logger.debug('Removing file or directory %s', path) + self._moved_paths.append(path) + renames(path, new_path) + for pth in self.pth.values(): + pth.remove() + + logger.info('Successfully uninstalled %s', dist_name_version) + + def _allowed_to_proceed(self, verbose): + """Display which files would be deleted and prompt for confirmation + """ + + def _display(msg, paths): + if not paths: + return + + logger.info(msg) + with indent_log(): + for path in sorted(compact(paths)): + logger.info(path) + + if not verbose: + will_remove, will_skip = compress_for_output_listing(self.paths) + else: + # In verbose mode, display all the files that are going to be + # deleted. + will_remove = list(self.paths) + will_skip = set() + + _display('Would remove:', will_remove) + _display('Would not remove (might be manually added):', will_skip) + _display('Would not remove (outside of prefix):', self._refuse) + + return ask('Proceed (y/n)? ', ('y', 'n')) == 'y' + + def rollback(self): + """Rollback the changes previously made by remove().""" + if self.save_dir.path is None: + logger.error( + "Can't roll back %s; was not uninstalled", + self.dist.project_name, + ) + return False + logger.info('Rolling back uninstall of %s', self.dist.project_name) + for path in self._moved_paths: + tmp_path = self._stash(path) + logger.debug('Replacing %s', path) + renames(tmp_path, path) + for pth in self.pth.values(): + pth.rollback() + + def commit(self): + """Remove temporary save dir: rollback will no longer be possible.""" + self.save_dir.cleanup() + self._moved_paths = [] + + @classmethod + def from_dist(cls, dist): + dist_path = normalize_path(dist.location) + if not dist_is_local(dist): + logger.info( + "Not uninstalling %s at %s, outside environment %s", + dist.key, + dist_path, + sys.prefix, + ) + return cls(dist) + + if dist_path in {p for p in {sysconfig.get_path("stdlib"), + sysconfig.get_path("platstdlib")} + if p}: + logger.info( + "Not uninstalling %s at %s, as it is in the standard library.", + dist.key, + dist_path, + ) + return cls(dist) + + paths_to_remove = cls(dist) + develop_egg_link = egg_link_path(dist) + develop_egg_link_egg_info = '{}.egg-info'.format( + pkg_resources.to_filename(dist.project_name)) + egg_info_exists = dist.egg_info and os.path.exists(dist.egg_info) + # Special case for distutils installed package + distutils_egg_info = getattr(dist._provider, 'path', None) + + # Uninstall cases order do matter as in the case of 2 installs of the + # same package, pip needs to uninstall the currently detected version + if (egg_info_exists and dist.egg_info.endswith('.egg-info') and + not dist.egg_info.endswith(develop_egg_link_egg_info)): + # if dist.egg_info.endswith(develop_egg_link_egg_info), we + # are in fact in the develop_egg_link case + paths_to_remove.add(dist.egg_info) + if dist.has_metadata('installed-files.txt'): + for installed_file in dist.get_metadata( + 'installed-files.txt').splitlines(): + path = os.path.normpath( + os.path.join(dist.egg_info, installed_file) + ) + paths_to_remove.add(path) + # FIXME: need a test for this elif block + # occurs with --single-version-externally-managed/--record outside + # of pip + elif dist.has_metadata('top_level.txt'): + if dist.has_metadata('namespace_packages.txt'): + namespaces = dist.get_metadata('namespace_packages.txt') + else: + namespaces = [] + for top_level_pkg in [ + p for p + in dist.get_metadata('top_level.txt').splitlines() + if p and p not in namespaces]: + path = os.path.join(dist.location, top_level_pkg) + paths_to_remove.add(path) + paths_to_remove.add(path + '.py') + paths_to_remove.add(path + '.pyc') + paths_to_remove.add(path + '.pyo') + + elif distutils_egg_info: + raise UninstallationError( + "Cannot uninstall {!r}. It is a distutils installed project " + "and thus we cannot accurately determine which files belong " + "to it which would lead to only a partial uninstall.".format( + dist.project_name, + ) + ) + + elif dist.location.endswith('.egg'): + # package installed by easy_install + # We cannot match on dist.egg_name because it can slightly vary + # i.e. setuptools-0.6c11-py2.6.egg vs setuptools-0.6rc11-py2.6.egg + paths_to_remove.add(dist.location) + easy_install_egg = os.path.split(dist.location)[1] + easy_install_pth = os.path.join(os.path.dirname(dist.location), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, './' + easy_install_egg) + + elif egg_info_exists and dist.egg_info.endswith('.dist-info'): + for path in uninstallation_paths(dist): + paths_to_remove.add(path) + + elif develop_egg_link: + # develop egg + with open(develop_egg_link, 'r') as fh: + link_pointer = os.path.normcase(fh.readline().strip()) + assert (link_pointer == dist.location), ( + 'Egg-link %s does not match installed location of %s ' + '(at %s)' % (link_pointer, dist.project_name, dist.location) + ) + paths_to_remove.add(develop_egg_link) + easy_install_pth = os.path.join(os.path.dirname(develop_egg_link), + 'easy-install.pth') + paths_to_remove.add_pth(easy_install_pth, dist.location) + + else: + logger.debug( + 'Not sure how to uninstall: %s - Check: %s', + dist, dist.location, + ) + + # find distutils scripts= scripts + if dist.has_metadata('scripts') and dist.metadata_isdir('scripts'): + for script in dist.metadata_listdir('scripts'): + if dist_in_usersite(dist): + bin_dir = bin_user + else: + bin_dir = bin_py + paths_to_remove.add(os.path.join(bin_dir, script)) + if WINDOWS: + paths_to_remove.add(os.path.join(bin_dir, script) + '.bat') + + # find console_scripts + _scripts_to_remove = [] + console_scripts = dist.get_entry_map(group='console_scripts') + for name in console_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, False)) + # find gui_scripts + gui_scripts = dist.get_entry_map(group='gui_scripts') + for name in gui_scripts.keys(): + _scripts_to_remove.extend(_script_names(dist, name, True)) + + for s in _scripts_to_remove: + paths_to_remove.add(s) + + return paths_to_remove + + +class UninstallPthEntries(object): + def __init__(self, pth_file): + if not os.path.isfile(pth_file): + raise UninstallationError( + "Cannot remove entries from nonexistent file %s" % pth_file + ) + self.file = pth_file + self.entries = set() + self._saved_lines = None + + def add(self, entry): + entry = os.path.normcase(entry) + # On Windows, os.path.normcase converts the entry to use + # backslashes. This is correct for entries that describe absolute + # paths outside of site-packages, but all the others use forward + # slashes. + if WINDOWS and not os.path.splitdrive(entry)[0]: + entry = entry.replace('\\', '/') + self.entries.add(entry) + + def remove(self): + logger.debug('Removing pth entries from %s:', self.file) + with open(self.file, 'rb') as fh: + # windows uses '\r\n' with py3k, but uses '\n' with py2.x + lines = fh.readlines() + self._saved_lines = lines + if any(b'\r\n' in line for line in lines): + endline = '\r\n' + else: + endline = '\n' + # handle missing trailing newline + if lines and not lines[-1].endswith(endline.encode("utf-8")): + lines[-1] = lines[-1] + endline.encode("utf-8") + for entry in self.entries: + try: + logger.debug('Removing entry: %s', entry) + lines.remove((entry + endline).encode("utf-8")) + except ValueError: + pass + with open(self.file, 'wb') as fh: + fh.writelines(lines) + + def rollback(self): + if self._saved_lines is None: + logger.error( + 'Cannot roll back changes to %s, none were made', self.file + ) + return False + logger.debug('Rolling %s back to previous state', self.file) + with open(self.file, 'wb') as fh: + fh.writelines(self._saved_lines) + return True diff --git a/env/lib/python3.7/site-packages/pip/_internal/resolve.py b/env/lib/python3.7/site-packages/pip/_internal/resolve.py new file mode 100644 index 0000000..2d9f1c5 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/resolve.py @@ -0,0 +1,353 @@ +"""Dependency Resolution + +The dependency resolution in pip is performed as follows: + +for top-level requirements: + a. only one spec allowed per project, regardless of conflicts or not. + otherwise a "double requirement" exception is raised + b. they override sub-dependency requirements. +for sub-dependencies + a. "first found, wins" (where the order is breadth first) +""" + +import logging +from collections import defaultdict +from itertools import chain + +from pip._internal.exceptions import ( + BestVersionAlreadyInstalled, DistributionNotFound, HashError, HashErrors, + UnsupportedPythonVersion, +) +from pip._internal.req.constructors import install_req_from_req +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import dist_in_usersite, ensure_dir +from pip._internal.utils.packaging import check_dist_requires_python + +logger = logging.getLogger(__name__) + + +class Resolver(object): + """Resolves which packages need to be installed/uninstalled to perform \ + the requested operation without breaking the requirements of any package. + """ + + _allowed_strategies = {"eager", "only-if-needed", "to-satisfy-only"} + + def __init__(self, preparer, session, finder, wheel_cache, use_user_site, + ignore_dependencies, ignore_installed, ignore_requires_python, + force_reinstall, isolated, upgrade_strategy): + super(Resolver, self).__init__() + assert upgrade_strategy in self._allowed_strategies + + self.preparer = preparer + self.finder = finder + self.session = session + + # NOTE: This would eventually be replaced with a cache that can give + # information about both sdist and wheels transparently. + self.wheel_cache = wheel_cache + + self.require_hashes = None # This is set in resolve + + self.upgrade_strategy = upgrade_strategy + self.force_reinstall = force_reinstall + self.isolated = isolated + self.ignore_dependencies = ignore_dependencies + self.ignore_installed = ignore_installed + self.ignore_requires_python = ignore_requires_python + self.use_user_site = use_user_site + + self._discovered_dependencies = defaultdict(list) + + def resolve(self, requirement_set): + """Resolve what operations need to be done + + As a side-effect of this method, the packages (and their dependencies) + are downloaded, unpacked and prepared for installation. This + preparation is done by ``pip.operations.prepare``. + + Once PyPI has static dependency metadata available, it would be + possible to move the preparation to become a step separated from + dependency resolution. + """ + # make the wheelhouse + if self.preparer.wheel_download_dir: + ensure_dir(self.preparer.wheel_download_dir) + + # If any top-level requirement has a hash specified, enter + # hash-checking mode, which requires hashes from all. + root_reqs = ( + requirement_set.unnamed_requirements + + list(requirement_set.requirements.values()) + ) + self.require_hashes = ( + requirement_set.require_hashes or + any(req.has_hash_options for req in root_reqs) + ) + + # Display where finder is looking for packages + locations = self.finder.get_formatted_locations() + if locations: + logger.info(locations) + + # Actually prepare the files, and collect any exceptions. Most hash + # exceptions cannot be checked ahead of time, because + # req.populate_link() needs to be called before we can make decisions + # based on link type. + discovered_reqs = [] + hash_errors = HashErrors() + for req in chain(root_reqs, discovered_reqs): + try: + discovered_reqs.extend( + self._resolve_one(requirement_set, req) + ) + except HashError as exc: + exc.req = req + hash_errors.append(exc) + + if hash_errors: + raise hash_errors + + def _is_upgrade_allowed(self, req): + if self.upgrade_strategy == "to-satisfy-only": + return False + elif self.upgrade_strategy == "eager": + return True + else: + assert self.upgrade_strategy == "only-if-needed" + return req.is_direct + + def _set_req_to_reinstall(self, req): + """ + Set a requirement to be installed. + """ + # Don't uninstall the conflict if doing a user install and the + # conflict is not a user install. + if not self.use_user_site or dist_in_usersite(req.satisfied_by): + req.conflicts_with = req.satisfied_by + req.satisfied_by = None + + # XXX: Stop passing requirement_set for options + def _check_skip_installed(self, req_to_install): + """Check if req_to_install should be skipped. + + This will check if the req is installed, and whether we should upgrade + or reinstall it, taking into account all the relevant user options. + + After calling this req_to_install will only have satisfied_by set to + None if the req_to_install is to be upgraded/reinstalled etc. Any + other value will be a dist recording the current thing installed that + satisfies the requirement. + + Note that for vcs urls and the like we can't assess skipping in this + routine - we simply identify that we need to pull the thing down, + then later on it is pulled down and introspected to assess upgrade/ + reinstalls etc. + + :return: A text reason for why it was skipped, or None. + """ + if self.ignore_installed: + return None + + req_to_install.check_if_exists(self.use_user_site) + if not req_to_install.satisfied_by: + return None + + if self.force_reinstall: + self._set_req_to_reinstall(req_to_install) + return None + + if not self._is_upgrade_allowed(req_to_install): + if self.upgrade_strategy == "only-if-needed": + return 'already satisfied, skipping upgrade' + return 'already satisfied' + + # Check for the possibility of an upgrade. For link-based + # requirements we have to pull the tree down and inspect to assess + # the version #, so it's handled way down. + if not req_to_install.link: + try: + self.finder.find_requirement(req_to_install, upgrade=True) + except BestVersionAlreadyInstalled: + # Then the best version is installed. + return 'already up-to-date' + except DistributionNotFound: + # No distribution found, so we squash the error. It will + # be raised later when we re-try later to do the install. + # Why don't we just raise here? + pass + + self._set_req_to_reinstall(req_to_install) + return None + + def _get_abstract_dist_for(self, req): + """Takes a InstallRequirement and returns a single AbstractDist \ + representing a prepared variant of the same. + """ + assert self.require_hashes is not None, ( + "require_hashes should have been set in Resolver.resolve()" + ) + + if req.editable: + return self.preparer.prepare_editable_requirement( + req, self.require_hashes, self.use_user_site, self.finder, + ) + + # satisfied_by is only evaluated by calling _check_skip_installed, + # so it must be None here. + assert req.satisfied_by is None + skip_reason = self._check_skip_installed(req) + + if req.satisfied_by: + return self.preparer.prepare_installed_requirement( + req, self.require_hashes, skip_reason + ) + + upgrade_allowed = self._is_upgrade_allowed(req) + abstract_dist = self.preparer.prepare_linked_requirement( + req, self.session, self.finder, upgrade_allowed, + self.require_hashes + ) + + # NOTE + # The following portion is for determining if a certain package is + # going to be re-installed/upgraded or not and reporting to the user. + # This should probably get cleaned up in a future refactor. + + # req.req is only avail after unpack for URL + # pkgs repeat check_if_exists to uninstall-on-upgrade + # (#14) + if not self.ignore_installed: + req.check_if_exists(self.use_user_site) + + if req.satisfied_by: + should_modify = ( + self.upgrade_strategy != "to-satisfy-only" or + self.force_reinstall or + self.ignore_installed or + req.link.scheme == 'file' + ) + if should_modify: + self._set_req_to_reinstall(req) + else: + logger.info( + 'Requirement already satisfied (use --upgrade to upgrade):' + ' %s', req, + ) + + return abstract_dist + + def _resolve_one(self, requirement_set, req_to_install): + """Prepare a single requirements file. + + :return: A list of additional InstallRequirements to also install. + """ + # Tell user what we are doing for this requirement: + # obtain (editable), skipping, processing (local url), collecting + # (remote url or package name) + if req_to_install.constraint or req_to_install.prepared: + return [] + + req_to_install.prepared = True + + # register tmp src for cleanup in case something goes wrong + requirement_set.reqs_to_cleanup.append(req_to_install) + + abstract_dist = self._get_abstract_dist_for(req_to_install) + + # Parse and return dependencies + dist = abstract_dist.dist(self.finder) + try: + check_dist_requires_python(dist) + except UnsupportedPythonVersion as err: + if self.ignore_requires_python: + logger.warning(err.args[0]) + else: + raise + + more_reqs = [] + + def add_req(subreq, extras_requested): + sub_install_req = install_req_from_req( + str(subreq), + req_to_install, + isolated=self.isolated, + wheel_cache=self.wheel_cache, + ) + parent_req_name = req_to_install.name + to_scan_again, add_to_parent = requirement_set.add_requirement( + sub_install_req, + parent_req_name=parent_req_name, + extras_requested=extras_requested, + ) + if parent_req_name and add_to_parent: + self._discovered_dependencies[parent_req_name].append( + add_to_parent + ) + more_reqs.extend(to_scan_again) + + with indent_log(): + # We add req_to_install before its dependencies, so that we + # can refer to it when adding dependencies. + if not requirement_set.has_requirement(req_to_install.name): + # 'unnamed' requirements will get added here + req_to_install.is_direct = True + requirement_set.add_requirement( + req_to_install, parent_req_name=None, + ) + + if not self.ignore_dependencies: + if req_to_install.extras: + logger.debug( + "Installing extra requirements: %r", + ','.join(req_to_install.extras), + ) + missing_requested = sorted( + set(req_to_install.extras) - set(dist.extras) + ) + for missing in missing_requested: + logger.warning( + '%s does not provide the extra \'%s\'', + dist, missing + ) + + available_requested = sorted( + set(dist.extras) & set(req_to_install.extras) + ) + for subreq in dist.requires(available_requested): + add_req(subreq, extras_requested=available_requested) + + if not req_to_install.editable and not req_to_install.satisfied_by: + # XXX: --no-install leads this to report 'Successfully + # downloaded' for only non-editable reqs, even though we took + # action on them. + requirement_set.successfully_downloaded.append(req_to_install) + + return more_reqs + + def get_installation_order(self, req_set): + """Create the installation order. + + The installation order is topological - requirements are installed + before the requiring thing. We break cycles at an arbitrary point, + and make no other guarantees. + """ + # The current implementation, which we may change at any point + # installs the user specified things in the order given, except when + # dependencies must come earlier to achieve topological order. + order = [] + ordered_reqs = set() + + def schedule(req): + if req.satisfied_by or req in ordered_reqs: + return + if req.constraint: + return + ordered_reqs.add(req) + for dep in self._discovered_dependencies[req.name]: + schedule(dep) + order.append(req) + + for install_req in req_set.requirements.values(): + schedule(install_req) + return order diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__init__.py b/env/lib/python3.7/site-packages/pip/_internal/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a69d93bdf9b34357593245f54ef643d2f08d0a8e GIT binary patch literal 148 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd%;%m4r;EF)(C literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/appdirs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..042096c8b3aae24ddff826227e6c53698237dce7 GIT binary patch literal 7869 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 IX(eI*9uV`8%K!iX literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..471db17f311d3f5f1ff86cb17f5c840018ff5f76 GIT binary patch literal 5939 zcmd5=&2!wwl?NJ_84NfYeVC?1NwyKo`WTxUN|r1uidON5qzw~gs5R|KK{*gF zF~GQi5jm`(Ys+*hxg_P?<6f5B%O+KuRQ`?JbLw1Dm6LMVKftH`y~fOlQsT;WheQMD zkM~|by!Y#0_XkIgxCVaye_r@>^)MeuZh~mF;NSS<9-77mws#{?6Falyv!@y;Z^SPIbP#O zc%2{Zy8gT<@4qY-4ov@~sBWC%$2LpyfBA8L5i(E2r~7C8Gp3Q;&>GJAXGg9$yMa2` za2htevgv+h%F`1oEdNZQOPt}>X4PNR5?|UZq0bFI@4uRy;xF@sFAe`SVefnVq5X67 zWM7%-UqxkOi8nTxf0@6@k6=_&EDML%_t;lVy8JC(N8Odg;Y-C6x7Lit^3D&|@?odr z<-IWXc+}|#nR!t%c@#+DJKj2 zq7%hJ9jD&8ko_nL;~t&SA=){<7HeKnW`rtBNckJ%>+dY*{lW4e8eEQ&EDz)O za(kakkt}`}h*g!RYJi?XF0~_CVgbMRpWE*tz_olL9W< zDHlN}Y2J?0b{J=OnzNCTJouD`{>|hv61so_ldHpPnA)EC;?%5Ea(ttg(M_4_l6+AV zi}Z9F#XsSi*rxuW5)LH`Q~#OpAKS4%-9EqF(n4p7+J8^coo9*~WmS@4(iN%%uOcZd zk#J>YqfFH%$pyD|Qe|(XQ3A0iG1jlja4T3J?+sMmU2|g__Hm~eEoW=k*$HoTw)fpGq7HYpgYVHCsAsn;q^gjI@j2v0 z=us6&5A$5gbM#g&Ol{c8rmrgBqDnJUM+;vDQ}r+AY6bo79e=jT z%rcv=*Gz}mcz0RD)cAkDO%O%DDbnk#c^wtNB_lWYn0yu4!8m2lDb5nctph~xm_XQW zO+JIFOcoARrceeXTgt^^N!XjTffhyfUxiqJ!cE*HLFy zZ6Cqm%)a@;z5~FTwu()yYFP3%I!Xcrc>~2i(*3XKQ|M+cw9gQQ^wL79b^jC(IXuJ3 zH#c%~pOK$7EL`>n#sTmIbs9}J%DW8D6+#v;x(n#x>{rLeftfu-y-QEjC#eBHAY}oo z=ohBO2PH#2V(u8V2$YORLun|}S*g{H65yBZXQ{}D(t=0Rh4<4*O+PQij zFnDOpcf3bY9BV|71>nMo8fB+0Yt&Sw7iN@#ilv#d0fmWjR)df3uC^ZhSkelpN*x4q zP64jTTB#kUnNT*FsLD}BzE`&HQkhHw@kjZnScfZz7#t0JG3Kl2@pD|+2^2<+V!me9 ztQxCZOy{XOaqscR_gZT!tF2(|ll%8q9^YGQQ{U;2n1+r_it~I*j^qQp9a5$lgeDJl zH2gO%O&$yrSg2{}lsi5rn@~Z^K86R)`=DXZAWnz;x1MKiq<@VB&!gxf8GllvMVA|k z#=o)8Yz#0pEz(v^IY+tBd&p8U@@w~Y3|daHcIUSwk_;&uJ8%AdzI%v(&4xkQ4>9PF z;OAZNKU1;BvqUE?7A`&ID|pC3aVf#EaGQV`izAig(%8fkE1tN;?VqtlO)oIR(oSDT z}%9e{Q;oGtXqgsu!{4Va#oTsamlVE??4l%n5 zc7r4ei*kuF`D$@{Ta~C5Z*+V6P^{@pBiVnzmFWWxRs)Njhd0}(n*C|3 zBmMNb%)D*nC9w6M7HqxX-Bu+>f6_@zjNc=o4^Xf6E1?wb{ zJ>Z#|8zuvsAn5Z2zZ9iybaFplS^e;zafq?ztLnY&wipnBXq4plNgxG>WjQ`aHk@k#+PRQQ8G;3d?x2&7F(1FifLZpN%|Q6Anu%=JOEpvS@I_|7Sky?^;0mPnI|v}V(MkQoyD4bpZ>3^N)Yh09R##Z=?t-3 z6hRdM3Si-Rq&`9Ux_lg_o`l;s^Pe+sZr%PRa&T2_4h%;=r~Sj%k&PZ*!kC`=zem?Sh-&h-3G(y^AjLIs^RYveChgKt7Q<=pP4d>D&6 z^d+(cg>4>VMO^BV)ffYftK-8SLrHb>wu3E2*>{gstaAz*4pkq77UAt~BSdLpW-OB#~g|gda literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/deprecation.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5effa139c622f3c5273825f2d93a0171bf4873de GIT binary patch literal 2522 zcmaJ?TW=dh7~R=jUt&9#rY)CBtw!Q%ppJwPNEJc}Y1LMMTa`lT3TYX8#?B^t>&$FY z2ls{a5q<;hBR_;k{=mNS)W5(JXJ$8!OC{Fw+~=F~o%!Z`U#_lp9DKp=@Ba8#*Kz(f zozu@pV;g_NpQ0?*cd;G_2AM$!zLcCHb(l6J6S+s(L>bb~H& zL|6WRb*;FUtOl#eTChf(n+|XDm8TA05$h*ju)#fcj&JY|?>;5LChzgpr%rI5pW|zM z9U~XG_pQ_4JRWv-Xp-?F7F6#sO`{}_MIutIsLrxDN~fr)NZAN01XDA5#AJ$LMcF7T zH02_fV$5`urE1W50S}!%Dc9LZWpSZJ2!ol_LyR?YCY3;=8-|BMD(nbDbT_|wc=utr zd+WyTSK+4@Vl4w)kgzODFkO9_3e~RB0B+SI0-w zbYDOE#0=Vh7^PZBz}qTx6sxTzE(ZBbwqa}2;B-;6iS3V@Xq&H9|94TV0L9$r&cTX& zTO&kJf3KanGbeL*?#=yq;{@T5eyquyX!pdG*R}Tyq4JzOY0jI^8gu74!Tjc{d$?n0 z86IB(=D`B*UYl0Od`!n-;9*L>0!*;IAdL|f(cy85{gTP zAVZ@=+W5I-)9rX2(sNxR&D=|&(ZGOZ^nEn6vrjnq;x6}o^N6E8Fxxf^@B7Tt4ef;B z9Q^phvc<)O6|ugLfNZin7byoX?bBc{d&<5HV8@MHGUOVLD7#BYEu1A^Y%E!aUaLbW ztnG!B-ygz)GEw5V8-ANKiKJ+cjb50~gv!DpjSeSs=XK|aKZkxGM6MuYyk`iK=j1ap z>eL6A{|%nG}5y{r$g~ch((rOvu)GAFCJ?=w0fKx z+EQaq?+IEcn6BjHXm5t0NWE;6?lHBnG!h~`L%|32ae2(fR=Hk1Qx%9*K+V$sITzx` z%;l!gvO}>r?Iqs~+8G_Q)IhEdo@OaTZrM>dRLdL9CKT_E@=QQZU-b$k6fviGOQ0pm z4h5%CTA4MJ-D8o$M#Nht6^*Q|_Y@r$QbM2?hk&dp*amc*0ce?|!e|=UU3g&*uMC?f zEzT&qZMrlqk`cCpA9EdAvhhJ>P17R_5f^kQD1+!5&nHDpE!}jI$;BDw7ERWmlPKkI zCd8EdLGGb2|hI5%6MqJQ|5PXDV>S)=CkJwDn97=v&I*7VxF7P?%%#Myhew|SLhDSGoUls zZRuPJPJezfIDTtS>s(#i+L}gsuNV!+S+bSSa%R=v!ckkt1Nty4Y*1LommHR2$|Scr z)LcG5!RQN<4f?LUfU4{uvy2a7aVTQwXA^EDOqZV0QhH{7y}sNuESq)52%|I!v}`@768xDWS0YT!3Ilq{-!nOGe_rMPFAT@ZBoQC^ W1Wvm>w}+NbHoOhr_dDm>-G2eczsQaN literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/encoding.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7332aa1380c11a85daae169882fc9ab8f43cdbd GIT binary patch literal 1084 zcmZuwO;6h}7`Br%P16DrLla{=M4B|Uo1lYE2u))`Ks!xhFzpMefT}ch+kl${+Z7a* z)3(cg#MbV%zvSyqoOj!4Z(NEv%#q*c{mSF#b(GDiDHp-2|9EtWErfoj!DKn$Y`_*A z3_%1lR39U*V;viHL!((YDLS@@(J}xt#MEdLOJkN~G&;oAm?K$@E^%5$J6q3FV^|=$ z5w1@Wm*l^o`ZU4sQK@hR=b~L@^<-;JWxy`4UN{;Sn{?tas!Np>ov5r#O5ian?gB#) zlQ3!@JYPRL6pxDsi-%`RM^8!tPT66>*eC;g3%2+P=KQHd+vuoxXk6k;V}OQufJd0y z10;=Bd4p&ObpHj6Z@JG1Dr%zj0{}Ok$Bt8Wa1(;5C^U+5;1~ zZoFZ3gou^0k?d%E+Jv{ZkAT&b&M-%u5l+5KcbFfc^vqK3;@eh-1}C2HHT#kZPe=|k zdaam4YIE<6Cu1*&Ij4bSeUDHHjwd_RqtW;}T-SqD^BHUUzys|p4tz$J+EgZ-wkW(y zCe20Y6SU;9@PvACLZf2IizDxCUv}cCvim2!O83eD%TxC%H9GlFWqc8YVXah97RY+9 zTp@if#aSpj%49TBHld&hKB7oiC{@0?yS2CddiPc1T~*nF`aI|;yUpWXB9uMWsOJ7B zQkkMJ)GU+;ZTUSWC+bUho0O99aJccO#4><&n?IJsC1lo)9f1eU(yVy=kkg+!QJ+x7#4v wsq*v}SJ@!$CLyDI1|qFP4}Qzs*BV}QW71>vW%>=pJQxS-$Gk=z6-?Ls2bTdUz5oCK literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/filesystem.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9039fbf51746618b05136768f6b76773801394e3 GIT binary patch literal 615 zcmYjNy^hmB5T4m}Vq^J2imUDc5H8MXC=nnKG)Q-aPYSXSk>y=3PW*Sfo4bqTG#mvz z4?t4#O50NL3RKMc05R75?96z+Z|3FEQ3xd2w@2^4a)2N1@mClHFG%%cG6DovkllM6 zJgZpEGmap*@IFK42}~g#{iJR zpe9uM^?YXPZq}9EY1wF#SJi28bJ?uS)f1N-bWt`&(!6T6F=eG^AInPWtv0ewx~-iS zOIfV%@7>-sQu#DipO66_qQ^W8F=7#C7~urR7_cc*Q>w-zH6myIRws^Cc0z#3Kd@u~ jONzFp;;`-T*TDKe^U#e5p4P3{RPvd-o^~q-gcI@Kv*(uu literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/glibc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5ea7c42c8acf5318617a613bfde909d464691d47 GIT binary patch literal 1506 zcmZ8h-EJH;6t+FHv(rhF{tzkz2rMX7M&t)o+_Wm?r!+z+T2&2F(Y9zbvAw&Koxj?i zhD4LA@CG~p$tCZ=llYb^UV$sl@g|~)SN8FKwm%=A@0|H=c{w4_#(&&<_16+1f8(Ev z#$fUdbn^oYl1N&TijFD8IV;(ic^ixaZ^LmY0~!8C#sfK!5!gr$Wej#GugL^#EZHte zm;M1Zl2Ugg-!o0wS(O!4+h{uyxPUEy9z%Zu-8_TAl2a<_89gS4Nl*6KF?~Vm)sWa= zp6E47@F(dm`5AWZhds>(Jv|}E%tk%4!xLt9dUgue0|V>PiQwqLb7ebS8$K6|`;?SB$|1F(M|ZrQ5cYKwNmvz6tBIGEP^_Vt$t`kocFRl3g0 ztUR$(B+gfg1Yl^_aY8nJ{XOy2@rpj6nx^X?_Xd|61= zlQVW4^ntl+*=ZnIPwo&Ko-vRs*d=z*2d9w?&*%y5>6|s&=g7b#Y(4;~qS4XawXdH& zs`C9tKYsbe#)DrzPhV|%sHp#kj=p;OYpaA+@`|Jfg`M&HTr`knwW_V*o@%qg)9ZZN z*oXWxv+V{R27`DybWAJ6teCm@AlEen1eC^^TY28qwy4yL1?&O{s~b#p)3s@+SK#?> zMXT3cp_R-Qw97zSR9%&MdPgg-*B9X^2tgLGtgorW|52|{|C>W=^s zSf1EW0t~+oJ+4@Sx!*&1&SQNW>%!6=LJu_oK~LFeJ6)*fdD1|C0EhI4IN)7Z9ea0{ zzfl>6FSo^BsTMBYhn)r!gn(NyxTQaaxj+CLg^mthc8c^+rrs$iLK*aAf)*T1!=vAS z(udqOTq?*=2$JGs7*C2`4FKRjE2eU%VfN+v`rA2O4 zwf690w)$}8r zU4$v}VPg7IK;YAnWZ9&HFObSIje*iAp~hmNF2oP$2a5m{sXVqgx>%F literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/hashes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..15bfa4e0ee1c680e42a1b1543fa6c881e8188e4f GIT binary patch literal 3283 zcmbVOUvnF`5eM#$$0J2bvZ}ao(&-@Wv<}mVnm9=(aXg*4wiDaaDvj*e$xSln(*Y#U zygw8GMiPg5u{4vXPCr7W$G-Oi^mE*6p7Is?)Lnq2Bv+Zt`T{|a{= zkxu&uIG=QAwG!{BG8=0VrTM6odaL7BjZ_N>Emu{5nN>YH9YT(xP8oc~B@FXIZS%vbZN@DdCtUDPkTagK;rbm9GZzjrad(zVCkUp83B2 z&W!{`nm;ZOA45|Qp%WyeoPcp?=<+Mv<=!z3JznGfF$rs^IDCDpc38LSh5>K$Wf*Vp z6}}4Jrcr#Y@=;i!Ch={yC*#pbNTvs|W;^3FcXGw8`KZ7Uf>C(JxERtc99pcq?&0czp1S?G7|`6}l zfLokNX;$Kxg9c`e>z`T*{ z^^50v_dOgmEdm*YEaGf)tkXZgwaJQgLU%s5uv8tGFno-q z{tZM*4xRmnnoP-adPMJ%Z*CpB2W#3nai{JnojOzZ7I{i`S3ROVUF$i+rhG^VzS`$> z>Ru&B^acG2IKG7TlX$r~XOv)JQUQuaTiIj}cS5$4_DGWNGT)YJ)O&^5PC+g&9oDkz^4AZ~~_x+BECQ zGG`cA@eUvkd}|{FsD*=gtmCf56Z&vFPL*J2y?OMpw8skAlbKjN$2xiCi^3q&V90>w zCi|V*>a--LA-N1)RY&2nbfNwJe z8Dk!xQ6Kp$>@XD0B$X)7htMpf>7+dqz*^$Mk!WsnB$^zcLNtXV=_!Uhoy0#5m6-L? zOl)N75YVynTqOEuApz8Q15TC==w>Qa9`5{-PSx5)>mkc6SYuW6C)X~uF>)=`MeE`* zMqLI3SQv8Mk@Jt%p#!Qz#G=}tlWp=P6g|v&Ta_bsF!hupQOMuInvQE>Ob57u>OBXJgENQG{0&?Qp8J$HRZ5Hd7*J%%s>Ir&8pim<8Pf&5|-7!ClE*0a%=9FpymWsT)voevP>>n53v+ zGZbhho5}2AKM^CmATc#4_po@U8tXT10@BG@8ovMpGzvD82{q;ra^yUBwA&{sgxKHD ziq9K&%i=oT6?*1!BiOTN7O2mjvEg1U`&~c{dSa{NRW&t+JCNLjU*p}X{mJbopKU*Q zd@s6x`_cUwzTleBh@vEml>!u;ITrEo6otY_BHrZc1rPjxeMdG_;tn*m4jtwPO|Ov? z=hRf{c@}mhUIpYk*j_YZyJfG2{%09*Js7RIgfr8&Ws=RusIHU6t;e z(rF8@si?1-`T6asy8wo=Rmd0tBfoly(Ok2-fZW8Sbz`Wi{pj)bXIq~d$K88W`L<@5 j__7YZBsQzymJRwpVL~(k+HwMC-C1{Ao>yzSt2h4#S&}B@ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/logging.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4bd18924cd4b4b61cb8f547d947c6828eb4b2749 GIT binary patch literal 5316 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/models.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/models.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..604cb69d15f6a45203e3fffffbdf1da91ff00252 GIT binary patch literal 1897 zcmbtU&2G~`5Z<+&d*UqUJ%BO#<5+FZEtqpCe1gouz35{i&ku4mh9aBO#X3$)6u zeGlNsEBVTaSK!2qos>3eX;3zr8QVLV{pQ=5*=;uK3|H^#qYtYdV?XI-vhbblpqKy^ zupR>rPRx7!1p^nna|WJt&fK00&Rf>5oZf$DRjjO%COAlS0P;X3Dme^>DahE=e_<5X zjYv<~=IOdK^!2fKx?Y6FN{$Se2xWAut>@e$OD%(m>_w7PGM0_lfS>V6 zdR{*?eN9}nxvrooAeU+ZU+H{u5n>7748>wMpI&-Kg%>)KCBy~AEqoZUZ%DJ{1Lr%{ z9un;00b_!5Kh2~LZL0IC5HY6Qb_z&&CAEF2r;up^w2CqTwRr<26zRVp=_W?igtq`9 zFMwz&lW7<$_-zB_Ru~v(4j6}j`M4GaF>z-G7!+q77`L#oh7dMqfiWK&^61}}vW^h$ z&j5qs%)v%-3ma4y4`zTtajpy|YRIB%C<*LY98K7@j#;+YH#DLK?uZZEvvC)Bc^#)9 z4VNU6np!SzbyNFtn8k7^akN0$;%?dERK|IAC~ZH5>2jvpe~4nLs2Fc>&$(&XjQh6R zZqk%U!Xajn*M-30bsW=kLx`i}FdpyJgn%>>Lem`54N}y?ni@z``D!X2O;@LhxUvmt zf=*+kxl%(hvp~9kpq6J#Rag*9oV?ORW>Oz+%N2ic9W= znHlOrkVOIKp)W@A0}51p>=l+cCW1spL^3?APMfrj*F|)HXbIzPO=Q|hvx?cA! zJng@I@JIiKW&MXf7LSX;M`-Gw=(xpMVx_Fj7>(`3ZrkSVv>o$y+pc+++GX>uv@3W! ziI-N})zokMhR#iv(ptN2#-*f@F1MG>xSTZ8mG+7mSCZ9qt-WT(Ub3EUv^UZl?Hl;6 zwr>je@|M_~vG(oXSls7J-&lM}y!G5^zs+mB{*Bdshd1~#-tThz(AsYP7qVO1tXPhY zRi2Er2;+2^OMS3y7haNg2HiLjMSVCp38hf^NOpw6_R6V{D$X+u>t95jL3ASa;*1MP zYtNn>JpTOIA%@LPPjm+1Fw(s+Kg+Oe7rw~UNQ#ihve-BgI*c==qa+bLyka_D-TG>0 zE8W@RM_ZrV-}>zS)?vFtaxNYlgOAYE+vtSVX550d8MkpShdbQG+vO$PuUs?^Mbdpl zVjSv7iw@D!Z_MCltYijHA zWo2T|nD+YBO+)z%w7<2UT3=evtn9XHXFoeu8}Io)q~k>0%SW0+dfpmd6kdqcScl;)Qtm1`i7~ZkX1BrbCvYr-XKGp?~26+P9QX`qS*nI+&TkA}TPmrPpVfWvpcOd^^S$S=1vg zGbV?+N+VdaId!yuxioQRZ0f$WV&=xy)ScLuHC>+p5uE+ip18WvUw&ZCX}SH}1{Ofw zZ%*8aK^`x?a2XKr5(|rwv3r^P%1}cEmf!+Oq-N(MFf+L0l z0pt2g3?muoT&nFAS%)&DM_q%uWpqUa{**md#9u;fo#$ z38YOE3Lau`@xHb$*#t0|!tj>}Ei;zC&uxqy8V|~c798B_yKwGb%$=J%hj4xF!nsT1 zf0%%yg0r5`Js|^x&)_Ul!F8w$jxPdulJ5t2j(RbcR4`J42U)HIod-Nt!z8*0Kpu>S zCohuDL!n1CWXThG} zxr|zdzNkJqI6V4ze}DIB;eh`hv@c0zMU&z*MA9-ohPxy1)OwK$Q=ua`eN?Q{`r<20 z;!LPw{qZaN4|2Vik1`HaJ5UA?MT;+OWzez?6}^%TjxRzI0_Q8jmQ}Wa5+Ar}GWkn< zUx#v9y|&*|SXCn#KW9^WVyh;lISm_9u%0^Hp1R+$3r{-})_1w{f=x@h)Gu9@XV$dL z-ASom8Id_Z>H{tj*ds>;4CzV^)r9ZQHd0@%0SuJf+xNx~W@MNKvz`ur8 zKLLXJjhhy);Ju92oLJm@QJ#7e?{bCEG_6jm>U$&Ss$QE^d6oN=wqMx&b=(3nU2Y(} zlxH?V7~RALjX!ZF{=oW<$qyz@|Hj1c-xxUbrEk*R&FB{TRbHDeWiDsaCB1oho7X|- zPL^gSNM%0;ir*Ue*tb7NvEJ;zO$7pPzQAc$35yDamGQp~rh{%SgD3+gDcYMa7^yV} z@_wAgKrbNMmE!A>$T}B6-VIEoQ-ta~>xf_ohd2{r&)X> z+VQCfPGhOz>>@i2a6B+?+(HR?M+Lt-+p@>2fwL>&j zMn^dc>SrVzB}5cetn;Shcn^{&J?7EFKM@(4HU1IqxkxMXRMUEZaxO~LLk#A-!OMZV z#`WQa?jaWJAY8=5@n62mM?oYJcT}967=>LGX2F)a8}#xsf$!ku99b|rjp8IaPDINm za@EU62@g7XreaiuS0RkpoyL)|!=0_`a2V|DEJ7U4zXPfi;flA$KR-h7M7%?|0^|f$ zHFGc#BQj`w4NX>m223s01#@l_Vp{`?OHK21d~o=UPS(V1X3*A#J1F zQmh#)5o9{JWK3r&RB&1rP8yvXBb!WC)Q$nBg|sH($qF$jC;16Nc~LowWQGeB)!p-s zfP@IkB`%IfC)+joE81Df&8#X`u2aK;U$OKGKn&RD3H&a}Ne)nyNlqNoctg~N6lsqC z30L+nD#WOh@;5=b^2z~o1RjB{qRy&#%w?|aqq(eR`}R8OLywj1Ci5N7wy|16rHDPu zqh0vfY~969hZ2DApqd0FW}OCTXjT3Je7E1D8lgMV^amr9l-MOD5L5FM6;d22tdgr1 zIsd$TqB_T@qlG(VNQb6+nkT*uTw*Z|68fV926H1lCb~7VVNnaWjKvKm+P7a{F;#L4 z(8j@YJHGq>Hc;6=Pu-@#L+l^{uKCZoq%k6xsq+Zi(!jEc6ufVMAzL*01xZ)VkNcvd x=NPA)X|(i;rLJqF!h0|;tsYYNQ31M|jZ$g;gN|!<4K}Hl5Z}E!+vm$UPSYf95r0n5Qdw#o0TuKCRfM)F5yeDJpv3}Ru6Jwuocq_^ zb=yP^LIik#4}tT@SK3#e_zFBRvuB6Iyl~Ra?#}Mc?#%q=cb_&I4uP-x`@7%%Rwv|7 zoXkEG2A@C^zk-NJL=%$IE~Pj&5~FMA-t3ytn~9ZHx)r@ULc{t|g6hvAakKGbT;8bV|FIB0H-8M7qn76D>f0IdY>0^efR~)P#ODGImL8 z=`VN>X;IY-o{2meN#@6Ck#pGrowLPQv=eZ_ILsQwLEq<0#!K zrqY<0kvXwsMOI~PXh$@%em1U=6XTS^x-mA!^q>lERDy?K+VSAKH(=p`7xz3lU|w-3 z2YKdAALqrHHxkTC0~rqV`aWmRM=?0%mpk{pGoRXyHuspx5zmCTzsE;xe`a@PFz?N- zIB%K>ZG37wWtnVWw6zr^;(r*6aPna<|vZIYgy=W@k^)_FtHyR-IR%Q|_6yT_$-IRh0s9p{!vZXUa^2LYYEx z5Qjp!)A0Cl*2`O_YR*MjU7J(*XHi#+Wg`5ki9ZNmh3o#lyCKtJqlk<3I1@5RlJ)Rq zKO4&Dw^6AZ+$I^%f@EVP<3wx}L3j}K2Fpz*$Nr%RX!QUPeKquf(k1QM=)9jYk0zUa27+DdFK)WU@lWJtj+L#RO z6MAYu(OQ7-`Uyc4Pn- zA_L-E85_VEz!%b%^`QfVdd3+&a}9XqNBV?hA6i5%4BZ2V|3JyHNy*WgY)lrTN@-zi zo?1w(yU>o!@6D&=88b zv$a@2-Z*j~M*tpuw4>q5K|HFkLo%&DtiWnxqy zkpqM47k*t5v~mlc4_PSvEJzt|-~$#>G*Mtd@JlFk-7n3P34asU-U89G_&d;*e+8^_ zKZ--imr+OAT;kPhW%(gg=4RWqwj`Gm!P?ZW7;cr)4u!<;9!Fu literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/setuptools_build.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..695b670ad9c262c3084fad2f20b21c3455c00689 GIT binary patch literal 343 zcmYLF!Ait15KY(1A}roK_o7Xp+g`lYiUIz*iOCi)|xD7m$1l1*IJqKxuhmimu#%Yn(H9Y^QOeG{_{4gAhErNzp0>WtSOf7$#n{Xj;HY zZR+4oJd>i!TA?gpQouX3xK+LOySy?;<8hQXhi*d1J&ATl)nfJduv#u}D_ULO+caghZ=bGy|m)12x%-gq(e0HyAp|}U-(t(kU$Op%T&HrzvPXiY$(;vI(d9Tx)0WhNpk< zWpO$1@IBmW2n{EkCM2aJO7YoBtdV7Ud*qnDHEKa`CvMsvwJ8zS+!LKsI_myRxWiko z2ycmvm-eW~ttZ5H{{@@Gr`4r!PvuFeMG&V&F7*(;xiZyKhzO@FE(``Q^(!=jj3_4% z03F%<@@q1t#zhB0ae4a{flxf&f!^g^z5#uk_jn(Ak8koz(05)Fhm5)q$d#(UE7IaY zEJdVq`69ew6Y`5l3L#mPgi0}e5Neh`&lC$Y4&Ouwk7dC^reR?&L-~U7#qvS7%i!8Q zh*h&Z3NyARSg8bOA=qG1o@sHUSsG^HK6uHc`JS=IkC_yO6iQ?|)N!7%e9S^)?_y6s zXf5MCz)#&VGtqky>VxGAet4KiwLzUjI)X(~gc{;mV-~|1=9yTo=OPjM>=n)Zejvb# zG^UoBGj))c3CCRPC7eA!5E&Ckv5vF-r9Cuo(~P_YNrQ-AWB3T1Zot}E2i$7 zR1nv7$za74lvOAeYh{38ab^O43#4#? z^G%YRRTx$_rL7?vRt|z5E%qk%c5|z5;6W2jXXK?dw@wKqGuX3-p1eK-;lQ5L6Ke+J zfjzUJb!IlSAR@3Ut>LckRxMS+Hk4?#@`51FVjTpPgO#h?I+Dscj5F>#m7_#5mL5!% z9c)n6KuS76V0Lj3{7wG*c1NehP7xQk;!No22vJx6jHKC!e8JQDPEvy4Ia$HmH0QOiEE%dT$LD$n79N8a6?#D^xvc z1q~Ng7&La9m^eM`fY{Nw#jQDTbV5$)DTN5>6QZ37nYXk%X>;3*d8cp|{R!j1Wne$7 zX`Nr=yVIX)*<$ZdEfB36XR3t^AFRmMaQfww!?-9w%1w=$GXqI`?p(UVj!&j-r2g^A zEj(i3oEgVQ(@*O_)*c18#_t%$Rc?~+!(mmmxY#TAFKVg?fz?(k*Lxb(J|a`&LS1!x~efZFsKADb;~5M1N7>NoNii6nu^OTmCpaj#26-{>p8nOb<) z9BZ@Z*`5QxD`w2^V<6*Fml72S_iWWhKESb4wR2@SDG?6&365<6%?3*$9T*`Uq_K(& yN>yiH=!b?)CQ11bu5t6d3H$*w{?5XzpK5WtTO)A~wbUqZ&+fjN5Z!)Apa?Epxr~GasHKQT7q(nXU}wrn8G@yd1s2CEueJhWmYQT zqiUd%WPac;V?Yah-m+n*>bf8P&9JmxUDAxDAnO8`qyo7Pbv44X6jG&>6e=vtm9LPJ z(nJSRMew9>ld-97uWu|Zm>L_XQfC6y3v3#3?HRj@74r58>d^}Wb}u~vG<42*vR(Lx zBZLy1Gd87lYF3L@2#s=iZk1C3`r6JF$T+tyIqX9Pmb>}-WiO+ns`En>0j$E7JX27- zP$mNN_m+zgvs;m(b?l*JmK<4HTKA2VvyeCL9!6;iD%$0$Sr=W8`ib^Hm~o}CLD9ad zJ*RzQ+f}P%9q=e6=9@d)h%82Yb4_^Qa$49%nhMh33Sj9*0u09uM2u!Jj0U0VIFU_a zD~VMF^zd5rDz!s}ux;5nNwsb;R6i0$RyG5%wZFuJYv#1*l#2#Hn{~m!Fz^{NuC3rL z5`(%*3Sip~XiCF|8eWU69jl_EiecGE9Br32AooE$C_@o*eLT{&n2u}o6ltTVo_uv- z(?|y^@ZH?TCXAAVa78KQ+)a?39gaoT1zr2>YJWZ)A0AI$zkBog{p924@%Ui;cC}s4 z>HnosM7~77ij-v;(LEUGRE=o=@xw<+@{#8wszPY}D9;x5VWK!Ba&gj literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/utils/__pycache__/ui.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4534fedff0a03c8aa1d894665da6ccb77f9b1c31 GIT binary patch literal 11817 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py b/env/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py new file mode 100644 index 0000000..cc96f98 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/appdirs.py @@ -0,0 +1,258 @@ +""" +This code was taken from https://github.com/ActiveState/appdirs and modified +to suit our purposes. +""" +from __future__ import absolute_import + +import os +import sys + +from pip._vendor.six import PY2, text_type + +from pip._internal.utils.compat import WINDOWS, expanduser + + +def user_cache_dir(appname): + r""" + Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + + Typical user cache directories are: + macOS: ~/Library/Caches/ + Unix: ~/.cache/ (XDG default) + Windows: C:\Users\\AppData\Local\\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go + in the `CSIDL_LOCAL_APPDATA` directory. This is identical to the + non-roaming app data dir (the default returned by `user_data_dir`). Apps + typically put cache data somewhere *under* the given dir here. Some + examples: + ...\Mozilla\Firefox\Profiles\\Cache + ...\Acme\SuperApp\Cache\1.0 + + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + """ + if WINDOWS: + # Get the base path + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + + # When using Python 2, return paths as bytes on Windows like we do on + # other operating systems. See helper function docs for more details. + if PY2 and isinstance(path, text_type): + path = _win_path_to_bytes(path) + + # Add our app name and Cache directory to it + path = os.path.join(path, appname, "Cache") + elif sys.platform == "darwin": + # Get the base path + path = expanduser("~/Library/Caches") + + # Add our app name to it + path = os.path.join(path, appname) + else: + # Get the base path + path = os.getenv("XDG_CACHE_HOME", expanduser("~/.cache")) + + # Add our app name to it + path = os.path.join(path, appname) + + return path + + +def user_data_dir(appname, roaming=False): + r""" + Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + macOS: ~/Library/Application Support/ + if it exists, else ~/.config/ + Unix: ~/.local/share/ # or in + $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\\ ... + ...Application Data\ + Win XP (roaming): C:\Documents and Settings\\Local ... + ...Settings\Application Data\ + Win 7 (not roaming): C:\\Users\\AppData\Local\ + Win 7 (roaming): C:\\Users\\AppData\Roaming\ + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/". + """ + if WINDOWS: + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.join(os.path.normpath(_get_win_folder(const)), appname) + elif sys.platform == "darwin": + path = os.path.join( + expanduser('~/Library/Application Support/'), + appname, + ) if os.path.isdir(os.path.join( + expanduser('~/Library/Application Support/'), + appname, + ) + ) else os.path.join( + expanduser('~/.config/'), + appname, + ) + else: + path = os.path.join( + os.getenv('XDG_DATA_HOME', expanduser("~/.local/share")), + appname, + ) + + return path + + +def user_config_dir(appname, roaming=True): + """Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "roaming" (boolean, default True) can be set False to not use the + Windows roaming appdata directory. That means that for users on a + Windows network setup for roaming profiles, this user data will be + sync'd on login. See + + for a discussion of issues. + + Typical user data directories are: + macOS: same as user_data_dir + Unix: ~/.config/ + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/". + """ + if WINDOWS: + path = user_data_dir(appname, roaming=roaming) + elif sys.platform == "darwin": + path = user_data_dir(appname) + else: + path = os.getenv('XDG_CONFIG_HOME', expanduser("~/.config")) + path = os.path.join(path, appname) + + return path + + +# for the discussion regarding site_config_dirs locations +# see +def site_config_dirs(appname): + r"""Return a list of potential user-shared config dirs for this application. + + "appname" is the name of application. + + Typical user config directories are: + macOS: /Library/Application Support// + Unix: /etc or $XDG_CONFIG_DIRS[i]// for each value in + $XDG_CONFIG_DIRS + Win XP: C:\Documents and Settings\All Users\Application ... + ...Data\\ + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory + on Vista.) + Win 7: Hidden, but writeable on Win 7: + C:\ProgramData\\ + """ + if WINDOWS: + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + pathlist = [os.path.join(path, appname)] + elif sys.platform == 'darwin': + pathlist = [os.path.join('/Library/Application Support', appname)] + else: + # try looking in $XDG_CONFIG_DIRS + xdg_config_dirs = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + if xdg_config_dirs: + pathlist = [ + os.path.join(expanduser(x), appname) + for x in xdg_config_dirs.split(os.pathsep) + ] + else: + pathlist = [] + + # always look in /etc directly as well + pathlist.append('/etc') + + return pathlist + + +# -- Windows support functions -- + +def _get_win_folder_from_registry(csidl_name): + """ + This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + directory, _type = _winreg.QueryValueEx(key, shell_folder_name) + return directory + + +def _get_win_folder_with_ctypes(csidl_name): + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # . + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + + +if WINDOWS: + try: + import ctypes + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +def _win_path_to_bytes(path): + """Encode Windows paths to bytes. Only used on Python 2. + + Motivation is to be consistent with other operating systems where paths + are also returned as bytes. This avoids problems mixing bytes and Unicode + elsewhere in the codebase. For more details and discussion see + . + + If encoding using ASCII and MBCS fails, return the original Unicode path. + """ + for encoding in ('ASCII', 'MBCS'): + try: + return path.encode(encoding) + except (UnicodeEncodeError, LookupError): + pass + return path diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/compat.py b/env/lib/python3.7/site-packages/pip/_internal/utils/compat.py new file mode 100644 index 0000000..3114f2d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/compat.py @@ -0,0 +1,248 @@ +"""Stuff that differs in different Python versions and platform +distributions.""" +from __future__ import absolute_import, division + +import codecs +import locale +import logging +import os +import shutil +import sys + +from pip._vendor.six import text_type + +try: + import ipaddress +except ImportError: + try: + from pip._vendor import ipaddress # type: ignore + except ImportError: + import ipaddr as ipaddress # type: ignore + ipaddress.ip_address = ipaddress.IPAddress + ipaddress.ip_network = ipaddress.IPNetwork + + +__all__ = [ + "ipaddress", "uses_pycache", "console_to_str", "native_str", + "get_path_uid", "stdlib_pkgs", "WINDOWS", "samefile", "get_terminal_size", + "get_extension_suffixes", +] + + +logger = logging.getLogger(__name__) + +if sys.version_info >= (3, 4): + uses_pycache = True + from importlib.util import cache_from_source +else: + import imp + + try: + cache_from_source = imp.cache_from_source # type: ignore + except AttributeError: + # does not use __pycache__ + cache_from_source = None + + uses_pycache = cache_from_source is not None + + +if sys.version_info >= (3, 5): + backslashreplace_decode = "backslashreplace" +else: + # In version 3.4 and older, backslashreplace exists + # but does not support use for decoding. + # We implement our own replace handler for this + # situation, so that we can consistently use + # backslash replacement for all versions. + def backslashreplace_decode_fn(err): + raw_bytes = (err.object[i] for i in range(err.start, err.end)) + if sys.version_info[0] == 2: + # Python 2 gave us characters - convert to numeric bytes + raw_bytes = (ord(b) for b in raw_bytes) + return u"".join(u"\\x%x" % c for c in raw_bytes), err.end + codecs.register_error( + "backslashreplace_decode", + backslashreplace_decode_fn, + ) + backslashreplace_decode = "backslashreplace_decode" + + +def console_to_str(data): + """Return a string, safe for output, of subprocess output. + + We assume the data is in the locale preferred encoding. + If it won't decode properly, we warn the user but decode as + best we can. + + We also ensure that the output can be safely written to + standard output without encoding errors. + """ + + # First, get the encoding we assume. This is the preferred + # encoding for the locale, unless that is not found, or + # it is ASCII, in which case assume UTF-8 + encoding = locale.getpreferredencoding() + if (not encoding) or codecs.lookup(encoding).name == "ascii": + encoding = "utf-8" + + # Now try to decode the data - if we fail, warn the user and + # decode with replacement. + try: + s = data.decode(encoding) + except UnicodeDecodeError: + logger.warning( + "Subprocess output does not appear to be encoded as %s", + encoding, + ) + s = data.decode(encoding, errors=backslashreplace_decode) + + # Make sure we can print the output, by encoding it to the output + # encoding with replacement of unencodable characters, and then + # decoding again. + # We use stderr's encoding because it's less likely to be + # redirected and if we don't find an encoding we skip this + # step (on the assumption that output is wrapped by something + # that won't fail). + # The double getattr is to deal with the possibility that we're + # being called in a situation where sys.__stderr__ doesn't exist, + # or doesn't have an encoding attribute. Neither of these cases + # should occur in normal pip use, but there's no harm in checking + # in case people use pip in (unsupported) unusual situations. + output_encoding = getattr(getattr(sys, "__stderr__", None), + "encoding", None) + + if output_encoding: + s = s.encode(output_encoding, errors="backslashreplace") + s = s.decode(output_encoding) + + return s + + +if sys.version_info >= (3,): + def native_str(s, replace=False): + if isinstance(s, bytes): + return s.decode('utf-8', 'replace' if replace else 'strict') + return s + +else: + def native_str(s, replace=False): + # Replace is ignored -- unicode to UTF-8 can't fail + if isinstance(s, text_type): + return s.encode('utf-8') + return s + + +def get_path_uid(path): + """ + Return path's uid. + + Does not follow symlinks: + https://github.com/pypa/pip/pull/935#discussion_r5307003 + + Placed this function in compat due to differences on AIX and + Jython, that should eventually go away. + + :raises OSError: When path is a symlink or can't be read. + """ + if hasattr(os, 'O_NOFOLLOW'): + fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW) + file_uid = os.fstat(fd).st_uid + os.close(fd) + else: # AIX and Jython + # WARNING: time of check vulnerability, but best we can do w/o NOFOLLOW + if not os.path.islink(path): + # older versions of Jython don't have `os.fstat` + file_uid = os.stat(path).st_uid + else: + # raise OSError for parity with os.O_NOFOLLOW above + raise OSError( + "%s is a symlink; Will not return uid for symlinks" % path + ) + return file_uid + + +if sys.version_info >= (3, 4): + from importlib.machinery import EXTENSION_SUFFIXES + + def get_extension_suffixes(): + return EXTENSION_SUFFIXES +else: + from imp import get_suffixes + + def get_extension_suffixes(): + return [suffix[0] for suffix in get_suffixes()] + + +def expanduser(path): + """ + Expand ~ and ~user constructions. + + Includes a workaround for https://bugs.python.org/issue14768 + """ + expanded = os.path.expanduser(path) + if path.startswith('~/') and expanded.startswith('//'): + expanded = expanded[1:] + return expanded + + +# packages in the stdlib that may have installation metadata, but should not be +# considered 'installed'. this theoretically could be determined based on +# dist.location (py27:`sysconfig.get_paths()['stdlib']`, +# py26:sysconfig.get_config_vars('LIBDEST')), but fear platform variation may +# make this ineffective, so hard-coding +stdlib_pkgs = {"python", "wsgiref", "argparse"} + + +# windows detection, covers cpython and ironpython +WINDOWS = (sys.platform.startswith("win") or + (sys.platform == 'cli' and os.name == 'nt')) + + +def samefile(file1, file2): + """Provide an alternative for os.path.samefile on Windows/Python2""" + if hasattr(os.path, 'samefile'): + return os.path.samefile(file1, file2) + else: + path1 = os.path.normcase(os.path.abspath(file1)) + path2 = os.path.normcase(os.path.abspath(file2)) + return path1 == path2 + + +if hasattr(shutil, 'get_terminal_size'): + def get_terminal_size(): + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + return tuple(shutil.get_terminal_size()) +else: + def get_terminal_size(): + """ + Returns a tuple (x, y) representing the width(x) and the height(y) + in characters of the terminal window. + """ + def ioctl_GWINSZ(fd): + try: + import fcntl + import termios + import struct + cr = struct.unpack_from( + 'hh', + fcntl.ioctl(fd, termios.TIOCGWINSZ, '12345678') + ) + except Exception: + return None + if cr == (0, 0): + return None + return cr + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except Exception: + pass + if not cr: + cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) + return int(cr[1]), int(cr[0]) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py b/env/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py new file mode 100644 index 0000000..bd744cf --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/deprecation.py @@ -0,0 +1,89 @@ +""" +A module that implements tooling to enable easy warnings about deprecations. +""" +from __future__ import absolute_import + +import logging +import warnings + +from pip._vendor.packaging.version import parse + +from pip import __version__ as current_version +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any, Optional # noqa: F401 + + +class PipDeprecationWarning(Warning): + pass + + +_original_showwarning = None # type: Any + + +# Warnings <-> Logging Integration +def _showwarning(message, category, filename, lineno, file=None, line=None): + if file is not None: + if _original_showwarning is not None: + _original_showwarning( + message, category, filename, lineno, file, line, + ) + elif issubclass(category, PipDeprecationWarning): + # We use a specially named logger which will handle all of the + # deprecation messages for pip. + logger = logging.getLogger("pip._internal.deprecations") + logger.warning(message) + else: + _original_showwarning( + message, category, filename, lineno, file, line, + ) + + +def install_warning_logger(): + # Enable our Deprecation Warnings + warnings.simplefilter("default", PipDeprecationWarning, append=True) + + global _original_showwarning + + if _original_showwarning is None: + _original_showwarning = warnings.showwarning + warnings.showwarning = _showwarning + + +def deprecated(reason, replacement, gone_in, issue=None): + # type: (str, Optional[str], Optional[str], Optional[int]) -> None + """Helper to deprecate existing functionality. + + reason: + Textual reason shown to the user about why this functionality has + been deprecated. + replacement: + Textual suggestion shown to the user about what alternative + functionality they can use. + gone_in: + The version of pip does this functionality should get removed in. + Raises errors if pip's current version is greater than or equal to + this. + issue: + Issue number on the tracker that would serve as a useful place for + users to find related discussion and provide feedback. + + Always pass replacement, gone_in and issue as keyword arguments for clarity + at the call site. + """ + + # Construct a nice message. + # This is purposely eagerly formatted as we want it to appear as if someone + # typed this entire message out. + message = "DEPRECATION: " + reason + if replacement is not None: + message += " A possible replacement is {}.".format(replacement) + if issue is not None: + url = "https://github.com/pypa/pip/issues/" + str(issue) + message += " You can find discussion regarding this at {}.".format(url) + + # Raise as an error if it has to be removed. + if gone_in is not None and parse(current_version) >= parse(gone_in): + raise PipDeprecationWarning(message) + warnings.warn(message, category=PipDeprecationWarning, stacklevel=2) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/encoding.py b/env/lib/python3.7/site-packages/pip/_internal/utils/encoding.py new file mode 100644 index 0000000..56f6036 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/encoding.py @@ -0,0 +1,33 @@ +import codecs +import locale +import re +import sys + +BOMS = [ + (codecs.BOM_UTF8, 'utf8'), + (codecs.BOM_UTF16, 'utf16'), + (codecs.BOM_UTF16_BE, 'utf16-be'), + (codecs.BOM_UTF16_LE, 'utf16-le'), + (codecs.BOM_UTF32, 'utf32'), + (codecs.BOM_UTF32_BE, 'utf32-be'), + (codecs.BOM_UTF32_LE, 'utf32-le'), +] + +ENCODING_RE = re.compile(br'coding[:=]\s*([-\w.]+)') + + +def auto_decode(data): + """Check a bytes string for a BOM to correctly detect the encoding + + Fallback to locale.getpreferredencoding(False) like open() on Python3""" + for bom, encoding in BOMS: + if data.startswith(bom): + return data[len(bom):].decode(encoding) + # Lets check the first two lines as in PEP263 + for line in data.split(b'\n')[:2]: + if line[0:1] == b'#' and ENCODING_RE.search(line): + encoding = ENCODING_RE.search(line).groups()[0].decode('ascii') + return data.decode(encoding) + return data.decode( + locale.getpreferredencoding(False) or sys.getdefaultencoding(), + ) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py b/env/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py new file mode 100644 index 0000000..1e9cebd --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/filesystem.py @@ -0,0 +1,28 @@ +import os +import os.path + +from pip._internal.utils.compat import get_path_uid + + +def check_path_owner(path): + # If we don't have a way to check the effective uid of this process, then + # we'll just assume that we own the directory. + if not hasattr(os, "geteuid"): + return True + + previous = None + while path != previous: + if os.path.lexists(path): + # Check if path is writable by current user. + if os.geteuid() == 0: + # Special handling for root user in order to handle properly + # cases where users use sudo without -H flag. + try: + path_uid = get_path_uid(path) + except OSError: + return False + return path_uid == 0 + else: + return os.access(path, os.W_OK) + else: + previous, path = path, os.path.dirname(path) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/glibc.py b/env/lib/python3.7/site-packages/pip/_internal/utils/glibc.py new file mode 100644 index 0000000..ebcfc5b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/glibc.py @@ -0,0 +1,84 @@ +from __future__ import absolute_import + +import ctypes +import re +import warnings + + +def glibc_version_string(): + "Returns glibc version string, or None if not using glibc." + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + process_namespace = ctypes.CDLL(None) + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5" + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + return version_str + + +# Separated out from have_compatible_glibc for easier unit testing +def check_glibc_version(version_str, required_major, minimum_minor): + # Parse string and check against requested version. + # + # We use a regexp instead of str.split because we want to discard any + # random junk that might come after the minor version -- this might happen + # in patched/forked versions of glibc (e.g. Linaro's version of glibc + # uses version strings like "2.20-2014.11"). See gh-3588. + m = re.match(r"(?P[0-9]+)\.(?P[0-9]+)", version_str) + if not m: + warnings.warn("Expected glibc version with 2 components major.minor," + " got: %s" % version_str, RuntimeWarning) + return False + return (int(m.group("major")) == required_major and + int(m.group("minor")) >= minimum_minor) + + +def have_compatible_glibc(required_major, minimum_minor): + version_str = glibc_version_string() + if version_str is None: + return False + return check_glibc_version(version_str, required_major, minimum_minor) + + +# platform.libc_ver regularly returns completely nonsensical glibc +# versions. E.g. on my computer, platform says: +# +# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.7') +# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.9') +# +# But the truth is: +# +# ~$ ldd --version +# ldd (Debian GLIBC 2.22-11) 2.22 +# +# This is unfortunate, because it means that the linehaul data on libc +# versions that was generated by pip 8.1.2 and earlier is useless and +# misleading. Solution: instead of using platform, use our code that actually +# works. +def libc_ver(): + """Try to determine the glibc version + + Returns a tuple of strings (lib, version) which default to empty strings + in case the lookup fails. + """ + glibc_version = glibc_version_string() + if glibc_version is None: + return ("", "") + else: + return ("glibc", glibc_version) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/hashes.py b/env/lib/python3.7/site-packages/pip/_internal/utils/hashes.py new file mode 100644 index 0000000..8b909ba --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/hashes.py @@ -0,0 +1,94 @@ +from __future__ import absolute_import + +import hashlib + +from pip._vendor.six import iteritems, iterkeys, itervalues + +from pip._internal.exceptions import ( + HashMismatch, HashMissing, InstallationError, +) +from pip._internal.utils.misc import read_chunks + +# The recommended hash algo of the moment. Change this whenever the state of +# the art changes; it won't hurt backward compatibility. +FAVORITE_HASH = 'sha256' + + +# Names of hashlib algorithms allowed by the --hash option and ``pip hash`` +# Currently, those are the ones at least as collision-resistant as sha256. +STRONG_HASHES = ['sha256', 'sha384', 'sha512'] + + +class Hashes(object): + """A wrapper that builds multiple hashes at once and checks them against + known-good values + + """ + def __init__(self, hashes=None): + """ + :param hashes: A dict of algorithm names pointing to lists of allowed + hex digests + """ + self._allowed = {} if hashes is None else hashes + + def check_against_chunks(self, chunks): + """Check good hashes against ones built from iterable of chunks of + data. + + Raise HashMismatch if none match. + + """ + gots = {} + for hash_name in iterkeys(self._allowed): + try: + gots[hash_name] = hashlib.new(hash_name) + except (ValueError, TypeError): + raise InstallationError('Unknown hash name: %s' % hash_name) + + for chunk in chunks: + for hash in itervalues(gots): + hash.update(chunk) + + for hash_name, got in iteritems(gots): + if got.hexdigest() in self._allowed[hash_name]: + return + self._raise(gots) + + def _raise(self, gots): + raise HashMismatch(self._allowed, gots) + + def check_against_file(self, file): + """Check good hashes against a file-like object + + Raise HashMismatch if none match. + + """ + return self.check_against_chunks(read_chunks(file)) + + def check_against_path(self, path): + with open(path, 'rb') as file: + return self.check_against_file(file) + + def __nonzero__(self): + """Return whether I know any known-good hashes.""" + return bool(self._allowed) + + def __bool__(self): + return self.__nonzero__() + + +class MissingHashes(Hashes): + """A workalike for Hashes used when we're missing a hash for a requirement + + It computes the actual hash of the requirement and raises a HashMissing + exception showing it to the user. + + """ + def __init__(self): + """Don't offer the ``hashes`` kwarg.""" + # Pass our favorite hash in to generate a "gotten hash". With the + # empty list, it will never match, so an error will always raise. + super(MissingHashes, self).__init__(hashes={FAVORITE_HASH: []}) + + def _raise(self, gots): + raise HashMissing(gots[FAVORITE_HASH].hexdigest()) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/logging.py b/env/lib/python3.7/site-packages/pip/_internal/utils/logging.py new file mode 100644 index 0000000..d9b9541 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/logging.py @@ -0,0 +1,225 @@ +from __future__ import absolute_import + +import contextlib +import logging +import logging.handlers +import os + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.misc import ensure_dir + +try: + import threading +except ImportError: + import dummy_threading as threading # type: ignore + + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + + +_log_state = threading.local() +_log_state.indentation = 0 + + +@contextlib.contextmanager +def indent_log(num=2): + """ + A context manager which will cause the log output to be indented for any + log messages emitted inside it. + """ + _log_state.indentation += num + try: + yield + finally: + _log_state.indentation -= num + + +def get_indentation(): + return getattr(_log_state, 'indentation', 0) + + +class IndentingFormatter(logging.Formatter): + + def format(self, record): + """ + Calls the standard formatter, but will indent all of the log messages + by our current indentation level. + """ + formatted = logging.Formatter.format(self, record) + formatted = "".join([ + (" " * get_indentation()) + line + for line in formatted.splitlines(True) + ]) + return formatted + + +def _color_wrap(*colors): + def wrapped(inp): + return "".join(list(colors) + [inp, colorama.Style.RESET_ALL]) + return wrapped + + +class ColorizedStreamHandler(logging.StreamHandler): + + # Don't build up a list of colors if we don't have colorama + if colorama: + COLORS = [ + # This needs to be in order from highest logging level to lowest. + (logging.ERROR, _color_wrap(colorama.Fore.RED)), + (logging.WARNING, _color_wrap(colorama.Fore.YELLOW)), + ] + else: + COLORS = [] + + def __init__(self, stream=None, no_color=None): + logging.StreamHandler.__init__(self, stream) + self._no_color = no_color + + if WINDOWS and colorama: + self.stream = colorama.AnsiToWin32(self.stream) + + def should_color(self): + # Don't colorize things if we do not have colorama or if told not to + if not colorama or self._no_color: + return False + + real_stream = ( + self.stream if not isinstance(self.stream, colorama.AnsiToWin32) + else self.stream.wrapped + ) + + # If the stream is a tty we should color it + if hasattr(real_stream, "isatty") and real_stream.isatty(): + return True + + # If we have an ANSI term we should color it + if os.environ.get("TERM") == "ANSI": + return True + + # If anything else we should not color it + return False + + def format(self, record): + msg = logging.StreamHandler.format(self, record) + + if self.should_color(): + for level, color in self.COLORS: + if record.levelno >= level: + msg = color(msg) + break + + return msg + + +class BetterRotatingFileHandler(logging.handlers.RotatingFileHandler): + + def _open(self): + ensure_dir(os.path.dirname(self.baseFilename)) + return logging.handlers.RotatingFileHandler._open(self) + + +class MaxLevelFilter(logging.Filter): + + def __init__(self, level): + self.level = level + + def filter(self, record): + return record.levelno < self.level + + +def setup_logging(verbosity, no_color, user_log_file): + """Configures and sets up all of the logging + """ + + # Determine the level to be logging at. + if verbosity >= 1: + level = "DEBUG" + elif verbosity == -1: + level = "WARNING" + elif verbosity == -2: + level = "ERROR" + elif verbosity <= -3: + level = "CRITICAL" + else: + level = "INFO" + + # The "root" logger should match the "console" level *unless* we also need + # to log to a user log file. + include_user_log = user_log_file is not None + if include_user_log: + additional_log_file = user_log_file + root_level = "DEBUG" + else: + additional_log_file = "/dev/null" + root_level = level + + # Disable any logging besides WARNING unless we have DEBUG level logging + # enabled for vendored libraries. + vendored_log_level = "WARNING" if level in ["INFO", "ERROR"] else "DEBUG" + + # Shorthands for clarity + log_streams = { + "stdout": "ext://sys.stdout", + "stderr": "ext://sys.stderr", + } + handler_classes = { + "stream": "pip._internal.utils.logging.ColorizedStreamHandler", + "file": "pip._internal.utils.logging.BetterRotatingFileHandler", + } + + logging.config.dictConfig({ + "version": 1, + "disable_existing_loggers": False, + "filters": { + "exclude_warnings": { + "()": "pip._internal.utils.logging.MaxLevelFilter", + "level": logging.WARNING, + }, + }, + "formatters": { + "indent": { + "()": IndentingFormatter, + "format": "%(message)s", + }, + }, + "handlers": { + "console": { + "level": level, + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stdout"], + "filters": ["exclude_warnings"], + "formatter": "indent", + }, + "console_errors": { + "level": "WARNING", + "class": handler_classes["stream"], + "no_color": no_color, + "stream": log_streams["stderr"], + "formatter": "indent", + }, + "user_log": { + "level": "DEBUG", + "class": handler_classes["file"], + "filename": additional_log_file, + "delay": True, + "formatter": "indent", + }, + }, + "root": { + "level": root_level, + "handlers": ["console", "console_errors"] + ( + ["user_log"] if include_user_log else [] + ), + }, + "loggers": { + "pip._vendor": { + "level": vendored_log_level + } + }, + }) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/misc.py b/env/lib/python3.7/site-packages/pip/_internal/utils/misc.py new file mode 100644 index 0000000..84a421f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/misc.py @@ -0,0 +1,940 @@ +from __future__ import absolute_import + +import contextlib +import errno +import io +import locale +# we have a submodule named 'logging' which would shadow this if we used the +# regular name: +import logging as std_logging +import os +import posixpath +import re +import shutil +import stat +import subprocess +import sys +import tarfile +import zipfile +from collections import deque + +from pip._vendor import pkg_resources +# NOTE: retrying is not annotated in typeshed as on 2017-07-17, which is +# why we ignore the type on this import. +from pip._vendor.retrying import retry # type: ignore +from pip._vendor.six import PY2 +from pip._vendor.six.moves import input +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.exceptions import CommandError, InstallationError +from pip._internal.locations import ( + running_under_virtualenv, site_packages, user_site, virtualenv_no_global, + write_delete_marker_file, +) +from pip._internal.utils.compat import ( + WINDOWS, console_to_str, expanduser, stdlib_pkgs, +) + +if PY2: + from io import BytesIO as StringIO +else: + from io import StringIO + +__all__ = ['rmtree', 'display_path', 'backup_dir', + 'ask', 'splitext', + 'format_size', 'is_installable_dir', + 'is_svn_page', 'file_contents', + 'split_leading_dir', 'has_leading_dir', + 'normalize_path', + 'renames', 'get_prog', + 'unzip_file', 'untar_file', 'unpack_file', 'call_subprocess', + 'captured_stdout', 'ensure_dir', + 'ARCHIVE_EXTENSIONS', 'SUPPORTED_EXTENSIONS', + 'get_installed_version', 'remove_auth_from_url'] + + +logger = std_logging.getLogger(__name__) + +BZ2_EXTENSIONS = ('.tar.bz2', '.tbz') +XZ_EXTENSIONS = ('.tar.xz', '.txz', '.tlz', '.tar.lz', '.tar.lzma') +ZIP_EXTENSIONS = ('.zip', '.whl') +TAR_EXTENSIONS = ('.tar.gz', '.tgz', '.tar') +ARCHIVE_EXTENSIONS = ( + ZIP_EXTENSIONS + BZ2_EXTENSIONS + TAR_EXTENSIONS + XZ_EXTENSIONS) +SUPPORTED_EXTENSIONS = ZIP_EXTENSIONS + TAR_EXTENSIONS +try: + import bz2 # noqa + SUPPORTED_EXTENSIONS += BZ2_EXTENSIONS +except ImportError: + logger.debug('bz2 module is not available') + +try: + # Only for Python 3.3+ + import lzma # noqa + SUPPORTED_EXTENSIONS += XZ_EXTENSIONS +except ImportError: + logger.debug('lzma module is not available') + + +def import_or_raise(pkg_or_module_string, ExceptionType, *args, **kwargs): + try: + return __import__(pkg_or_module_string) + except ImportError: + raise ExceptionType(*args, **kwargs) + + +def ensure_dir(path): + """os.path.makedirs without EEXIST.""" + try: + os.makedirs(path) + except OSError as e: + if e.errno != errno.EEXIST: + raise + + +def get_prog(): + try: + prog = os.path.basename(sys.argv[0]) + if prog in ('__main__.py', '-c'): + return "%s -m pip" % sys.executable + else: + return prog + except (AttributeError, TypeError, IndexError): + pass + return 'pip' + + +# Retry every half second for up to 3 seconds +@retry(stop_max_delay=3000, wait_fixed=500) +def rmtree(dir, ignore_errors=False): + shutil.rmtree(dir, ignore_errors=ignore_errors, + onerror=rmtree_errorhandler) + + +def rmtree_errorhandler(func, path, exc_info): + """On Windows, the files in .svn are read-only, so when rmtree() tries to + remove them, an exception is thrown. We catch that here, remove the + read-only attribute, and hopefully continue without problems.""" + # if file type currently read only + if os.stat(path).st_mode & stat.S_IREAD: + # convert to read/write + os.chmod(path, stat.S_IWRITE) + # use the original function to repeat the operation + func(path) + return + else: + raise + + +def display_path(path): + """Gives the display value for a given path, making it relative to cwd + if possible.""" + path = os.path.normcase(os.path.abspath(path)) + if sys.version_info[0] == 2: + path = path.decode(sys.getfilesystemencoding(), 'replace') + path = path.encode(sys.getdefaultencoding(), 'replace') + if path.startswith(os.getcwd() + os.path.sep): + path = '.' + path[len(os.getcwd()):] + return path + + +def backup_dir(dir, ext='.bak'): + """Figure out the name of a directory to back up the given dir to + (adding .bak, .bak2, etc)""" + n = 1 + extension = ext + while os.path.exists(dir + extension): + n += 1 + extension = ext + str(n) + return dir + extension + + +def ask_path_exists(message, options): + for action in os.environ.get('PIP_EXISTS_ACTION', '').split(): + if action in options: + return action + return ask(message, options) + + +def ask(message, options): + """Ask the message interactively, with the given possible responses""" + while 1: + if os.environ.get('PIP_NO_INPUT'): + raise Exception( + 'No input was expected ($PIP_NO_INPUT set); question: %s' % + message + ) + response = input(message) + response = response.strip().lower() + if response not in options: + print( + 'Your response (%r) was not one of the expected responses: ' + '%s' % (response, ', '.join(options)) + ) + else: + return response + + +def format_size(bytes): + if bytes > 1000 * 1000: + return '%.1fMB' % (bytes / 1000.0 / 1000) + elif bytes > 10 * 1000: + return '%ikB' % (bytes / 1000) + elif bytes > 1000: + return '%.1fkB' % (bytes / 1000.0) + else: + return '%ibytes' % bytes + + +def is_installable_dir(path): + """Is path is a directory containing setup.py or pyproject.toml? + """ + if not os.path.isdir(path): + return False + setup_py = os.path.join(path, 'setup.py') + if os.path.isfile(setup_py): + return True + pyproject_toml = os.path.join(path, 'pyproject.toml') + if os.path.isfile(pyproject_toml): + return True + return False + + +def is_svn_page(html): + """ + Returns true if the page appears to be the index page of an svn repository + """ + return (re.search(r'[^<]*Revision \d+:', html) and + re.search(r'Powered by (?:<a[^>]*?>)?Subversion', html, re.I)) + + +def file_contents(filename): + with open(filename, 'rb') as fp: + return fp.read().decode('utf-8') + + +def read_chunks(file, size=io.DEFAULT_BUFFER_SIZE): + """Yield pieces of data from a file-like object until EOF.""" + while True: + chunk = file.read(size) + if not chunk: + break + yield chunk + + +def split_leading_dir(path): + path = path.lstrip('/').lstrip('\\') + if '/' in path and (('\\' in path and path.find('/') < path.find('\\')) or + '\\' not in path): + return path.split('/', 1) + elif '\\' in path: + return path.split('\\', 1) + else: + return path, '' + + +def has_leading_dir(paths): + """Returns true if all the paths have the same leading path name + (i.e., everything is in one subdirectory in an archive)""" + common_prefix = None + for path in paths: + prefix, rest = split_leading_dir(path) + if not prefix: + return False + elif common_prefix is None: + common_prefix = prefix + elif prefix != common_prefix: + return False + return True + + +def normalize_path(path, resolve_symlinks=True): + """ + Convert a path to its canonical, case-normalized, absolute version. + + """ + path = expanduser(path) + if resolve_symlinks: + path = os.path.realpath(path) + else: + path = os.path.abspath(path) + return os.path.normcase(path) + + +def splitext(path): + """Like os.path.splitext, but take off .tar too""" + base, ext = posixpath.splitext(path) + if base.lower().endswith('.tar'): + ext = base[-4:] + ext + base = base[:-4] + return base, ext + + +def renames(old, new): + """Like os.renames(), but handles renaming across devices.""" + # Implementation borrowed from os.renames(). + head, tail = os.path.split(new) + if head and tail and not os.path.exists(head): + os.makedirs(head) + + shutil.move(old, new) + + head, tail = os.path.split(old) + if head and tail: + try: + os.removedirs(head) + except OSError: + pass + + +def is_local(path): + """ + Return True if path is within sys.prefix, if we're running in a virtualenv. + + If we're not in a virtualenv, all paths are considered "local." + + """ + if not running_under_virtualenv(): + return True + return normalize_path(path).startswith(normalize_path(sys.prefix)) + + +def dist_is_local(dist): + """ + Return True if given Distribution object is installed locally + (i.e. within current virtualenv). + + Always True if we're not in a virtualenv. + + """ + return is_local(dist_location(dist)) + + +def dist_in_usersite(dist): + """ + Return True if given Distribution is installed in user site. + """ + norm_path = normalize_path(dist_location(dist)) + return norm_path.startswith(normalize_path(user_site)) + + +def dist_in_site_packages(dist): + """ + Return True if given Distribution is installed in + sysconfig.get_python_lib(). + """ + return normalize_path( + dist_location(dist) + ).startswith(normalize_path(site_packages)) + + +def dist_is_editable(dist): + """Is distribution an editable install?""" + for path_item in sys.path: + egg_link = os.path.join(path_item, dist.project_name + '.egg-link') + if os.path.isfile(egg_link): + return True + return False + + +def get_installed_distributions(local_only=True, + skip=stdlib_pkgs, + include_editables=True, + editables_only=False, + user_only=False): + """ + Return a list of installed Distribution objects. + + If ``local_only`` is True (default), only return installations + local to the current virtualenv, if in a virtualenv. + + ``skip`` argument is an iterable of lower-case project names to + ignore; defaults to stdlib_pkgs + + If ``include_editables`` is False, don't report editables. + + If ``editables_only`` is True , only report editables. + + If ``user_only`` is True , only report installations in the user + site directory. + + """ + if local_only: + local_test = dist_is_local + else: + def local_test(d): + return True + + if include_editables: + def editable_test(d): + return True + else: + def editable_test(d): + return not dist_is_editable(d) + + if editables_only: + def editables_only_test(d): + return dist_is_editable(d) + else: + def editables_only_test(d): + return True + + if user_only: + user_test = dist_in_usersite + else: + def user_test(d): + return True + + return [d for d in pkg_resources.working_set + if local_test(d) and + d.key not in skip and + editable_test(d) and + editables_only_test(d) and + user_test(d) + ] + + +def egg_link_path(dist): + """ + Return the path for the .egg-link file if it exists, otherwise, None. + + There's 3 scenarios: + 1) not in a virtualenv + try to find in site.USER_SITE, then site_packages + 2) in a no-global virtualenv + try to find in site_packages + 3) in a yes-global virtualenv + try to find in site_packages, then site.USER_SITE + (don't look in global location) + + For #1 and #3, there could be odd cases, where there's an egg-link in 2 + locations. + + This method will just return the first one found. + """ + sites = [] + if running_under_virtualenv(): + if virtualenv_no_global(): + sites.append(site_packages) + else: + sites.append(site_packages) + if user_site: + sites.append(user_site) + else: + if user_site: + sites.append(user_site) + sites.append(site_packages) + + for site in sites: + egglink = os.path.join(site, dist.project_name) + '.egg-link' + if os.path.isfile(egglink): + return egglink + + +def dist_location(dist): + """ + Get the site-packages location of this distribution. Generally + this is dist.location, except in the case of develop-installed + packages, where dist.location is the source code location, and we + want to know where the egg-link file is. + + """ + egg_link = egg_link_path(dist) + if egg_link: + return egg_link + return dist.location + + +def current_umask(): + """Get the current umask which involves having to set it temporarily.""" + mask = os.umask(0) + os.umask(mask) + return mask + + +def unzip_file(filename, location, flatten=True): + """ + Unzip the file (with path `filename`) to the destination `location`. All + files are written based on system defaults and umask (i.e. permissions are + not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + zipfp = open(filename, 'rb') + try: + zip = zipfile.ZipFile(zipfp, allowZip64=True) + leading = has_leading_dir(zip.namelist()) and flatten + for info in zip.infolist(): + name = info.filename + data = zip.read(name) + fn = name + if leading: + fn = split_leading_dir(name)[1] + fn = os.path.join(location, fn) + dir = os.path.dirname(fn) + if fn.endswith('/') or fn.endswith('\\'): + # A directory + ensure_dir(fn) + else: + ensure_dir(dir) + fp = open(fn, 'wb') + try: + fp.write(data) + finally: + fp.close() + mode = info.external_attr >> 16 + # if mode and regular file and any execute permissions for + # user/group/world? + if mode and stat.S_ISREG(mode) and mode & 0o111: + # make dest file have execute for user/group/world + # (chmod +x) no-op on windows per python docs + os.chmod(fn, (0o777 - current_umask() | 0o111)) + finally: + zipfp.close() + + +def untar_file(filename, location): + """ + Untar the file (with path `filename`) to the destination `location`. + All files are written based on system defaults and umask (i.e. permissions + are not preserved), except that regular file members with any execute + permissions (user, group, or world) have "chmod +x" applied after being + written. Note that for windows, any execute changes using os.chmod are + no-ops per the python docs. + """ + ensure_dir(location) + if filename.lower().endswith('.gz') or filename.lower().endswith('.tgz'): + mode = 'r:gz' + elif filename.lower().endswith(BZ2_EXTENSIONS): + mode = 'r:bz2' + elif filename.lower().endswith(XZ_EXTENSIONS): + mode = 'r:xz' + elif filename.lower().endswith('.tar'): + mode = 'r' + else: + logger.warning( + 'Cannot determine compression type for file %s', filename, + ) + mode = 'r:*' + tar = tarfile.open(filename, mode) + try: + # note: python<=2.5 doesn't seem to know about pax headers, filter them + leading = has_leading_dir([ + member.name for member in tar.getmembers() + if member.name != 'pax_global_header' + ]) + for member in tar.getmembers(): + fn = member.name + if fn == 'pax_global_header': + continue + if leading: + fn = split_leading_dir(fn)[1] + path = os.path.join(location, fn) + if member.isdir(): + ensure_dir(path) + elif member.issym(): + try: + tar._extract_member(member, path) + except Exception as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + else: + try: + fp = tar.extractfile(member) + except (KeyError, AttributeError) as exc: + # Some corrupt tar files seem to produce this + # (specifically bad symlinks) + logger.warning( + 'In the tar file %s the member %s is invalid: %s', + filename, member.name, exc, + ) + continue + ensure_dir(os.path.dirname(path)) + with open(path, 'wb') as destfp: + shutil.copyfileobj(fp, destfp) + fp.close() + # Update the timestamp (useful for cython compiled files) + tar.utime(member, path) + # member have any execute permissions for user/group/world? + if member.mode & 0o111: + # make dest file have execute for user/group/world + # no-op on windows per python docs + os.chmod(path, (0o777 - current_umask() | 0o111)) + finally: + tar.close() + + +def unpack_file(filename, location, content_type, link): + filename = os.path.realpath(filename) + if (content_type == 'application/zip' or + filename.lower().endswith(ZIP_EXTENSIONS) or + zipfile.is_zipfile(filename)): + unzip_file( + filename, + location, + flatten=not filename.endswith('.whl') + ) + elif (content_type == 'application/x-gzip' or + tarfile.is_tarfile(filename) or + filename.lower().endswith( + TAR_EXTENSIONS + BZ2_EXTENSIONS + XZ_EXTENSIONS)): + untar_file(filename, location) + elif (content_type and content_type.startswith('text/html') and + is_svn_page(file_contents(filename))): + # We don't really care about this + from pip._internal.vcs.subversion import Subversion + Subversion('svn+' + link.url).unpack(location) + else: + # FIXME: handle? + # FIXME: magic signatures? + logger.critical( + 'Cannot unpack file %s (downloaded from %s, content-type: %s); ' + 'cannot detect archive format', + filename, location, content_type, + ) + raise InstallationError( + 'Cannot determine archive format of %s' % location + ) + + +def call_subprocess(cmd, show_stdout=True, cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, unset_environ=None, spinner=None): + """ + Args: + unset_environ: an iterable of environment variable names to unset + prior to calling subprocess.Popen(). + """ + if unset_environ is None: + unset_environ = [] + # This function's handling of subprocess output is confusing and I + # previously broke it terribly, so as penance I will write a long comment + # explaining things. + # + # The obvious thing that affects output is the show_stdout= + # kwarg. show_stdout=True means, let the subprocess write directly to our + # stdout. Even though it is nominally the default, it is almost never used + # inside pip (and should not be used in new code without a very good + # reason); as of 2016-02-22 it is only used in a few places inside the VCS + # wrapper code. Ideally we should get rid of it entirely, because it + # creates a lot of complexity here for a rarely used feature. + # + # Most places in pip set show_stdout=False. What this means is: + # - We connect the child stdout to a pipe, which we read. + # - By default, we hide the output but show a spinner -- unless the + # subprocess exits with an error, in which case we show the output. + # - If the --verbose option was passed (= loglevel is DEBUG), then we show + # the output unconditionally. (But in this case we don't want to show + # the output a second time if it turns out that there was an error.) + # + # stderr is always merged with stdout (even if show_stdout=True). + if show_stdout: + stdout = None + else: + stdout = subprocess.PIPE + if command_desc is None: + cmd_parts = [] + for part in cmd: + if ' ' in part or '\n' in part or '"' in part or "'" in part: + part = '"%s"' % part.replace('"', '\\"') + cmd_parts.append(part) + command_desc = ' '.join(cmd_parts) + logger.debug("Running command %s", command_desc) + env = os.environ.copy() + if extra_environ: + env.update(extra_environ) + for name in unset_environ: + env.pop(name, None) + try: + proc = subprocess.Popen( + cmd, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, + stdout=stdout, cwd=cwd, env=env, + ) + proc.stdin.close() + except Exception as exc: + logger.critical( + "Error %s while executing command %s", exc, command_desc, + ) + raise + all_output = [] + if stdout is not None: + while True: + line = console_to_str(proc.stdout.readline()) + if not line: + break + line = line.rstrip() + all_output.append(line + '\n') + if logger.getEffectiveLevel() <= std_logging.DEBUG: + # Show the line immediately + logger.debug(line) + else: + # Update the spinner + if spinner is not None: + spinner.spin() + try: + proc.wait() + finally: + if proc.stdout: + proc.stdout.close() + if spinner is not None: + if proc.returncode: + spinner.finish("error") + else: + spinner.finish("done") + if proc.returncode: + if on_returncode == 'raise': + if (logger.getEffectiveLevel() > std_logging.DEBUG and + not show_stdout): + logger.info( + 'Complete output from command %s:', command_desc, + ) + logger.info( + ''.join(all_output) + + '\n----------------------------------------' + ) + raise InstallationError( + 'Command "%s" failed with error code %s in %s' + % (command_desc, proc.returncode, cwd)) + elif on_returncode == 'warn': + logger.warning( + 'Command "%s" had error code %s in %s', + command_desc, proc.returncode, cwd, + ) + elif on_returncode == 'ignore': + pass + else: + raise ValueError('Invalid value: on_returncode=%s' % + repr(on_returncode)) + if not show_stdout: + return ''.join(all_output) + + +def read_text_file(filename): + """Return the contents of *filename*. + + Try to decode the file contents with utf-8, the preferred system encoding + (e.g., cp1252 on some Windows machines), and latin1, in that order. + Decoding a byte string with latin1 will never raise an error. In the worst + case, the returned string will contain some garbage characters. + + """ + with open(filename, 'rb') as fp: + data = fp.read() + + encodings = ['utf-8', locale.getpreferredencoding(False), 'latin1'] + for enc in encodings: + try: + data = data.decode(enc) + except UnicodeDecodeError: + continue + break + + assert type(data) != bytes # Latin1 should have worked. + return data + + +def _make_build_dir(build_dir): + os.makedirs(build_dir) + write_delete_marker_file(build_dir) + + +class FakeFile(object): + """Wrap a list of lines in an object with readline() to make + ConfigParser happy.""" + def __init__(self, lines): + self._gen = (l for l in lines) + + def readline(self): + try: + try: + return next(self._gen) + except NameError: + return self._gen.next() + except StopIteration: + return '' + + def __iter__(self): + return self._gen + + +class StreamWrapper(StringIO): + + @classmethod + def from_stream(cls, orig_stream): + cls.orig_stream = orig_stream + return cls() + + # compileall.compile_dir() needs stdout.encoding to print to stdout + @property + def encoding(self): + return self.orig_stream.encoding + + +@contextlib.contextmanager +def captured_output(stream_name): + """Return a context manager used by captured_stdout/stdin/stderr + that temporarily replaces the sys stream *stream_name* with a StringIO. + + Taken from Lib/support/__init__.py in the CPython repo. + """ + orig_stdout = getattr(sys, stream_name) + setattr(sys, stream_name, StreamWrapper.from_stream(orig_stdout)) + try: + yield getattr(sys, stream_name) + finally: + setattr(sys, stream_name, orig_stdout) + + +def captured_stdout(): + """Capture the output of sys.stdout: + + with captured_stdout() as stdout: + print('hello') + self.assertEqual(stdout.getvalue(), 'hello\n') + + Taken from Lib/support/__init__.py in the CPython repo. + """ + return captured_output('stdout') + + +class cached_property(object): + """A property that is only computed once per instance and then replaces + itself with an ordinary attribute. Deleting the attribute resets the + property. + + Source: https://github.com/bottlepy/bottle/blob/0.11.5/bottle.py#L175 + """ + + def __init__(self, func): + self.__doc__ = getattr(func, '__doc__') + self.func = func + + def __get__(self, obj, cls): + if obj is None: + # We're being accessed from the class itself, not from an object + return self + value = obj.__dict__[self.func.__name__] = self.func(obj) + return value + + +def get_installed_version(dist_name, working_set=None): + """Get the installed version of dist_name avoiding pkg_resources cache""" + # Create a requirement that we'll look for inside of setuptools. + req = pkg_resources.Requirement.parse(dist_name) + + if working_set is None: + # We want to avoid having this cached, so we need to construct a new + # working set each time. + working_set = pkg_resources.WorkingSet() + + # Get the installed distribution from our working set + dist = working_set.find(req) + + # Check to see if we got an installed distribution or not, if we did + # we want to return it's version. + return dist.version if dist else None + + +def consume(iterator): + """Consume an iterable at C speed.""" + deque(iterator, maxlen=0) + + +# Simulates an enum +def enum(*sequential, **named): + enums = dict(zip(sequential, range(len(sequential))), **named) + reverse = {value: key for key, value in enums.items()} + enums['reverse_mapping'] = reverse + return type('Enum', (), enums) + + +def make_vcs_requirement_url(repo_url, rev, egg_project_name, subdir=None): + """ + Return the URL for a VCS requirement. + + Args: + repo_url: the remote VCS url, with any needed VCS prefix (e.g. "git+"). + """ + req = '{}@{}#egg={}'.format(repo_url, rev, egg_project_name) + if subdir: + req += '&subdirectory={}'.format(subdir) + + return req + + +def split_auth_from_netloc(netloc): + """ + Parse out and remove the auth information from a netloc. + + Returns: (netloc, (username, password)). + """ + if '@' not in netloc: + return netloc, (None, None) + + # Split from the right because that's how urllib.parse.urlsplit() + # behaves if more than one @ is present (which can be checked using + # the password attribute of urlsplit()'s return value). + auth, netloc = netloc.rsplit('@', 1) + if ':' in auth: + # Split from the left because that's how urllib.parse.urlsplit() + # behaves if more than one : is present (which again can be checked + # using the password attribute of the return value) + user_pass = tuple(auth.split(':', 1)) + else: + user_pass = auth, None + + return netloc, user_pass + + +def remove_auth_from_url(url): + # Return a copy of url with 'username:password@' removed. + # username/pass params are passed to subversion through flags + # and are not recognized in the url. + + # parsed url + purl = urllib_parse.urlsplit(url) + netloc, user_pass = split_auth_from_netloc(purl.netloc) + + # stripped url + url_pieces = ( + purl.scheme, netloc, purl.path, purl.query, purl.fragment + ) + surl = urllib_parse.urlunsplit(url_pieces) + return surl + + +def protect_pip_from_modification_on_windows(modifying_pip): + """Protection of pip.exe from modification on Windows + + On Windows, any operation modifying pip should be run as: + python -m pip ... + """ + pip_names = [ + "pip.exe", + "pip{}.exe".format(sys.version_info[0]), + "pip{}.{}.exe".format(*sys.version_info[:2]) + ] + + # See https://github.com/pypa/pip/issues/1299 for more discussion + should_show_use_python_msg = ( + modifying_pip and + WINDOWS and + os.path.basename(sys.argv[0]) in pip_names + ) + + if should_show_use_python_msg: + new_command = [ + sys.executable, "-m", "pip" + ] + sys.argv[1:] + raise CommandError( + 'To modify pip, please run the following command:\n{}' + .format(" ".join(new_command)) + ) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/models.py b/env/lib/python3.7/site-packages/pip/_internal/utils/models.py new file mode 100644 index 0000000..d5cb80a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/models.py @@ -0,0 +1,40 @@ +"""Utilities for defining models +""" + +import operator + + +class KeyBasedCompareMixin(object): + """Provides comparision capabilities that is based on a key + """ + + def __init__(self, key, defining_class): + self._compare_key = key + self._defining_class = defining_class + + def __hash__(self): + return hash(self._compare_key) + + def __lt__(self, other): + return self._compare(other, operator.__lt__) + + def __le__(self, other): + return self._compare(other, operator.__le__) + + def __gt__(self, other): + return self._compare(other, operator.__gt__) + + def __ge__(self, other): + return self._compare(other, operator.__ge__) + + def __eq__(self, other): + return self._compare(other, operator.__eq__) + + def __ne__(self, other): + return self._compare(other, operator.__ne__) + + def _compare(self, other, method): + if not isinstance(other, self._defining_class): + return NotImplemented + + return method(self._compare_key, other._compare_key) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/outdated.py b/env/lib/python3.7/site-packages/pip/_internal/utils/outdated.py new file mode 100644 index 0000000..5bfbfe1 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/outdated.py @@ -0,0 +1,154 @@ +from __future__ import absolute_import + +import datetime +import json +import logging +import os.path +import sys + +from pip._vendor import lockfile, pkg_resources +from pip._vendor.packaging import version as packaging_version + +from pip._internal.index import PackageFinder +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.filesystem import check_path_owner +from pip._internal.utils.misc import ensure_dir, get_installed_version + +SELFCHECK_DATE_FMT = "%Y-%m-%dT%H:%M:%SZ" + + +logger = logging.getLogger(__name__) + + +class SelfCheckState(object): + def __init__(self, cache_dir): + self.state = {} + self.statefile_path = None + + # Try to load the existing state + if cache_dir: + self.statefile_path = os.path.join(cache_dir, "selfcheck.json") + try: + with open(self.statefile_path) as statefile: + self.state = json.load(statefile)[sys.prefix] + except (IOError, ValueError, KeyError): + # Explicitly suppressing exceptions, since we don't want to + # error out if the cache file is invalid. + pass + + def save(self, pypi_version, current_time): + # If we do not have a path to cache in, don't bother saving. + if not self.statefile_path: + return + + # Check to make sure that we own the directory + if not check_path_owner(os.path.dirname(self.statefile_path)): + return + + # Now that we've ensured the directory is owned by this user, we'll go + # ahead and make sure that all our directories are created. + ensure_dir(os.path.dirname(self.statefile_path)) + + # Attempt to write out our version check file + with lockfile.LockFile(self.statefile_path): + if os.path.exists(self.statefile_path): + with open(self.statefile_path) as statefile: + state = json.load(statefile) + else: + state = {} + + state[sys.prefix] = { + "last_check": current_time.strftime(SELFCHECK_DATE_FMT), + "pypi_version": pypi_version, + } + + with open(self.statefile_path, "w") as statefile: + json.dump(state, statefile, sort_keys=True, + separators=(",", ":")) + + +def was_installed_by_pip(pkg): + """Checks whether pkg was installed by pip + + This is used not to display the upgrade message when pip is in fact + installed by system package manager, such as dnf on Fedora. + """ + try: + dist = pkg_resources.get_distribution(pkg) + return (dist.has_metadata('INSTALLER') and + 'pip' in dist.get_metadata_lines('INSTALLER')) + except pkg_resources.DistributionNotFound: + return False + + +def pip_version_check(session, options): + """Check for an update for pip. + + Limit the frequency of checks to once per week. State is stored either in + the active virtualenv or in the user's USER_CACHE_DIR keyed off the prefix + of the pip script path. + """ + installed_version = get_installed_version("pip") + if not installed_version: + return + + pip_version = packaging_version.parse(installed_version) + pypi_version = None + + try: + state = SelfCheckState(cache_dir=options.cache_dir) + + current_time = datetime.datetime.utcnow() + # Determine if we need to refresh the state + if "last_check" in state.state and "pypi_version" in state.state: + last_check = datetime.datetime.strptime( + state.state["last_check"], + SELFCHECK_DATE_FMT + ) + if (current_time - last_check).total_seconds() < 7 * 24 * 60 * 60: + pypi_version = state.state["pypi_version"] + + # Refresh the version if we need to or just see if we need to warn + if pypi_version is None: + # Lets use PackageFinder to see what the latest pip version is + finder = PackageFinder( + find_links=options.find_links, + index_urls=[options.index_url] + options.extra_index_urls, + allow_all_prereleases=False, # Explicitly set to False + trusted_hosts=options.trusted_hosts, + process_dependency_links=options.process_dependency_links, + session=session, + ) + all_candidates = finder.find_all_candidates("pip") + if not all_candidates: + return + pypi_version = str( + max(all_candidates, key=lambda c: c.version).version + ) + + # save that we've performed a check + state.save(pypi_version, current_time) + + remote_version = packaging_version.parse(pypi_version) + + # Determine if our pypi_version is older + if (pip_version < remote_version and + pip_version.base_version != remote_version.base_version and + was_installed_by_pip('pip')): + # Advise "python -m pip" on Windows to avoid issues + # with overwriting pip.exe. + if WINDOWS: + pip_cmd = "python -m pip" + else: + pip_cmd = "pip" + logger.warning( + "You are using pip version %s, however version %s is " + "available.\nYou should consider upgrading via the " + "'%s install --upgrade pip' command.", + pip_version, pypi_version, pip_cmd + ) + except Exception: + logger.debug( + "There was an error checking the latest version of pip", + exc_info=True, + ) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/packaging.py b/env/lib/python3.7/site-packages/pip/_internal/utils/packaging.py new file mode 100644 index 0000000..c43142f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/packaging.py @@ -0,0 +1,75 @@ +from __future__ import absolute_import + +import logging +import sys +from email.parser import FeedParser # type: ignore + +from pip._vendor import pkg_resources +from pip._vendor.packaging import specifiers, version + +from pip._internal import exceptions +from pip._internal.utils.misc import display_path + +logger = logging.getLogger(__name__) + + +def check_requires_python(requires_python): + """ + Check if the python version in use match the `requires_python` specifier. + + Returns `True` if the version of python in use matches the requirement. + Returns `False` if the version of python in use does not matches the + requirement. + + Raises an InvalidSpecifier if `requires_python` have an invalid format. + """ + if requires_python is None: + # The package provides no information + return True + requires_python_specifier = specifiers.SpecifierSet(requires_python) + + # We only use major.minor.micro + python_version = version.parse('.'.join(map(str, sys.version_info[:3]))) + return python_version in requires_python_specifier + + +def get_metadata(dist): + if (isinstance(dist, pkg_resources.DistInfoDistribution) and + dist.has_metadata('METADATA')): + metadata = dist.get_metadata('METADATA') + elif dist.has_metadata('PKG-INFO'): + metadata = dist.get_metadata('PKG-INFO') + else: + logger.warning("No metadata found in %s", display_path(dist.location)) + metadata = '' + + feed_parser = FeedParser() + feed_parser.feed(metadata) + return feed_parser.close() + + +def check_dist_requires_python(dist): + pkg_info_dict = get_metadata(dist) + requires_python = pkg_info_dict.get('Requires-Python') + try: + if not check_requires_python(requires_python): + raise exceptions.UnsupportedPythonVersion( + "%s requires Python '%s' but the running Python is %s" % ( + dist.project_name, + requires_python, + '.'.join(map(str, sys.version_info[:3])),) + ) + except specifiers.InvalidSpecifier as e: + logger.warning( + "Package %s has an invalid Requires-Python entry %s - %s", + dist.project_name, requires_python, e, + ) + return + + +def get_installer(dist): + if dist.has_metadata('INSTALLER'): + for line in dist.get_metadata_lines('INSTALLER'): + if line.strip(): + return line.strip() + return '' diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py b/env/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py new file mode 100644 index 0000000..03973e9 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/setuptools_build.py @@ -0,0 +1,8 @@ +# Shim to wrap setup.py invocation with setuptools +SETUPTOOLS_SHIM = ( + "import setuptools, tokenize;__file__=%r;" + "f=getattr(tokenize, 'open', open)(__file__);" + "code=f.read().replace('\\r\\n', '\\n');" + "f.close();" + "exec(compile(code, __file__, 'exec'))" +) diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py b/env/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py new file mode 100644 index 0000000..edc506b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/temp_dir.py @@ -0,0 +1,82 @@ +from __future__ import absolute_import + +import logging +import os.path +import tempfile + +from pip._internal.utils.misc import rmtree + +logger = logging.getLogger(__name__) + + +class TempDirectory(object): + """Helper class that owns and cleans up a temporary directory. + + This class can be used as a context manager or as an OO representation of a + temporary directory. + + Attributes: + path + Location to the created temporary directory or None + delete + Whether the directory should be deleted when exiting + (when used as a contextmanager) + + Methods: + create() + Creates a temporary directory and stores its path in the path + attribute. + cleanup() + Deletes the temporary directory and sets path attribute to None + + When used as a context manager, a temporary directory is created on + entering the context and, if the delete attribute is True, on exiting the + context the created directory is deleted. + """ + + def __init__(self, path=None, delete=None, kind="temp"): + super(TempDirectory, self).__init__() + + if path is None and delete is None: + # If we were not given an explicit directory, and we were not given + # an explicit delete option, then we'll default to deleting. + delete = True + + self.path = path + self.delete = delete + self.kind = kind + + def __repr__(self): + return "<{} {!r}>".format(self.__class__.__name__, self.path) + + def __enter__(self): + self.create() + return self + + def __exit__(self, exc, value, tb): + if self.delete: + self.cleanup() + + def create(self): + """Create a temporary directory and store it's path in self.path + """ + if self.path is not None: + logger.debug( + "Skipped creation of temporary directory: {}".format(self.path) + ) + return + # We realpath here because some systems have their default tmpdir + # symlinked to another directory. This tends to confuse build + # scripts, so we canonicalize the path by traversing potential + # symlinks here. + self.path = os.path.realpath( + tempfile.mkdtemp(prefix="pip-{}-".format(self.kind)) + ) + logger.debug("Created temporary directory: {}".format(self.path)) + + def cleanup(self): + """Remove the temporary directory created and reset state + """ + if self.path is not None and os.path.exists(self.path): + rmtree(self.path) + self.path = None diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/typing.py b/env/lib/python3.7/site-packages/pip/_internal/utils/typing.py new file mode 100644 index 0000000..e085cdf --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/typing.py @@ -0,0 +1,29 @@ +"""For neatly implementing static typing in pip. + +`mypy` - the static type analysis tool we use - uses the `typing` module, which +provides core functionality fundamental to mypy's functioning. + +Generally, `typing` would be imported at runtime and used in that fashion - +it acts as a no-op at runtime and does not have any run-time overhead by +design. + +As it turns out, `typing` is not vendorable - it uses separate sources for +Python 2/Python 3. Thus, this codebase can not expect it to be present. +To work around this, mypy allows the typing import to be behind a False-y +optional to prevent it from running at runtime and type-comments can be used +to remove the need for the types to be accessible directly during runtime. + +This module provides the False-y guard in a nicely named fashion so that a +curious maintainer can reach here to read this. + +In pip, all static-typing related imports should be guarded as follows: + + from pip._internal.utils.typing import MYPY_CHECK_RUNNING + + if MYPY_CHECK_RUNNING: + from typing import ... # noqa: F401 + +Ref: https://github.com/python/mypy/issues/3216 +""" + +MYPY_CHECK_RUNNING = False diff --git a/env/lib/python3.7/site-packages/pip/_internal/utils/ui.py b/env/lib/python3.7/site-packages/pip/_internal/utils/ui.py new file mode 100644 index 0000000..6bab904 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/utils/ui.py @@ -0,0 +1,421 @@ +from __future__ import absolute_import, division + +import contextlib +import itertools +import logging +import sys +import time +from signal import SIGINT, default_int_handler, signal + +from pip._vendor import six +from pip._vendor.progress.bar import ( + Bar, ChargingBar, FillingCirclesBar, FillingSquaresBar, IncrementalBar, + ShadyBar, +) +from pip._vendor.progress.helpers import HIDE_CURSOR, SHOW_CURSOR, WritelnMixin +from pip._vendor.progress.spinner import Spinner + +from pip._internal.utils.compat import WINDOWS +from pip._internal.utils.logging import get_indentation +from pip._internal.utils.misc import format_size +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Any # noqa: F401 + +try: + from pip._vendor import colorama +# Lots of different errors can come from this, including SystemError and +# ImportError. +except Exception: + colorama = None + +logger = logging.getLogger(__name__) + + +def _select_progress_class(preferred, fallback): + encoding = getattr(preferred.file, "encoding", None) + + # If we don't know what encoding this file is in, then we'll just assume + # that it doesn't support unicode and use the ASCII bar. + if not encoding: + return fallback + + # Collect all of the possible characters we want to use with the preferred + # bar. + characters = [ + getattr(preferred, "empty_fill", six.text_type()), + getattr(preferred, "fill", six.text_type()), + ] + characters += list(getattr(preferred, "phases", [])) + + # Try to decode the characters we're using for the bar using the encoding + # of the given file, if this works then we'll assume that we can use the + # fancier bar and if not we'll fall back to the plaintext bar. + try: + six.text_type().join(characters).encode(encoding) + except UnicodeEncodeError: + return fallback + else: + return preferred + + +_BaseBar = _select_progress_class(IncrementalBar, Bar) # type: Any + + +class InterruptibleMixin(object): + """ + Helper to ensure that self.finish() gets called on keyboard interrupt. + + This allows downloads to be interrupted without leaving temporary state + (like hidden cursors) behind. + + This class is similar to the progress library's existing SigIntMixin + helper, but as of version 1.2, that helper has the following problems: + + 1. It calls sys.exit(). + 2. It discards the existing SIGINT handler completely. + 3. It leaves its own handler in place even after an uninterrupted finish, + which will have unexpected delayed effects if the user triggers an + unrelated keyboard interrupt some time after a progress-displaying + download has already completed, for example. + """ + + def __init__(self, *args, **kwargs): + """ + Save the original SIGINT handler for later. + """ + super(InterruptibleMixin, self).__init__(*args, **kwargs) + + self.original_handler = signal(SIGINT, self.handle_sigint) + + # If signal() returns None, the previous handler was not installed from + # Python, and we cannot restore it. This probably should not happen, + # but if it does, we must restore something sensible instead, at least. + # The least bad option should be Python's default SIGINT handler, which + # just raises KeyboardInterrupt. + if self.original_handler is None: + self.original_handler = default_int_handler + + def finish(self): + """ + Restore the original SIGINT handler after finishing. + + This should happen regardless of whether the progress display finishes + normally, or gets interrupted. + """ + super(InterruptibleMixin, self).finish() + signal(SIGINT, self.original_handler) + + def handle_sigint(self, signum, frame): + """ + Call self.finish() before delegating to the original SIGINT handler. + + This handler should only be in place while the progress display is + active. + """ + self.finish() + self.original_handler(signum, frame) + + +class SilentBar(Bar): + + def update(self): + pass + + +class BlueEmojiBar(IncrementalBar): + + suffix = "%(percent)d%%" + bar_prefix = " " + bar_suffix = " " + phases = (u"\U0001F539", u"\U0001F537", u"\U0001F535") # type: Any + + +class DownloadProgressMixin(object): + + def __init__(self, *args, **kwargs): + super(DownloadProgressMixin, self).__init__(*args, **kwargs) + self.message = (" " * (get_indentation() + 2)) + self.message + + @property + def downloaded(self): + return format_size(self.index) + + @property + def download_speed(self): + # Avoid zero division errors... + if self.avg == 0.0: + return "..." + return format_size(1 / self.avg) + "/s" + + @property + def pretty_eta(self): + if self.eta: + return "eta %s" % self.eta_td + return "" + + def iter(self, it, n=1): + for x in it: + yield x + self.next(n) + self.finish() + + +class WindowsMixin(object): + + def __init__(self, *args, **kwargs): + # The Windows terminal does not support the hide/show cursor ANSI codes + # even with colorama. So we'll ensure that hide_cursor is False on + # Windows. + # This call neds to go before the super() call, so that hide_cursor + # is set in time. The base progress bar class writes the "hide cursor" + # code to the terminal in its init, so if we don't set this soon + # enough, we get a "hide" with no corresponding "show"... + if WINDOWS and self.hide_cursor: + self.hide_cursor = False + + super(WindowsMixin, self).__init__(*args, **kwargs) + + # Check if we are running on Windows and we have the colorama module, + # if we do then wrap our file with it. + if WINDOWS and colorama: + self.file = colorama.AnsiToWin32(self.file) + # The progress code expects to be able to call self.file.isatty() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.isatty = lambda: self.file.wrapped.isatty() + # The progress code expects to be able to call self.file.flush() + # but the colorama.AnsiToWin32() object doesn't have that, so we'll + # add it. + self.file.flush = lambda: self.file.wrapped.flush() + + +class BaseDownloadProgressBar(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin): + + file = sys.stdout + message = "%(percent)d%%" + suffix = "%(downloaded)s %(download_speed)s %(pretty_eta)s" + +# NOTE: The "type: ignore" comments on the following classes are there to +# work around https://github.com/python/typing/issues/241 + + +class DefaultDownloadProgressBar(BaseDownloadProgressBar, + _BaseBar): # type: ignore + pass + + +class DownloadSilentBar(BaseDownloadProgressBar, SilentBar): # type: ignore + pass + + +class DownloadIncrementalBar(BaseDownloadProgressBar, # type: ignore + IncrementalBar): + pass + + +class DownloadChargingBar(BaseDownloadProgressBar, # type: ignore + ChargingBar): + pass + + +class DownloadShadyBar(BaseDownloadProgressBar, ShadyBar): # type: ignore + pass + + +class DownloadFillingSquaresBar(BaseDownloadProgressBar, # type: ignore + FillingSquaresBar): + pass + + +class DownloadFillingCirclesBar(BaseDownloadProgressBar, # type: ignore + FillingCirclesBar): + pass + + +class DownloadBlueEmojiProgressBar(BaseDownloadProgressBar, # type: ignore + BlueEmojiBar): + pass + + +class DownloadProgressSpinner(WindowsMixin, InterruptibleMixin, + DownloadProgressMixin, WritelnMixin, Spinner): + + file = sys.stdout + suffix = "%(downloaded)s %(download_speed)s" + + def next_phase(self): + if not hasattr(self, "_phaser"): + self._phaser = itertools.cycle(self.phases) + return next(self._phaser) + + def update(self): + message = self.message % self + phase = self.next_phase() + suffix = self.suffix % self + line = ''.join([ + message, + " " if message else "", + phase, + " " if suffix else "", + suffix, + ]) + + self.writeln(line) + + +BAR_TYPES = { + "off": (DownloadSilentBar, DownloadSilentBar), + "on": (DefaultDownloadProgressBar, DownloadProgressSpinner), + "ascii": (DownloadIncrementalBar, DownloadProgressSpinner), + "pretty": (DownloadFillingCirclesBar, DownloadProgressSpinner), + "emoji": (DownloadBlueEmojiProgressBar, DownloadProgressSpinner) +} + + +def DownloadProgressProvider(progress_bar, max=None): + if max is None or max == 0: + return BAR_TYPES[progress_bar][1]().iter + else: + return BAR_TYPES[progress_bar][0](max=max).iter + + +################################################################ +# Generic "something is happening" spinners +# +# We don't even try using progress.spinner.Spinner here because it's actually +# simpler to reimplement from scratch than to coerce their code into doing +# what we need. +################################################################ + +@contextlib.contextmanager +def hidden_cursor(file): + # The Windows terminal does not support the hide/show cursor ANSI codes, + # even via colorama. So don't even try. + if WINDOWS: + yield + # We don't want to clutter the output with control characters if we're + # writing to a file, or if the user is running with --quiet. + # See https://github.com/pypa/pip/issues/3418 + elif not file.isatty() or logger.getEffectiveLevel() > logging.INFO: + yield + else: + file.write(HIDE_CURSOR) + try: + yield + finally: + file.write(SHOW_CURSOR) + + +class RateLimiter(object): + def __init__(self, min_update_interval_seconds): + self._min_update_interval_seconds = min_update_interval_seconds + self._last_update = 0 + + def ready(self): + now = time.time() + delta = now - self._last_update + return delta >= self._min_update_interval_seconds + + def reset(self): + self._last_update = time.time() + + +class InteractiveSpinner(object): + def __init__(self, message, file=None, spin_chars="-\\|/", + # Empirically, 8 updates/second looks nice + min_update_interval_seconds=0.125): + self._message = message + if file is None: + file = sys.stdout + self._file = file + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._finished = False + + self._spin_cycle = itertools.cycle(spin_chars) + + self._file.write(" " * get_indentation() + self._message + " ... ") + self._width = 0 + + def _write(self, status): + assert not self._finished + # Erase what we wrote before by backspacing to the beginning, writing + # spaces to overwrite the old text, and then backspacing again + backup = "\b" * self._width + self._file.write(backup + " " * self._width + backup) + # Now we have a blank slate to add our status + self._file.write(status) + self._width = len(status) + self._file.flush() + self._rate_limiter.reset() + + def spin(self): + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._write(next(self._spin_cycle)) + + def finish(self, final_status): + if self._finished: + return + self._write(final_status) + self._file.write("\n") + self._file.flush() + self._finished = True + + +# Used for dumb terminals, non-interactive installs (no tty), etc. +# We still print updates occasionally (once every 60 seconds by default) to +# act as a keep-alive for systems like Travis-CI that take lack-of-output as +# an indication that a task has frozen. +class NonInteractiveSpinner(object): + def __init__(self, message, min_update_interval_seconds=60): + self._message = message + self._finished = False + self._rate_limiter = RateLimiter(min_update_interval_seconds) + self._update("started") + + def _update(self, status): + assert not self._finished + self._rate_limiter.reset() + logger.info("%s: %s", self._message, status) + + def spin(self): + if self._finished: + return + if not self._rate_limiter.ready(): + return + self._update("still running...") + + def finish(self, final_status): + if self._finished: + return + self._update("finished with status '%s'" % (final_status,)) + self._finished = True + + +@contextlib.contextmanager +def open_spinner(message): + # Interactive spinner goes directly to sys.stdout rather than being routed + # through the logging system, but it acts like it has level INFO, + # i.e. it's only displayed if we're at level INFO or better. + # Non-interactive spinner goes through the logging system, so it is always + # in sync with logging configuration. + if sys.stdout.isatty() and logger.getEffectiveLevel() <= logging.INFO: + spinner = InteractiveSpinner(message) + else: + spinner = NonInteractiveSpinner(message) + try: + with hidden_cursor(sys.stdout): + yield spinner + except KeyboardInterrupt: + spinner.finish("canceled") + raise + except Exception: + spinner.finish("error") + raise + else: + spinner.finish("done") diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py b/env/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py new file mode 100644 index 0000000..794b35d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/vcs/__init__.py @@ -0,0 +1,509 @@ +"""Handles all VCS (version control) support""" +from __future__ import absolute_import + +import errno +import logging +import os +import shutil +import sys + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.exceptions import BadCommand +from pip._internal.utils.misc import ( + display_path, backup_dir, call_subprocess, rmtree, ask_path_exists, +) +from pip._internal.utils.typing import MYPY_CHECK_RUNNING + +if MYPY_CHECK_RUNNING: + from typing import Dict, Optional, Tuple # noqa: F401 + from pip._internal.cli.base_command import Command # noqa: F401 + +__all__ = ['vcs', 'get_src_requirement'] + + +logger = logging.getLogger(__name__) + + +class RevOptions(object): + + """ + Encapsulates a VCS-specific revision to install, along with any VCS + install options. + + Instances of this class should be treated as if immutable. + """ + + def __init__(self, vcs, rev=None, extra_args=None): + """ + Args: + vcs: a VersionControl object. + rev: the name of the revision to install. + extra_args: a list of extra options. + """ + if extra_args is None: + extra_args = [] + + self.extra_args = extra_args + self.rev = rev + self.vcs = vcs + + def __repr__(self): + return '<RevOptions {}: rev={!r}>'.format(self.vcs.name, self.rev) + + @property + def arg_rev(self): + if self.rev is None: + return self.vcs.default_arg_rev + + return self.rev + + def to_args(self): + """ + Return the VCS-specific command arguments. + """ + args = [] + rev = self.arg_rev + if rev is not None: + args += self.vcs.get_base_rev_args(rev) + args += self.extra_args + + return args + + def to_display(self): + if not self.rev: + return '' + + return ' (to revision {})'.format(self.rev) + + def make_new(self, rev): + """ + Make a copy of the current instance, but with a new rev. + + Args: + rev: the name of the revision for the new object. + """ + return self.vcs.make_rev_options(rev, extra_args=self.extra_args) + + +class VcsSupport(object): + _registry = {} # type: Dict[str, Command] + schemes = ['ssh', 'git', 'hg', 'bzr', 'sftp', 'svn'] + + def __init__(self): + # Register more schemes with urlparse for various version control + # systems + urllib_parse.uses_netloc.extend(self.schemes) + # Python >= 2.7.4, 3.3 doesn't have uses_fragment + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(self.schemes) + super(VcsSupport, self).__init__() + + def __iter__(self): + return self._registry.__iter__() + + @property + def backends(self): + return list(self._registry.values()) + + @property + def dirnames(self): + return [backend.dirname for backend in self.backends] + + @property + def all_schemes(self): + schemes = [] + for backend in self.backends: + schemes.extend(backend.schemes) + return schemes + + def register(self, cls): + if not hasattr(cls, 'name'): + logger.warning('Cannot register VCS %s', cls.__name__) + return + if cls.name not in self._registry: + self._registry[cls.name] = cls + logger.debug('Registered VCS backend: %s', cls.name) + + def unregister(self, cls=None, name=None): + if name in self._registry: + del self._registry[name] + elif cls in self._registry.values(): + del self._registry[cls.name] + else: + logger.warning('Cannot unregister because no class or name given') + + def get_backend_name(self, location): + """ + Return the name of the version control backend if found at given + location, e.g. vcs.get_backend_name('/path/to/vcs/checkout') + """ + for vc_type in self._registry.values(): + if vc_type.controls_location(location): + logger.debug('Determine that %s uses VCS: %s', + location, vc_type.name) + return vc_type.name + return None + + def get_backend(self, name): + name = name.lower() + if name in self._registry: + return self._registry[name] + + def get_backend_from_location(self, location): + vc_type = self.get_backend_name(location) + if vc_type: + return self.get_backend(vc_type) + return None + + +vcs = VcsSupport() + + +class VersionControl(object): + name = '' + dirname = '' + # List of supported schemes for this Version Control + schemes = () # type: Tuple[str, ...] + # Iterable of environment variable names to pass to call_subprocess(). + unset_environ = () # type: Tuple[str, ...] + default_arg_rev = None # type: Optional[str] + + def __init__(self, url=None, *args, **kwargs): + self.url = url + super(VersionControl, self).__init__(*args, **kwargs) + + def get_base_rev_args(self, rev): + """ + Return the base revision arguments for a vcs command. + + Args: + rev: the name of a revision to install. Cannot be None. + """ + raise NotImplementedError + + def make_rev_options(self, rev=None, extra_args=None): + """ + Return a RevOptions object. + + Args: + rev: the name of a revision to install. + extra_args: a list of extra options. + """ + return RevOptions(self, rev, extra_args=extra_args) + + def _is_local_repository(self, repo): + """ + posix absolute paths start with os.path.sep, + win32 ones start with drive (like c:\\folder) + """ + drive, tail = os.path.splitdrive(repo) + return repo.startswith(os.path.sep) or drive + + def export(self, location): + """ + Export the repository at the url to the destination location + i.e. only download the files, without vcs informations + """ + raise NotImplementedError + + def get_netloc_and_auth(self, netloc, scheme): + """ + Parse the repository URL's netloc, and return the new netloc to use + along with auth information. + + Args: + netloc: the original repository URL netloc. + scheme: the repository URL's scheme without the vcs prefix. + + This is mainly for the Subversion class to override, so that auth + information can be provided via the --username and --password options + instead of through the URL. For other subclasses like Git without + such an option, auth information must stay in the URL. + + Returns: (netloc, (username, password)). + """ + return netloc, (None, None) + + def get_url_rev_and_auth(self, url): + """ + Parse the repository URL to use, and return the URL, revision, + and auth info to use. + + Returns: (url, rev, (username, password)). + """ + scheme, netloc, path, query, frag = urllib_parse.urlsplit(url) + if '+' not in scheme: + raise ValueError( + "Sorry, {!r} is a malformed VCS url. " + "The format is <vcs>+<protocol>://<url>, " + "e.g. svn+http://myrepo/svn/MyApp#egg=MyApp".format(url) + ) + # Remove the vcs prefix. + scheme = scheme.split('+', 1)[1] + netloc, user_pass = self.get_netloc_and_auth(netloc, scheme) + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + url = urllib_parse.urlunsplit((scheme, netloc, path, query, '')) + return url, rev, user_pass + + def make_rev_args(self, username, password): + """ + Return the RevOptions "extra arguments" to use in obtain(). + """ + return [] + + def get_url_rev_options(self, url): + """ + Return the URL and RevOptions object to use in obtain() and in + some cases export(), as a tuple (url, rev_options). + """ + url, rev, user_pass = self.get_url_rev_and_auth(url) + username, password = user_pass + extra_args = self.make_rev_args(username, password) + rev_options = self.make_rev_options(rev, extra_args=extra_args) + + return url, rev_options + + def normalize_url(self, url): + """ + Normalize a URL for comparison by unquoting it and removing any + trailing slash. + """ + return urllib_parse.unquote(url).rstrip('/') + + def compare_urls(self, url1, url2): + """ + Compare two repo URLs for identity, ignoring incidental differences. + """ + return (self.normalize_url(url1) == self.normalize_url(url2)) + + def fetch_new(self, dest, url, rev_options): + """ + Fetch a revision from a repository, in the case that this is the + first fetch from the repository. + + Args: + dest: the directory to fetch the repository to. + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def switch(self, dest, url, rev_options): + """ + Switch the repo at ``dest`` to point to ``URL``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def update(self, dest, url, rev_options): + """ + Update an already-existing repo to the given ``rev_options``. + + Args: + rev_options: a RevOptions object. + """ + raise NotImplementedError + + def is_commit_id_equal(self, dest, name): + """ + Return whether the id of the current commit equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + raise NotImplementedError + + def obtain(self, dest): + """ + Install or update in editable mode the package represented by this + VersionControl object. + + Args: + dest: the repository directory in which to install or update. + """ + url, rev_options = self.get_url_rev_options(self.url) + + if not os.path.exists(dest): + self.fetch_new(dest, url, rev_options) + return + + rev_display = rev_options.to_display() + if self.is_repository_directory(dest): + existing_url = self.get_url(dest) + if self.compare_urls(existing_url, url): + logger.debug( + '%s in %s exists, and has correct URL (%s)', + self.repo_name.title(), + display_path(dest), + url, + ) + if not self.is_commit_id_equal(dest, rev_options.rev): + logger.info( + 'Updating %s %s%s', + display_path(dest), + self.repo_name, + rev_display, + ) + self.update(dest, url, rev_options) + else: + logger.info('Skipping because already up-to-date.') + return + + logger.warning( + '%s %s in %s exists with URL %s', + self.name, + self.repo_name, + display_path(dest), + existing_url, + ) + prompt = ('(s)witch, (i)gnore, (w)ipe, (b)ackup ', + ('s', 'i', 'w', 'b')) + else: + logger.warning( + 'Directory %s already exists, and is not a %s %s.', + dest, + self.name, + self.repo_name, + ) + prompt = ('(i)gnore, (w)ipe, (b)ackup ', ('i', 'w', 'b')) + + logger.warning( + 'The plan is to install the %s repository %s', + self.name, + url, + ) + response = ask_path_exists('What to do? %s' % prompt[0], prompt[1]) + + if response == 'a': + sys.exit(-1) + + if response == 'w': + logger.warning('Deleting %s', display_path(dest)) + rmtree(dest) + self.fetch_new(dest, url, rev_options) + return + + if response == 'b': + dest_dir = backup_dir(dest) + logger.warning( + 'Backing up %s to %s', display_path(dest), dest_dir, + ) + shutil.move(dest, dest_dir) + self.fetch_new(dest, url, rev_options) + return + + # Do nothing if the response is "i". + if response == 's': + logger.info( + 'Switching %s %s to %s%s', + self.repo_name, + display_path(dest), + url, + rev_display, + ) + self.switch(dest, url, rev_options) + + def unpack(self, location): + """ + Clean up current location and download the url repository + (and vcs infos) into location + """ + if os.path.exists(location): + rmtree(location) + self.obtain(location) + + def get_src_requirement(self, dist, location): + """ + Return a string representing the requirement needed to + redownload the files currently present in location, something + like: + {repository_url}@{revision}#egg={project_name}-{version_identifier} + """ + raise NotImplementedError + + def get_url(self, location): + """ + Return the url used at location + """ + raise NotImplementedError + + def get_revision(self, location): + """ + Return the current commit id of the files at the given location. + """ + raise NotImplementedError + + def run_command(self, cmd, show_stdout=True, cwd=None, + on_returncode='raise', + command_desc=None, + extra_environ=None, spinner=None): + """ + Run a VCS subcommand + This is simply a wrapper around call_subprocess that adds the VCS + command name, and checks that the VCS is available + """ + cmd = [self.name] + cmd + try: + return call_subprocess(cmd, show_stdout, cwd, + on_returncode, + command_desc, extra_environ, + unset_environ=self.unset_environ, + spinner=spinner) + except OSError as e: + # errno.ENOENT = no such file or directory + # In other words, the VCS executable isn't available + if e.errno == errno.ENOENT: + raise BadCommand( + 'Cannot find command %r - do you have ' + '%r installed and in your ' + 'PATH?' % (self.name, self.name)) + else: + raise # re-raise exception if a different error occurred + + @classmethod + def is_repository_directory(cls, path): + """ + Return whether a directory path is a repository directory. + """ + logger.debug('Checking in %s for %s (%s)...', + path, cls.dirname, cls.name) + return os.path.exists(os.path.join(path, cls.dirname)) + + @classmethod + def controls_location(cls, location): + """ + Check if a location is controlled by the vcs. + It is meant to be overridden to implement smarter detection + mechanisms for specific vcs. + + This can do more than is_repository_directory() alone. For example, + the Git override checks that Git is actually available. + """ + return cls.is_repository_directory(location) + + +def get_src_requirement(dist, location): + version_control = vcs.get_backend_from_location(location) + if version_control: + try: + return version_control().get_src_requirement(dist, + location) + except BadCommand: + logger.warning( + 'cannot determine version of editable source in %s ' + '(%s command not found in path)', + location, + version_control.name, + ) + return dist.as_requirement() + logger.warning( + 'cannot determine version of editable source in %s (is not SVN ' + 'checkout, Git clone, Mercurial clone or Bazaar branch)', + location, + ) + return dist.as_requirement() diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..411f9aba3263e8f79eec0324dce2c056ce37e2d9 GIT binary patch literal 15514 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/bazaar.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c8bd1ffd9c6532408cc00a632388c28eb89fd2ae GIT binary patch literal 3777 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 P!nK1GyCa%T=P&;Q$=0Ge literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/git.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb770c6637f61ecf92d6bc12e93d06721d0da3b4 GIT binary patch literal 9082 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 IuKeJC03J#a-2eap literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/mercurial.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d7a86f69509de1444b76330d740a35e7eacadff8 GIT binary patch literal 3750 zcmbVPNpl;=6`r0QAP9mKB}<NyLXwgaL`AA9<;p=N+lpm7sVwv&J91E|nvAELz)-V5 z-3>yTfVs$r9HP=s2zbmbzo)M``7ik7?=?tpkxm9{x_f$?_rCYNg&(Z1w;lY3|GE9Q zSL=@Re|kCn`4~LFqyB}4JDe3x$%c&4*e%?lYkP0#q4x^E42FSS^NX;IhLIfyMO?Oq zt+G9A+xM_oD?7uE9Y@7_*&TMvjo}7!guCd8&0{v)`kljL-ulMjEzy194X=oe#kRO| zOy6}MIfM4Mkj5D>vypzS>SC%zl9!WO>OIVLvbx&ON0U@4A@RO8N%c6<buyL3z%?D7 zt4WbQPiWd)FViO?Im}cd#nWjnMJXz6cQUj7g(xQ<VlLCQe2$~tzX+-Fx_VewTGoZ} za4sWBPJb>25Adi0jc|sHJ3xp59e3z+Zy0cY81jIJ-#EjFM?6LkJ$V~_i?8tx`ZizZ zUG!^wgZI#P_$J>%zs|4lZS-A!m0v@@!QbN7(f9ZbAo8|p{aMItD)Y23?s(LAyW^1w zvZAiUAdqX2r-{a+J7cXUO?)y?O^A_F<EBf!PIaE`(2k50p&#`O&qF*aL^Ee2hR?CR z|2hD~SEATAo)m`?#Bpr%-Tk||oZOw{lbyW6okg*e%|_LMe)<kg+9$~?Eo7AzcY)yD z@>KBM$#b(g5<2-hRRRV%Oj0>g*XY|;AlCe7rR45w`&L4GIMBjlg}#r025-6hlD+!n zkvn%5Z0;Vo#HG1&;BgNsx!k8Y9=!CJ^Vs3xXU^x&SLmT?)V%-EGvZcXk469YqrMcA zTIEEEe!83lvHH5U>s%<ER{*lE`bC}DfeD4Z09^E+<P|qjDzkBZC_V;+YieB25~X=P z)yB(ad~e{(2tu21T20dIiSaE_*W|QHvbrqOiVr;5r5*9=3$X@O6Q0X6JIEfk$SpKC z@TeG#<91lb^;y$9gK;TZMt)8|vN3(#V)r=)b8q1sJ4e1|3ov=^&V3EUUa(`I@LTxY z<sP926a(v@;P}YJso>ao%Q*^wu|E&yjE65>@_0gYuetgV#LTNve?02nQnwVrcT33* zKG?K(cB*<h;i(plyYmz{*ztf#V!|LaZTRwu6PvK8M<XGPpI7^}46s3xx+cONBF`XP zLgkZTj0a1ZH6m6$Arq<P%jsotR&sml5{jm^FLX9eDlz*RE>{Gq!(!$$*Z#HLZPsJW zl`~XV`&YmcAt}sSVE>1Kb`AjPoLLgGV-FDf1lm#X{Qf*xgmd3gG+0Cg@!UNIHFZ4q zx&Oj_)jJBYr!^004+!fl3H#Woe&aj3t^I?wefLRQ{+l^R2*S;l?kv`M05e5&51rsx z`DgT%^H-<p6V-WS&DOPMiy_s<JcilgmDyT*#vhMlW&$FlG7%U1>9o*>&6>Lp>uJIJ zRjvDKmIJH)3XAjpVy%3SEPWFQkabV3+B0sg<aNv%|Det*+@2#qltPj>o8F^zUm)xv zu77Idy78q*x$%_H#;+%$GQmvdTA1jQM;}R9OViz}A0cwX%JyCUgzkxEsU+UXKHe-- z1}#ev`BR!8>&l;_Azn;s_#1uEgeU#lvQPH&LKsgx%j7LOunK+F<xIFlU>8e@6mr-W zxZ<)l>#`2J&aQzsH$Cv>oEI*StjIz<CXcjac?ScS!^SX}h;h%F1fFLN#;n17+A;T6 ztK??^3^th-#W|cU?gQ6qZZSY^pipv2{Ws}lkG_Y!HV=?e7gbn#>4hLnYFHJ1eL)2Z zx!iy0Eg-rL$S&B;<gXA|+!qWpF0CvTXj6Dx!rrV~-tC^y4#87iCDCnE@Rx2MC@u4e z*-mnmP;e}eMNXr&Bt%a_r+k}ET615rUPO5XVZzEy@yLO>LYS@%BQ~2WTHE}CeQ#En z=zV6hOA1p31KUKXP*7~Brnj?0;k!V<d-op*PDdA2JF(WgxbnR8riW}#7f_<isVuon z#15%)y7)&NUnYSQeVS_*bvfPmgB6kw@QG&gyfRhI#ShRX8K-J|SsPmzoC;}oeD<13 zm&$_+yE6~l=|?GU<y?Qj3(}ZF3_S9Xw!l0}bjM8fIno$Xn1^+Wzw8L^weYbXP|7<- zxo`u~T8DEFju*V}VAgQ2@y4Tj)ZF=w?R-nMlcZ)4$@kHjpr~g^S8WtVQj^z@<%cvM zi_s{dcxM7sr@59S<yrE|!E2%{g+0_FL{8JABNJI4Aj;XJml3-{_E$0k2Uex+W1Ljv z@s5p0G1_g=yZP}&GF&>f!j3Rp)q?~gr)tn`ZvVEJrO#DARccxaTL~R5Yh}P#SHIBx zGDTMS*ot_{VhXv&w?Y1r6K=tMsn*GLlJf-8r^Vl~d07Rz&CN4mU*EVl*feos0Z9_m zPLi_b(?Vd}NfNq=KA0r(6I>{FNQ9P+^%nd{Wn=scpyVd4Ql6K$skuiDIkmN-{D4Me zH@Qd6r_`LOU`Mw4qJ&QaMMtS#uzzms#jUs#_u?Rq;}Cx>NjnEuN!<OZo=OtX#gvJt zzM+J5hu*HDfZk0GMa65mtMX^NWqk-?$tvcWT{|tTcX>UliaO;s>Y3{o7pFQe)NYxp zY*{i9+04y1?OD~8wj|xWxCO<#q`Fd4absGb+n;PTCdo5x!nJytSc(xCEY4S_E09cl de`%rjh*)YHO~;K{>~>JC_K-1qZrkg9`90&^txEs^ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_internal/vcs/__pycache__/subversion.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc9de523adaeb89c7d24593269131c2fdb8b9563 GIT binary patch literal 6352 zcmbtZ%WoUU8Q+;*E|)7xq8`@6b{xiWQZtF9BxsQb6vwrlM}bs8oHj`r+bqplQ7bLE z)XY*3f^31xZ7vPc0zI_3l<KK1a_FI_{sBGbJlCH55A<LZXn)@<NlCQPLrY<2XXo+F z%=i3#qZ^ZxzJ*`;_s`$?*Hf1D5BeDX98|93QGZ1tEWskH!ODzLokzUP&D$>9=IxXn zyzMB{aLcY4<3!npSN2Rj6XhCy*>6mgCmQ*3zA;&zH0^FQ)tD|%HwxtfvjV3-BeKV= zJZowmYICNRLv7yFeALbbyuT1EqPFy&B_>4vfhF?6^pRa&4hsGA!SXTfk$+^BCLdzw zR*C89>U|YQ?Ifs#jaDp^4YWBQgv}ki{je#5W>Sgbddbmw5vo>HJ*>2<$(CMfRCj{P zUQJbGu-gu0(4diR8EIEG5*Y+~0i(mDQf((&l}#BpD$O8?;#!I8sgDDx!nk=eZYDC0 zv<)(yNz8rg^3~7oUB3Hb>2l{>Ep9ZzBniZd4EE4*M^N+J9rXgfLz+HnoL<M=Ygboa zD6Owitwv`X{_H_T{T7wLDl=h0J`A$qkc(Z;2&e3djBp=V<*djG4{uN8gpYSF<zd+u zlVS?r6JlBv@Xm`FF^l))=hh|@b7KC1SDrHUb7BGYX|X7l&|eVC;ym6n;)1w{_pEqI zT*7-!JS~cN&wp+?R{0#{@r?FAYTw^W`J!#L*X%f}D79DH3TiuXJ1J#k9w+Ez(fXoN zTOE%oTS?OD<c2jh=-q49_~6*|rspOe<)IL)%j%>8e51ox<eyN{jtZhpZG*9L3PVis z=&iM+(OPSTt(CB;l4=yK)b{Jm?PT}c)M%bc*h~W1tVU~);F=m8V6}CqXX-&xxnETQ z6lAYbm30LxvXt2u>s&lJ?doF#N1M-JMh=hJe1uBZ>f_mF$LtR8@t&RVzKsL%E<3iF zl{iP%m)G#lY`gs|+L(MZ@w)8DXnmb^?SAgqTC`|<oiAEF2ekYyv_LptaAtjCiOh%A zZR=CK!63JD{hb4{iDI%96v5-73|g@YlUN=Wt7$9Lt(e4SfCy9)HmeCVvj{ymmCiFM zg|Jy4C-9u2iO(tR24<0WVQ>>_E8efDL_ppfrHS$!u?9;R7RD_it+b5>?ZPJOfz(de z+>9mpBh6!_9b=oI7^+0cEH!77*l=G@$ab?rR#j~ZDAP1`dc%#%bM!euq8hH_)f&Rg zJkbd`gHdu0MG=o8U9ot9Pce_>ZI3Om&de#frst~B=IH0*p&c1v-arN7u#O>wg!N&N z5Q>x7B&=hHoRqNZ93z}F0?R-FGTn@EV-`f@Y;+cHl7SF|!8Gu5$X7XuC7|KEC0G04 z!N7aT1vJY=DoDHJ1u8D0D7h(19Fn79hrER5lqbW<Pt)j;i5Pb1+-8u}w&30NSJ0~p zC@e6<Vch)re2I1DPqAe*e8d^r2)QZ4nJcIWW|S4&IjgLF)^$c_=NsBp`ytjY@l(f0 zB`co+nUhn<Cv05OO0VNlMndD#OG!U@kC(^yi2bJK^w<vDEm2K^|8a-UVV(7p9nPQC zuatC+I7dIyFM13YH&HqGahKn+?tTh40bM&{+YAQpsPnrnw9VOZ<#hqg>pJ8@ju93F z|2bc_jv47(FVn=>9(1kCwlh0iy3j?N9K|sgnPuqSt_ycTI_PdZVk-~-jo%~o>_diy zB^A&o+L_J=^*Z8TwN3$2JKJ&C)EN^Rbta1UVZ-)LaCoA9uv}dbK`WrxTRW^oh{Y<E z<O@W5m5MPH%#)uOn(}oFQ1d7(=Hrj_(Bqf5gE|<vcuEsb&l>q$^0y;4evJ>odi>xI zi3QPuO<?G6?$|xMN6fLd!M>fWe6?=Di*jP%y0u#%mQo+7YGQ3WFj@00>|?v<nijX~ z9y4_hV=Z`U+xYWr&%-zdX8)v{6%G{2ZeHwW<uAM0K6)_ztF!AQIXDgP2$5j7@Cm#+ zgpujo_KSnx?I3B(rt!^<>Ot6OH{ifi=um{yEFz>8H^V4U#Wr}2?_xdN3r?K(h>(%z zhR#BOG7QuswpQ}x5?G_1{c5zMvm!(gYy^NlK_f;GUq+vNk&5#)s!$<LBY+Hjx%LrI zWkM#lrEP4klrzppQi#;vaF^Pl_^BO`S2|<1s{O$xDw|F1qJx5g@!}C?Jy9=))HXm{ zk>y$$hc7@I^3aStn`L><`4soiGG*GP9@ml~jghgDYLnZbw;|ev3y0*+Csx9`))9wc z!KEKVCaF`0Y<TB)BbNSPD^x{dl?+8dl8E;a4-sYwE*4EtYowtRLGpf3Y*m#C1Vv1W z!+T+s29Kz%th5#3kOt;AMR8??hVREx6bHc!6jc&b@x3{mT>Rnf4^~GM0J+o_KyF60 zTiDbDj-^fXO+jk~WDSy)1ffcH8Y<kh6K)tFtq~xA=PH$2gtaS`R1_v&-oliS_(XH9 zjA#2W$j+rPLmXRZWRF8G8&1Cp0;f3)yRmz)&mQb1bz}0X0Ow&luvS=yy=jB<_D09W z`QBVx>o|lJOOCt=O6f7@PlJrnIVmt;7@>sJ`A}TbIpQ-C0HsPyzDIq=6PaVakIy|k z=`oFld93sF*fED_X1LHuqlV|Cjj5|B>ahPVlk;6dc))9~(KnY@@Xfn?@I5%4f1&{$ z)Q93XyBnNBdqW-3-mo9mbdbpElTePHGzktA-}LrqSA@SUI8+B_f`@mOP95&d@H5gI zdDD+Ey-VKo27Dkwk126Rgdg}y^)C7ls?g(*r!^9^DfA?nzDs9521ccjL!rm`O$u8! z1tS7No`Sz?0eW}dyBW75QEbKu{2T0H*kQaLd`3_+5Ee-3DmgS^JYlOU;aZBrZuq%U z8pk~2>QbLZ?ksg|-=P{|DV^P~$|mrad<|bil`)QNGL~U|6qocQEaN0hjr*$XKn;HZ zDrxv~9JXY5?b!%o+~u&E*;5=JOc?Q+jCPbQv=D;@LpF}gya&D|d>ddAHeqdNOdLY) zfEI*xWC`ylh(Sl}%P9f~eUHLF1@|-;Xgb0GfqqT^c&hDg1~rOaX$@Jq{5tWIi6p;0 ziM}a;?EHuyF#->QEn^pNS%X?`+3LB%7ZVTAa?3h`<PC7jHved-=0WS9$#lO!5Es$V zQ{N;r0#p|;_Ghf?^=HKtdR*k8ppne==V{~_O7{-eamI6^AZB1SwwM)jU+`WoSpZes z7K|v&8w!h{fL5Z=%YI@tiw@%Gj{hqrZ!?Sj1niJw*S+kItS0}|>Soa=lBI4IGkov{ zW!LTcn-qP|ZKNv0^vw6toYDC3cchG^B;Tbi&0g2+4b5M9xnuiz{~@`x8sR1SQF2IN z_#-^(B@~GF*4-;T1^|b|Kv+ADgbanXY)PaIY3+#pn(sPTojoM!Bb~LQps8)-rl|AP zmo*b(%J#@#kASm~47INPnbx9(U8}QpO1s8m_UbwTtVmr$WjME!S%3SW5p|YsR7G@1 z=7pezD~lp9Z}rXMb5fQ-_{{Oh8JOddDVgKVrpN2!SWukNVa!zE<}$|VOkKw97QQ~C zFV+}4kGzZKzu*}h#N;=f%*qNjhrCh}8vOrvA@70AU=Ol_`jd9?x079zmh}>D3RXwA z1gpV8El9Iid7I`FhB^h7j87rHXeS2#)s95SmK2G!Lp&#_)Iy|ABmfj$E&&?{N|K`J zX@jqD-T}r!P!6iHwx#`#t5G{hRgey#C(KB4>@v_EImi%~7$yhQ^QMpBN97c$vDS2| zd;`Qv6DPRM90_ng1&Qe`8QTPUgD#j5O6S=Fkb{n3Up5wy6jaB#NN)5iJn9+>3t<Kb zjj%g+IN^C8i5g)yDhb_F-$fue2RWyQWPFJiSb@9D$N0{L|Dw>N$V)0o(bq&?isI&$ z1rZ7H)`rb_a)F`_qOeVv9KD3>D49YGJGOv3kgOvua^T%Ei31GpbTda3nKK(H-jL6O zs!{0FKV;;G)bL#t+N1o4pqr7Sq|FSHA-P6_Oe6v4a1mo5NP)(;WW0?imd+bXh74>| zvUd7n^6#LOURQuyl$!(Xa%4l}AZ%>fh(+Y3$VnL%5w8Tp@p$L???(I8LsbMIY6E-{ zfF0c7siKIR-%5%`*zXz{4`8E7&9!5WJht`OP?;MVT$_fXf_v3!^bPHt+>^ySPo0wH z<0DH8+N&6jR4Ur9R2s2pM*-^jN`)xVg21H*ASKDtbdH#6Cg^O6V3nMuUb^6s&r)%P z3d+LeD^!rc<Si;lP2~5fFp?ylmHSj2qR^8A7+edYXb6Srs6)_b@FIolMLdcYA(@yz z?%Cd?H{m(>oANH?C-Ye^=goUBdA@<Gr3-Yn%{EdyIt_6~XX!GG5D57b&1FztKI?bD ziXc*}luD;b`GvFn?Ifh`0Tq((xaUeoG(uHNuZ>7e&Hb852=vTZdbkah6pJMN3qfZo z&LGc}b!ytCqCrJOojIVG56oSj>`<e*o-*kN(!e^L9$eFjmY5oGPkZaBd~w|g7Sc^s Z9w{8TfIM8nl3f@$3*Ywb!cVQY{{ud?EhPW| literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py b/env/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py new file mode 100644 index 0000000..3cc66c9 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/vcs/bazaar.py @@ -0,0 +1,112 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves.urllib import parse as urllib_parse + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import ( + display_path, make_vcs_requirement_url, rmtree, +) +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Bazaar(VersionControl): + name = 'bzr' + dirname = '.bzr' + repo_name = 'branch' + schemes = ( + 'bzr', 'bzr+http', 'bzr+https', 'bzr+ssh', 'bzr+sftp', 'bzr+ftp', + 'bzr+lp', + ) + + def __init__(self, url=None, *args, **kwargs): + super(Bazaar, self).__init__(url, *args, **kwargs) + # This is only needed for python <2.7.5 + # Register lp but do not expose as a scheme to support bzr+lp. + if getattr(urllib_parse, 'uses_fragment', None): + urllib_parse.uses_fragment.extend(['lp']) + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def export(self, location): + """ + Export the Bazaar repository at the url to the destination location + """ + # Remove the location to make sure Bazaar can export it correctly + if os.path.exists(location): + rmtree(location) + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['export', location], + cwd=temp_dir.path, show_stdout=False, + ) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['branch', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def switch(self, dest, url, rev_options): + self.run_command(['switch', url], cwd=dest) + + def update(self, dest, url, rev_options): + cmd_args = ['pull', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def get_url_rev_and_auth(self, url): + # hotfix the URL scheme after removing bzr+ from bzr+ssh:// readd it + url, rev, user_pass = super(Bazaar, self).get_url_rev_and_auth(url) + if url.startswith('ssh://'): + url = 'bzr+' + url + return url, rev, user_pass + + def get_url(self, location): + urls = self.run_command(['info'], show_stdout=False, cwd=location) + for line in urls.splitlines(): + line = line.strip() + for x in ('checkout of branch: ', + 'parent branch: '): + if line.startswith(x): + repo = line.split(x)[1] + if self._is_local_repository(repo): + return path_to_url(repo) + return repo + return None + + def get_revision(self, location): + revision = self.run_command( + ['revno'], show_stdout=False, cwd=location, + ) + return revision.splitlines()[-1] + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo: + return None + if not repo.lower().startswith('bzr:'): + repo = 'bzr+' + repo + current_rev = self.get_revision(location) + egg_project_name = dist.egg_name().split('-', 1)[0] + return make_vcs_requirement_url(repo, current_rev, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Bazaar) diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/git.py b/env/lib/python3.7/site-packages/pip/_internal/vcs/git.py new file mode 100644 index 0000000..9778539 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/vcs/git.py @@ -0,0 +1,346 @@ +from __future__ import absolute_import + +import logging +import os.path +import re + +from pip._vendor.packaging.version import parse as parse_version +from pip._vendor.six.moves.urllib import parse as urllib_parse +from pip._vendor.six.moves.urllib import request as urllib_request + +from pip._internal.exceptions import BadCommand +from pip._internal.utils.compat import samefile +from pip._internal.utils.misc import display_path, make_vcs_requirement_url +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +urlsplit = urllib_parse.urlsplit +urlunsplit = urllib_parse.urlunsplit + + +logger = logging.getLogger(__name__) + + +HASH_REGEX = re.compile('[a-fA-F0-9]{40}') + + +def looks_like_hash(sha): + return bool(HASH_REGEX.match(sha)) + + +class Git(VersionControl): + name = 'git' + dirname = '.git' + repo_name = 'clone' + schemes = ( + 'git', 'git+http', 'git+https', 'git+ssh', 'git+git', 'git+file', + ) + # Prevent the user's environment variables from interfering with pip: + # https://github.com/pypa/pip/issues/1130 + unset_environ = ('GIT_DIR', 'GIT_WORK_TREE') + default_arg_rev = 'HEAD' + + def __init__(self, url=None, *args, **kwargs): + + # Works around an apparent Git bug + # (see https://article.gmane.org/gmane.comp.version-control.git/146500) + if url: + scheme, netloc, path, query, fragment = urlsplit(url) + if scheme.endswith('file'): + initial_slashes = path[:-len(path.lstrip('/'))] + newpath = ( + initial_slashes + + urllib_request.url2pathname(path) + .replace('\\', '/').lstrip('/') + ) + url = urlunsplit((scheme, netloc, newpath, query, fragment)) + after_plus = scheme.find('+') + 1 + url = scheme[:after_plus] + urlunsplit( + (scheme[after_plus:], netloc, newpath, query, fragment), + ) + + super(Git, self).__init__(url, *args, **kwargs) + + def get_base_rev_args(self, rev): + return [rev] + + def get_git_version(self): + VERSION_PFX = 'git version ' + version = self.run_command(['version'], show_stdout=False) + if version.startswith(VERSION_PFX): + version = version[len(VERSION_PFX):].split()[0] + else: + version = '' + # get first 3 positions of the git version becasue + # on windows it is x.y.z.windows.t, and this parses as + # LegacyVersion which always smaller than a Version. + version = '.'.join(version.split('.')[:3]) + return parse_version(version) + + def get_branch(self, location): + """ + Return the current branch, or None if HEAD isn't at a branch + (e.g. detached HEAD). + """ + args = ['rev-parse', '--abbrev-ref', 'HEAD'] + output = self.run_command(args, show_stdout=False, cwd=location) + branch = output.strip() + + if branch == 'HEAD': + return None + + return branch + + def export(self, location): + """Export the Git repository at the url to the destination location""" + if not location.endswith('/'): + location = location + '/' + + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + self.run_command( + ['checkout-index', '-a', '-f', '--prefix', location], + show_stdout=False, cwd=temp_dir.path + ) + + def get_revision_sha(self, dest, rev): + """ + Return (sha_or_none, is_branch), where sha_or_none is a commit hash + if the revision names a remote branch or tag, otherwise None. + + Args: + dest: the repository directory. + rev: the revision name. + """ + # Pass rev to pre-filter the list. + output = self.run_command(['show-ref', rev], cwd=dest, + show_stdout=False, on_returncode='ignore') + refs = {} + for line in output.strip().splitlines(): + try: + sha, ref = line.split() + except ValueError: + # Include the offending line to simplify troubleshooting if + # this error ever occurs. + raise ValueError('unexpected show-ref line: {!r}'.format(line)) + + refs[ref] = sha + + branch_ref = 'refs/remotes/origin/{}'.format(rev) + tag_ref = 'refs/tags/{}'.format(rev) + + sha = refs.get(branch_ref) + if sha is not None: + return (sha, True) + + sha = refs.get(tag_ref) + + return (sha, False) + + def resolve_revision(self, dest, url, rev_options): + """ + Resolve a revision to a new RevOptions object with the SHA1 of the + branch, tag, or ref if found. + + Args: + rev_options: a RevOptions object. + """ + rev = rev_options.arg_rev + sha, is_branch = self.get_revision_sha(dest, rev) + + if sha is not None: + rev_options = rev_options.make_new(sha) + rev_options.branch_name = rev if is_branch else None + + return rev_options + + # Do not show a warning for the common case of something that has + # the form of a Git commit hash. + if not looks_like_hash(rev): + logger.warning( + "Did not find branch or tag '%s', assuming revision or ref.", + rev, + ) + + if not rev.startswith('refs/'): + return rev_options + + # If it looks like a ref, we have to fetch it explicitly. + self.run_command( + ['fetch', '-q', url] + rev_options.to_args(), + cwd=dest, + ) + # Change the revision to the SHA of the ref we fetched + sha = self.get_revision(dest, rev='FETCH_HEAD') + rev_options = rev_options.make_new(sha) + + return rev_options + + def is_commit_id_equal(self, dest, name): + """ + Return whether the current commit hash equals the given name. + + Args: + dest: the repository directory. + name: a string name. + """ + if not name: + # Then avoid an unnecessary subprocess call. + return False + + return self.get_revision(dest) == name + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning %s%s to %s', url, rev_display, display_path(dest), + ) + self.run_command(['clone', '-q', url, dest]) + + if rev_options.rev: + # Then a specific revision was requested. + rev_options = self.resolve_revision(dest, url, rev_options) + branch_name = getattr(rev_options, 'branch_name', None) + if branch_name is None: + # Only do a checkout if the current commit id doesn't match + # the requested revision. + if not self.is_commit_id_equal(dest, rev_options.rev): + cmd_args = ['checkout', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + elif self.get_branch(dest) != branch_name: + # Then a specific branch was requested, and that branch + # is not yet checked out. + track_branch = 'origin/{}'.format(branch_name) + cmd_args = [ + 'checkout', '-b', branch_name, '--track', track_branch, + ] + self.run_command(cmd_args, cwd=dest) + + #: repo may contain submodules + self.update_submodules(dest) + + def switch(self, dest, url, rev_options): + self.run_command(['config', 'remote.origin.url', url], cwd=dest) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + self.update_submodules(dest) + + def update(self, dest, url, rev_options): + # First fetch changes from the default remote + if self.get_git_version() >= parse_version('1.9.0'): + # fetch tags in addition to everything else + self.run_command(['fetch', '-q', '--tags'], cwd=dest) + else: + self.run_command(['fetch', '-q'], cwd=dest) + # Then reset to wanted revision (maybe even origin/master) + rev_options = self.resolve_revision(dest, url, rev_options) + cmd_args = ['reset', '--hard', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + #: update submodules + self.update_submodules(dest) + + def get_url(self, location): + """Return URL of the first remote encountered.""" + remotes = self.run_command( + ['config', '--get-regexp', r'remote\..*\.url'], + show_stdout=False, cwd=location, + ) + remotes = remotes.splitlines() + found_remote = remotes[0] + for remote in remotes: + if remote.startswith('remote.origin.url '): + found_remote = remote + break + url = found_remote.split(' ')[1] + return url.strip() + + def get_revision(self, location, rev=None): + if rev is None: + rev = 'HEAD' + current_rev = self.run_command( + ['rev-parse', rev], show_stdout=False, cwd=location, + ) + return current_rev.strip() + + def _get_subdirectory(self, location): + """Return the relative path of setup.py to the git repo root.""" + # find the repo root + git_dir = self.run_command(['rev-parse', '--git-dir'], + show_stdout=False, cwd=location).strip() + if not os.path.isabs(git_dir): + git_dir = os.path.join(location, git_dir) + root_dir = os.path.join(git_dir, '..') + # find setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + # relative path of setup.py to repo root + if samefile(root_dir, location): + return None + return os.path.relpath(location, root_dir) + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo.lower().startswith('git:'): + repo = 'git+' + repo + current_rev = self.get_revision(location) + egg_project_name = dist.egg_name().split('-', 1)[0] + subdir = self._get_subdirectory(location) + req = make_vcs_requirement_url(repo, current_rev, egg_project_name, + subdir=subdir) + + return req + + def get_url_rev_and_auth(self, url): + """ + Prefixes stub URLs like 'user@hostname:user/repo.git' with 'ssh://'. + That's required because although they use SSH they sometimes don't + work with a ssh:// scheme (e.g. GitHub). But we need a scheme for + parsing. Hence we remove it again afterwards and return it as a stub. + """ + if '://' not in url: + assert 'file:' not in url + url = url.replace('git+', 'git+ssh://') + url, rev, user_pass = super(Git, self).get_url_rev_and_auth(url) + url = url.replace('ssh://', '') + else: + url, rev, user_pass = super(Git, self).get_url_rev_and_auth(url) + + return url, rev, user_pass + + def update_submodules(self, location): + if not os.path.exists(os.path.join(location, '.gitmodules')): + return + self.run_command( + ['submodule', 'update', '--init', '--recursive', '-q'], + cwd=location, + ) + + @classmethod + def controls_location(cls, location): + if super(Git, cls).controls_location(location): + return True + try: + r = cls().run_command(['rev-parse'], + cwd=location, + show_stdout=False, + on_returncode='ignore') + return not r + except BadCommand: + logger.debug("could not determine if %s is under git control " + "because git is not available", location) + return False + + +vcs.register(Git) diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py b/env/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py new file mode 100644 index 0000000..17cfb67 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/vcs/mercurial.py @@ -0,0 +1,101 @@ +from __future__ import absolute_import + +import logging +import os + +from pip._vendor.six.moves import configparser + +from pip._internal.download import path_to_url +from pip._internal.utils.misc import display_path, make_vcs_requirement_url +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.vcs import VersionControl, vcs + +logger = logging.getLogger(__name__) + + +class Mercurial(VersionControl): + name = 'hg' + dirname = '.hg' + repo_name = 'clone' + schemes = ('hg', 'hg+http', 'hg+https', 'hg+ssh', 'hg+static-http') + + def get_base_rev_args(self, rev): + return [rev] + + def export(self, location): + """Export the Hg repository at the url to the destination location""" + with TempDirectory(kind="export") as temp_dir: + self.unpack(temp_dir.path) + + self.run_command( + ['archive', location], show_stdout=False, cwd=temp_dir.path + ) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Cloning hg %s%s to %s', + url, + rev_display, + display_path(dest), + ) + self.run_command(['clone', '--noupdate', '-q', url, dest]) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def switch(self, dest, url, rev_options): + repo_config = os.path.join(dest, self.dirname, 'hgrc') + config = configparser.SafeConfigParser() + try: + config.read(repo_config) + config.set('paths', 'default', url) + with open(repo_config, 'w') as config_file: + config.write(config_file) + except (OSError, configparser.NoSectionError) as exc: + logger.warning( + 'Could not switch Mercurial repository to %s: %s', url, exc, + ) + else: + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def update(self, dest, url, rev_options): + self.run_command(['pull', '-q'], cwd=dest) + cmd_args = ['update', '-q'] + rev_options.to_args() + self.run_command(cmd_args, cwd=dest) + + def get_url(self, location): + url = self.run_command( + ['showconfig', 'paths.default'], + show_stdout=False, cwd=location).strip() + if self._is_local_repository(url): + url = path_to_url(url) + return url.strip() + + def get_revision(self, location): + current_revision = self.run_command( + ['parents', '--template={rev}'], + show_stdout=False, cwd=location).strip() + return current_revision + + def get_revision_hash(self, location): + current_rev_hash = self.run_command( + ['parents', '--template={node}'], + show_stdout=False, cwd=location).strip() + return current_rev_hash + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if not repo.lower().startswith('hg:'): + repo = 'hg+' + repo + current_rev_hash = self.get_revision_hash(location) + egg_project_name = dist.egg_name().split('-', 1)[0] + return make_vcs_requirement_url(repo, current_rev_hash, + egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Mercurial) diff --git a/env/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py b/env/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py new file mode 100644 index 0000000..6f7cb5d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/vcs/subversion.py @@ -0,0 +1,213 @@ +from __future__ import absolute_import + +import logging +import os +import re + +from pip._internal.models.link import Link +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + display_path, make_vcs_requirement_url, rmtree, split_auth_from_netloc, +) +from pip._internal.vcs import VersionControl, vcs + +_svn_xml_url_re = re.compile('url="([^"]+)"') +_svn_rev_re = re.compile(r'committed-rev="(\d+)"') +_svn_info_xml_rev_re = re.compile(r'\s*revision="(\d+)"') +_svn_info_xml_url_re = re.compile(r'<url>(.*)</url>') + + +logger = logging.getLogger(__name__) + + +class Subversion(VersionControl): + name = 'svn' + dirname = '.svn' + repo_name = 'checkout' + schemes = ('svn', 'svn+ssh', 'svn+http', 'svn+https', 'svn+svn') + + def get_base_rev_args(self, rev): + return ['-r', rev] + + def export(self, location): + """Export the svn repository at the url to the destination location""" + url, rev_options = self.get_url_rev_options(self.url) + + logger.info('Exporting svn repository %s to %s', url, location) + with indent_log(): + if os.path.exists(location): + # Subversion doesn't like to check out over an existing + # directory --force fixes this, but was only added in svn 1.5 + rmtree(location) + cmd_args = ['export'] + rev_options.to_args() + [url, location] + self.run_command(cmd_args, show_stdout=False) + + def fetch_new(self, dest, url, rev_options): + rev_display = rev_options.to_display() + logger.info( + 'Checking out %s%s to %s', + url, + rev_display, + display_path(dest), + ) + cmd_args = ['checkout', '-q'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def switch(self, dest, url, rev_options): + cmd_args = ['switch'] + rev_options.to_args() + [url, dest] + self.run_command(cmd_args) + + def update(self, dest, url, rev_options): + cmd_args = ['update'] + rev_options.to_args() + [dest] + self.run_command(cmd_args) + + def get_location(self, dist, dependency_links): + for url in dependency_links: + egg_fragment = Link(url).egg_fragment + if not egg_fragment: + continue + if '-' in egg_fragment: + # FIXME: will this work when a package has - in the name? + key = '-'.join(egg_fragment.split('-')[:-1]).lower() + else: + key = egg_fragment + if key == dist.key: + return url.split('#', 1)[0] + return None + + def get_revision(self, location): + """ + Return the maximum revision for all files under a given location + """ + # Note: taken from setuptools.command.egg_info + revision = 0 + + for base, dirs, files in os.walk(location): + if self.dirname not in dirs: + dirs[:] = [] + continue # no sense walking uncontrolled subdirs + dirs.remove(self.dirname) + entries_fn = os.path.join(base, self.dirname, 'entries') + if not os.path.exists(entries_fn): + # FIXME: should we warn? + continue + + dirurl, localrev = self._get_svn_url_rev(base) + + if base == location: + base = dirurl + '/' # save the root url + elif not dirurl or not dirurl.startswith(base): + dirs[:] = [] + continue # not part of the same svn tree, skip it + revision = max(revision, localrev) + return revision + + def get_netloc_and_auth(self, netloc, scheme): + """ + This override allows the auth information to be passed to svn via the + --username and --password options instead of via the URL. + """ + if scheme == 'ssh': + # The --username and --password options can't be used for + # svn+ssh URLs, so keep the auth information in the URL. + return super(Subversion, self).get_netloc_and_auth( + netloc, scheme) + + return split_auth_from_netloc(netloc) + + def get_url_rev_and_auth(self, url): + # hotfix the URL scheme after removing svn+ from svn+ssh:// readd it + url, rev, user_pass = super(Subversion, self).get_url_rev_and_auth(url) + if url.startswith('ssh://'): + url = 'svn+' + url + return url, rev, user_pass + + def make_rev_args(self, username, password): + extra_args = [] + if username: + extra_args += ['--username', username] + if password: + extra_args += ['--password', password] + + return extra_args + + def get_url(self, location): + # In cases where the source is in a subdirectory, not alongside + # setup.py we have to look up in the location until we find a real + # setup.py + orig_location = location + while not os.path.exists(os.path.join(location, 'setup.py')): + last_location = location + location = os.path.dirname(location) + if location == last_location: + # We've traversed up to the root of the filesystem without + # finding setup.py + logger.warning( + "Could not find setup.py for directory %s (tried all " + "parent directories)", + orig_location, + ) + return None + + return self._get_svn_url_rev(location)[0] + + def _get_svn_url_rev(self, location): + from pip._internal.exceptions import InstallationError + + entries_path = os.path.join(location, self.dirname, 'entries') + if os.path.exists(entries_path): + with open(entries_path) as f: + data = f.read() + else: # subversion >= 1.7 does not have the 'entries' file + data = '' + + if (data.startswith('8') or + data.startswith('9') or + data.startswith('10')): + data = list(map(str.splitlines, data.split('\n\x0c\n'))) + del data[0][0] # get rid of the '8' + url = data[0][3] + revs = [int(d[9]) for d in data if len(d) > 9 and d[9]] + [0] + elif data.startswith('<?xml'): + match = _svn_xml_url_re.search(data) + if not match: + raise ValueError('Badly formatted data: %r' % data) + url = match.group(1) # get repository URL + revs = [int(m.group(1)) for m in _svn_rev_re.finditer(data)] + [0] + else: + try: + # subversion >= 1.7 + xml = self.run_command( + ['info', '--xml', location], + show_stdout=False, + ) + url = _svn_info_xml_url_re.search(xml).group(1) + revs = [ + int(m.group(1)) for m in _svn_info_xml_rev_re.finditer(xml) + ] + except InstallationError: + url, revs = None, [] + + if revs: + rev = max(revs) + else: + rev = 0 + + return url, rev + + def get_src_requirement(self, dist, location): + repo = self.get_url(location) + if repo is None: + return None + repo = 'svn+' + repo + rev = self.get_revision(location) + # FIXME: why not project name? + egg_project_name = dist.egg_name().split('-', 1)[0] + return make_vcs_requirement_url(repo, rev, egg_project_name) + + def is_commit_id_equal(self, dest, name): + """Always assume the versions don't match""" + return False + + +vcs.register(Subversion) diff --git a/env/lib/python3.7/site-packages/pip/_internal/wheel.py b/env/lib/python3.7/site-packages/pip/_internal/wheel.py new file mode 100644 index 0000000..5ce890e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_internal/wheel.py @@ -0,0 +1,831 @@ +""" +Support for installing and building the "wheel" binary package format. +""" +from __future__ import absolute_import + +import collections +import compileall +import csv +import hashlib +import logging +import os.path +import re +import shutil +import stat +import sys +import warnings +from base64 import urlsafe_b64encode +from email.parser import Parser + +from pip._vendor import pkg_resources +from pip._vendor.distlib.scripts import ScriptMaker +from pip._vendor.packaging.utils import canonicalize_name +from pip._vendor.six import StringIO + +from pip._internal import pep425tags +from pip._internal.download import path_to_url, unpack_url +from pip._internal.exceptions import ( + InstallationError, InvalidWheelFilename, UnsupportedWheel, +) +from pip._internal.locations import ( + PIP_DELETE_MARKER_FILENAME, distutils_scheme, +) +from pip._internal.utils.logging import indent_log +from pip._internal.utils.misc import ( + call_subprocess, captured_stdout, ensure_dir, read_chunks, +) +from pip._internal.utils.setuptools_build import SETUPTOOLS_SHIM +from pip._internal.utils.temp_dir import TempDirectory +from pip._internal.utils.typing import MYPY_CHECK_RUNNING +from pip._internal.utils.ui import open_spinner + +if MYPY_CHECK_RUNNING: + from typing import Dict, List, Optional # noqa: F401 + +wheel_ext = '.whl' + +VERSION_COMPATIBLE = (1, 0) + + +logger = logging.getLogger(__name__) + + +def rehash(path, blocksize=1 << 20): + """Return (hash, length) for path using hashlib.sha256()""" + h = hashlib.sha256() + length = 0 + with open(path, 'rb') as f: + for block in read_chunks(f, size=blocksize): + length += len(block) + h.update(block) + digest = 'sha256=' + urlsafe_b64encode( + h.digest() + ).decode('latin1').rstrip('=') + return (digest, length) + + +def open_for_csv(name, mode): + if sys.version_info[0] < 3: + nl = {} + bin = 'b' + else: + nl = {'newline': ''} + bin = '' + return open(name, mode + bin, **nl) + + +def fix_script(path): + """Replace #!python with #!/path/to/python + Return True if file was changed.""" + # XXX RECORD hashes will need to be updated + if os.path.isfile(path): + with open(path, 'rb') as script: + firstline = script.readline() + if not firstline.startswith(b'#!python'): + return False + exename = sys.executable.encode(sys.getfilesystemencoding()) + firstline = b'#!' + exename + os.linesep.encode("ascii") + rest = script.read() + with open(path, 'wb') as script: + script.write(firstline) + script.write(rest) + return True + + +dist_info_re = re.compile(r"""^(?P<namever>(?P<name>.+?)(-(?P<ver>.+?))?) + \.dist-info$""", re.VERBOSE) + + +def root_is_purelib(name, wheeldir): + """ + Return True if the extracted wheel in wheeldir should go into purelib. + """ + name_folded = name.replace("-", "_") + for item in os.listdir(wheeldir): + match = dist_info_re.match(item) + if match and match.group('name') == name_folded: + with open(os.path.join(wheeldir, item, 'WHEEL')) as wheel: + for line in wheel: + line = line.lower().rstrip() + if line == "root-is-purelib: true": + return True + return False + + +def get_entrypoints(filename): + if not os.path.exists(filename): + return {}, {} + + # This is done because you can pass a string to entry_points wrappers which + # means that they may or may not be valid INI files. The attempt here is to + # strip leading and trailing whitespace in order to make them valid INI + # files. + with open(filename) as fp: + data = StringIO() + for line in fp: + data.write(line.strip()) + data.write("\n") + data.seek(0) + + # get the entry points and then the script names + entry_points = pkg_resources.EntryPoint.parse_map(data) + console = entry_points.get('console_scripts', {}) + gui = entry_points.get('gui_scripts', {}) + + def _split_ep(s): + """get the string representation of EntryPoint, remove space and split + on '='""" + return str(s).replace(" ", "").split("=") + + # convert the EntryPoint objects into strings with module:function + console = dict(_split_ep(v) for v in console.values()) + gui = dict(_split_ep(v) for v in gui.values()) + return console, gui + + +def message_about_scripts_not_on_PATH(scripts): + # type: (List[str]) -> Optional[str] + """Determine if any scripts are not on PATH and format a warning. + + Returns a warning message if one or more scripts are not on PATH, + otherwise None. + """ + if not scripts: + return None + + # Group scripts by the path they were installed in + grouped_by_dir = collections.defaultdict(set) # type: Dict[str, set] + for destfile in scripts: + parent_dir = os.path.dirname(destfile) + script_name = os.path.basename(destfile) + grouped_by_dir[parent_dir].add(script_name) + + # We don't want to warn for directories that are on PATH. + not_warn_dirs = [ + os.path.normcase(i).rstrip(os.sep) for i in + os.environ.get("PATH", "").split(os.pathsep) + ] + # If an executable sits with sys.executable, we don't warn for it. + # This covers the case of venv invocations without activating the venv. + not_warn_dirs.append(os.path.normcase(os.path.dirname(sys.executable))) + warn_for = { + parent_dir: scripts for parent_dir, scripts in grouped_by_dir.items() + if os.path.normcase(parent_dir) not in not_warn_dirs + } + if not warn_for: + return None + + # Format a message + msg_lines = [] + for parent_dir, scripts in warn_for.items(): + scripts = sorted(scripts) + if len(scripts) == 1: + start_text = "script {} is".format(scripts[0]) + else: + start_text = "scripts {} are".format( + ", ".join(scripts[:-1]) + " and " + scripts[-1] + ) + + msg_lines.append( + "The {} installed in '{}' which is not on PATH." + .format(start_text, parent_dir) + ) + + last_line_fmt = ( + "Consider adding {} to PATH or, if you prefer " + "to suppress this warning, use --no-warn-script-location." + ) + if len(msg_lines) == 1: + msg_lines.append(last_line_fmt.format("this directory")) + else: + msg_lines.append(last_line_fmt.format("these directories")) + + # Returns the formatted multiline message + return "\n".join(msg_lines) + + +def move_wheel_files(name, req, wheeldir, user=False, home=None, root=None, + pycompile=True, scheme=None, isolated=False, prefix=None, + warn_script_location=True): + """Install a wheel""" + + if not scheme: + scheme = distutils_scheme( + name, user=user, home=home, root=root, isolated=isolated, + prefix=prefix, + ) + + if root_is_purelib(name, wheeldir): + lib_dir = scheme['purelib'] + else: + lib_dir = scheme['platlib'] + + info_dir = [] + data_dirs = [] + source = wheeldir.rstrip(os.path.sep) + os.path.sep + + # Record details of the files moved + # installed = files copied from the wheel to the destination + # changed = files changed while installing (scripts #! line typically) + # generated = files newly generated during the install (script wrappers) + installed = {} + changed = set() + generated = [] + + # Compile all of the pyc files that we're going to be installing + if pycompile: + with captured_stdout() as stdout: + with warnings.catch_warnings(): + warnings.filterwarnings('ignore') + compileall.compile_dir(source, force=True, quiet=True) + logger.debug(stdout.getvalue()) + + def normpath(src, p): + return os.path.relpath(src, p).replace(os.path.sep, '/') + + def record_installed(srcfile, destfile, modified=False): + """Map archive RECORD paths to installation RECORD paths.""" + oldpath = normpath(srcfile, wheeldir) + newpath = normpath(destfile, lib_dir) + installed[oldpath] = newpath + if modified: + changed.add(destfile) + + def clobber(source, dest, is_base, fixer=None, filter=None): + ensure_dir(dest) # common for the 'include' path + + for dir, subdirs, files in os.walk(source): + basedir = dir[len(source):].lstrip(os.path.sep) + destdir = os.path.join(dest, basedir) + if is_base and basedir.split(os.path.sep, 1)[0].endswith('.data'): + continue + for s in subdirs: + destsubdir = os.path.join(dest, basedir, s) + if is_base and basedir == '' and destsubdir.endswith('.data'): + data_dirs.append(s) + continue + elif (is_base and + s.endswith('.dist-info') and + canonicalize_name(s).startswith( + canonicalize_name(req.name))): + assert not info_dir, ('Multiple .dist-info directories: ' + + destsubdir + ', ' + + ', '.join(info_dir)) + info_dir.append(destsubdir) + for f in files: + # Skip unwanted files + if filter and filter(f): + continue + srcfile = os.path.join(dir, f) + destfile = os.path.join(dest, basedir, f) + # directory creation is lazy and after the file filtering above + # to ensure we don't install empty dirs; empty dirs can't be + # uninstalled. + ensure_dir(destdir) + + # copyfile (called below) truncates the destination if it + # exists and then writes the new contents. This is fine in most + # cases, but can cause a segfault if pip has loaded a shared + # object (e.g. from pyopenssl through its vendored urllib3) + # Since the shared object is mmap'd an attempt to call a + # symbol in it will then cause a segfault. Unlinking the file + # allows writing of new contents while allowing the process to + # continue to use the old copy. + if os.path.exists(destfile): + os.unlink(destfile) + + # We use copyfile (not move, copy, or copy2) to be extra sure + # that we are not moving directories over (copyfile fails for + # directories) as well as to ensure that we are not copying + # over any metadata because we want more control over what + # metadata we actually copy over. + shutil.copyfile(srcfile, destfile) + + # Copy over the metadata for the file, currently this only + # includes the atime and mtime. + st = os.stat(srcfile) + if hasattr(os, "utime"): + os.utime(destfile, (st.st_atime, st.st_mtime)) + + # If our file is executable, then make our destination file + # executable. + if os.access(srcfile, os.X_OK): + st = os.stat(srcfile) + permissions = ( + st.st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH + ) + os.chmod(destfile, permissions) + + changed = False + if fixer: + changed = fixer(destfile) + record_installed(srcfile, destfile, changed) + + clobber(source, lib_dir, True) + + assert info_dir, "%s .dist-info directory not found" % req + + # Get the defined entry points + ep_file = os.path.join(info_dir[0], 'entry_points.txt') + console, gui = get_entrypoints(ep_file) + + def is_entrypoint_wrapper(name): + # EP, EP.exe and EP-script.py are scripts generated for + # entry point EP by setuptools + if name.lower().endswith('.exe'): + matchname = name[:-4] + elif name.lower().endswith('-script.py'): + matchname = name[:-10] + elif name.lower().endswith(".pya"): + matchname = name[:-4] + else: + matchname = name + # Ignore setuptools-generated scripts + return (matchname in console or matchname in gui) + + for datadir in data_dirs: + fixer = None + filter = None + for subdir in os.listdir(os.path.join(wheeldir, datadir)): + fixer = None + if subdir == 'scripts': + fixer = fix_script + filter = is_entrypoint_wrapper + source = os.path.join(wheeldir, datadir, subdir) + dest = scheme[subdir] + clobber(source, dest, False, fixer=fixer, filter=filter) + + maker = ScriptMaker(None, scheme['scripts']) + + # Ensure old scripts are overwritten. + # See https://github.com/pypa/pip/issues/1800 + maker.clobber = True + + # Ensure we don't generate any variants for scripts because this is almost + # never what somebody wants. + # See https://bitbucket.org/pypa/distlib/issue/35/ + maker.variants = {''} + + # This is required because otherwise distlib creates scripts that are not + # executable. + # See https://bitbucket.org/pypa/distlib/issue/32/ + maker.set_mode = True + + # Simplify the script and fix the fact that the default script swallows + # every single stack trace. + # See https://bitbucket.org/pypa/distlib/issue/34/ + # See https://bitbucket.org/pypa/distlib/issue/33/ + def _get_script_text(entry): + if entry.suffix is None: + raise InstallationError( + "Invalid script entry point: %s for req: %s - A callable " + "suffix is required. Cf https://packaging.python.org/en/" + "latest/distributing.html#console-scripts for more " + "information." % (entry, req) + ) + return maker.script_template % { + "module": entry.prefix, + "import_name": entry.suffix.split(".")[0], + "func": entry.suffix, + } + + maker._get_script_text = _get_script_text + maker.script_template = r"""# -*- coding: utf-8 -*- +import re +import sys + +from %(module)s import %(import_name)s + +if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit(%(func)s()) +""" + + # Special case pip and setuptools to generate versioned wrappers + # + # The issue is that some projects (specifically, pip and setuptools) use + # code in setup.py to create "versioned" entry points - pip2.7 on Python + # 2.7, pip3.3 on Python 3.3, etc. But these entry points are baked into + # the wheel metadata at build time, and so if the wheel is installed with + # a *different* version of Python the entry points will be wrong. The + # correct fix for this is to enhance the metadata to be able to describe + # such versioned entry points, but that won't happen till Metadata 2.0 is + # available. + # In the meantime, projects using versioned entry points will either have + # incorrect versioned entry points, or they will not be able to distribute + # "universal" wheels (i.e., they will need a wheel per Python version). + # + # Because setuptools and pip are bundled with _ensurepip and virtualenv, + # we need to use universal wheels. So, as a stopgap until Metadata 2.0, we + # override the versioned entry points in the wheel and generate the + # correct ones. This code is purely a short-term measure until Metadata 2.0 + # is available. + # + # To add the level of hack in this section of code, in order to support + # ensurepip this code will look for an ``ENSUREPIP_OPTIONS`` environment + # variable which will control which version scripts get installed. + # + # ENSUREPIP_OPTIONS=altinstall + # - Only pipX.Y and easy_install-X.Y will be generated and installed + # ENSUREPIP_OPTIONS=install + # - pipX.Y, pipX, easy_install-X.Y will be generated and installed. Note + # that this option is technically if ENSUREPIP_OPTIONS is set and is + # not altinstall + # DEFAULT + # - The default behavior is to install pip, pipX, pipX.Y, easy_install + # and easy_install-X.Y. + pip_script = console.pop('pip', None) + if pip_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + spec = 'pip = ' + pip_script + generated.extend(maker.make(spec)) + + if os.environ.get("ENSUREPIP_OPTIONS", "") != "altinstall": + spec = 'pip%s = %s' % (sys.version[:1], pip_script) + generated.extend(maker.make(spec)) + + spec = 'pip%s = %s' % (sys.version[:3], pip_script) + generated.extend(maker.make(spec)) + # Delete any other versioned pip entry points + pip_ep = [k for k in console if re.match(r'pip(\d(\.\d)?)?$', k)] + for k in pip_ep: + del console[k] + easy_install_script = console.pop('easy_install', None) + if easy_install_script: + if "ENSUREPIP_OPTIONS" not in os.environ: + spec = 'easy_install = ' + easy_install_script + generated.extend(maker.make(spec)) + + spec = 'easy_install-%s = %s' % (sys.version[:3], easy_install_script) + generated.extend(maker.make(spec)) + # Delete any other versioned easy_install entry points + easy_install_ep = [ + k for k in console if re.match(r'easy_install(-\d\.\d)?$', k) + ] + for k in easy_install_ep: + del console[k] + + # Generate the console and GUI entry points specified in the wheel + if len(console) > 0: + generated_console_scripts = maker.make_multiple( + ['%s = %s' % kv for kv in console.items()] + ) + generated.extend(generated_console_scripts) + + if warn_script_location: + msg = message_about_scripts_not_on_PATH(generated_console_scripts) + if msg is not None: + logger.warning(msg) + + if len(gui) > 0: + generated.extend( + maker.make_multiple( + ['%s = %s' % kv for kv in gui.items()], + {'gui': True} + ) + ) + + # Record pip as the installer + installer = os.path.join(info_dir[0], 'INSTALLER') + temp_installer = os.path.join(info_dir[0], 'INSTALLER.pip') + with open(temp_installer, 'wb') as installer_file: + installer_file.write(b'pip\n') + shutil.move(temp_installer, installer) + generated.append(installer) + + # Record details of all files installed + record = os.path.join(info_dir[0], 'RECORD') + temp_record = os.path.join(info_dir[0], 'RECORD.pip') + with open_for_csv(record, 'r') as record_in: + with open_for_csv(temp_record, 'w+') as record_out: + reader = csv.reader(record_in) + writer = csv.writer(record_out) + outrows = [] + for row in reader: + row[0] = installed.pop(row[0], row[0]) + if row[0] in changed: + row[1], row[2] = rehash(row[0]) + outrows.append(tuple(row)) + for f in generated: + digest, length = rehash(f) + outrows.append((normpath(f, lib_dir), digest, length)) + for f in installed: + outrows.append((installed[f], '', '')) + for row in sorted(outrows): + writer.writerow(row) + shutil.move(temp_record, record) + + +def wheel_version(source_dir): + """ + Return the Wheel-Version of an extracted wheel, if possible. + + Otherwise, return False if we couldn't parse / extract it. + """ + try: + dist = [d for d in pkg_resources.find_on_path(None, source_dir)][0] + + wheel_data = dist.get_metadata('WHEEL') + wheel_data = Parser().parsestr(wheel_data) + + version = wheel_data['Wheel-Version'].strip() + version = tuple(map(int, version.split('.'))) + return version + except Exception: + return False + + +def check_compatibility(version, name): + """ + Raises errors or warns if called with an incompatible Wheel-Version. + + Pip should refuse to install a Wheel-Version that's a major series + ahead of what it's compatible with (e.g 2.0 > 1.1); and warn when + installing a version only minor version ahead (e.g 1.2 > 1.1). + + version: a 2-tuple representing a Wheel-Version (Major, Minor) + name: name of wheel or package to raise exception about + + :raises UnsupportedWheel: when an incompatible Wheel-Version is given + """ + if not version: + raise UnsupportedWheel( + "%s is in an unsupported or invalid wheel" % name + ) + if version[0] > VERSION_COMPATIBLE[0]: + raise UnsupportedWheel( + "%s's Wheel-Version (%s) is not compatible with this version " + "of pip" % (name, '.'.join(map(str, version))) + ) + elif version > VERSION_COMPATIBLE: + logger.warning( + 'Installing from a newer Wheel-Version (%s)', + '.'.join(map(str, version)), + ) + + +class Wheel(object): + """A wheel file""" + + # TODO: maybe move the install code into this class + + wheel_file_re = re.compile( + r"""^(?P<namever>(?P<name>.+?)-(?P<ver>.*?)) + ((-(?P<build>\d[^-]*?))?-(?P<pyver>.+?)-(?P<abi>.+?)-(?P<plat>.+?) + \.whl|\.dist-info)$""", + re.VERBOSE + ) + + def __init__(self, filename): + """ + :raises InvalidWheelFilename: when the filename is invalid for a wheel + """ + wheel_info = self.wheel_file_re.match(filename) + if not wheel_info: + raise InvalidWheelFilename( + "%s is not a valid wheel filename." % filename + ) + self.filename = filename + self.name = wheel_info.group('name').replace('_', '-') + # we'll assume "_" means "-" due to wheel naming scheme + # (https://github.com/pypa/pip/issues/1150) + self.version = wheel_info.group('ver').replace('_', '-') + self.build_tag = wheel_info.group('build') + self.pyversions = wheel_info.group('pyver').split('.') + self.abis = wheel_info.group('abi').split('.') + self.plats = wheel_info.group('plat').split('.') + + # All the tag combinations from this file + self.file_tags = { + (x, y, z) for x in self.pyversions + for y in self.abis for z in self.plats + } + + def support_index_min(self, tags=None): + """ + Return the lowest index that one of the wheel's file_tag combinations + achieves in the supported_tags list e.g. if there are 8 supported tags, + and one of the file tags is first in the list, then return 0. Returns + None is the wheel is not supported. + """ + if tags is None: # for mock + tags = pep425tags.get_supported() + indexes = [tags.index(c) for c in self.file_tags if c in tags] + return min(indexes) if indexes else None + + def supported(self, tags=None): + """Is this wheel supported on this system?""" + if tags is None: # for mock + tags = pep425tags.get_supported() + return bool(set(tags).intersection(self.file_tags)) + + +class WheelBuilder(object): + """Build wheels from a RequirementSet.""" + + def __init__(self, finder, preparer, wheel_cache, + build_options=None, global_options=None, no_clean=False): + self.finder = finder + self.preparer = preparer + self.wheel_cache = wheel_cache + + self._wheel_dir = preparer.wheel_download_dir + + self.build_options = build_options or [] + self.global_options = global_options or [] + self.no_clean = no_clean + + def _build_one(self, req, output_dir, python_tag=None): + """Build one wheel. + + :return: The filename of the built wheel, or None if the build failed. + """ + # Install build deps into temporary directory (PEP 518) + with req.build_env: + return self._build_one_inside_env(req, output_dir, + python_tag=python_tag) + + def _build_one_inside_env(self, req, output_dir, python_tag=None): + with TempDirectory(kind="wheel") as temp_dir: + if self.__build_one(req, temp_dir.path, python_tag=python_tag): + try: + wheel_name = os.listdir(temp_dir.path)[0] + wheel_path = os.path.join(output_dir, wheel_name) + shutil.move( + os.path.join(temp_dir.path, wheel_name), wheel_path + ) + logger.info('Stored in directory: %s', output_dir) + return wheel_path + except Exception: + pass + # Ignore return, we can't do anything else useful. + self._clean_one(req) + return None + + def _base_setup_args(self, req): + # NOTE: Eventually, we'd want to also -S to the flags here, when we're + # isolating. Currently, it breaks Python in virtualenvs, because it + # relies on site.py to find parts of the standard library outside the + # virtualenv. + return [ + sys.executable, '-u', '-c', + SETUPTOOLS_SHIM % req.setup_py + ] + list(self.global_options) + + def __build_one(self, req, tempd, python_tag=None): + base_args = self._base_setup_args(req) + + spin_message = 'Running setup.py bdist_wheel for %s' % (req.name,) + with open_spinner(spin_message) as spinner: + logger.debug('Destination directory: %s', tempd) + wheel_args = base_args + ['bdist_wheel', '-d', tempd] \ + + self.build_options + + if python_tag is not None: + wheel_args += ["--python-tag", python_tag] + + try: + call_subprocess(wheel_args, cwd=req.setup_py_dir, + show_stdout=False, spinner=spinner) + return True + except Exception: + spinner.finish("error") + logger.error('Failed building wheel for %s', req.name) + return False + + def _clean_one(self, req): + base_args = self._base_setup_args(req) + + logger.info('Running setup.py clean for %s', req.name) + clean_args = base_args + ['clean', '--all'] + try: + call_subprocess(clean_args, cwd=req.source_dir, show_stdout=False) + return True + except Exception: + logger.error('Failed cleaning build dir for %s', req.name) + return False + + def build(self, requirements, session, autobuilding=False): + """Build wheels. + + :param unpack: If True, replace the sdist we built from with the + newly built wheel, in preparation for installation. + :return: True if all the wheels built correctly. + """ + from pip._internal import index + from pip._internal.models.link import Link + + building_is_possible = self._wheel_dir or ( + autobuilding and self.wheel_cache.cache_dir + ) + assert building_is_possible + + buildset = [] + format_control = self.finder.format_control + for req in requirements: + if req.constraint: + continue + if req.is_wheel: + if not autobuilding: + logger.info( + 'Skipping %s, due to already being wheel.', req.name, + ) + elif autobuilding and req.editable: + pass + elif autobuilding and not req.source_dir: + pass + elif autobuilding and req.link and not req.link.is_artifact: + # VCS checkout. Build wheel just for this run. + buildset.append((req, True)) + else: + ephem_cache = False + if autobuilding: + link = req.link + base, ext = link.splitext() + if index.egg_info_matches(base, None, link) is None: + # E.g. local directory. Build wheel just for this run. + ephem_cache = True + if "binary" not in format_control.get_allowed_formats( + canonicalize_name(req.name)): + logger.info( + "Skipping bdist_wheel for %s, due to binaries " + "being disabled for it.", req.name, + ) + continue + buildset.append((req, ephem_cache)) + + if not buildset: + return True + + # Build the wheels. + logger.info( + 'Building wheels for collected packages: %s', + ', '.join([req.name for (req, _) in buildset]), + ) + _cache = self.wheel_cache # shorter name + with indent_log(): + build_success, build_failure = [], [] + for req, ephem in buildset: + python_tag = None + if autobuilding: + python_tag = pep425tags.implementation_tag + if ephem: + output_dir = _cache.get_ephem_path_for_link(req.link) + else: + output_dir = _cache.get_path_for_link(req.link) + try: + ensure_dir(output_dir) + except OSError as e: + logger.warning("Building wheel for %s failed: %s", + req.name, e) + build_failure.append(req) + continue + else: + output_dir = self._wheel_dir + wheel_file = self._build_one( + req, output_dir, + python_tag=python_tag, + ) + if wheel_file: + build_success.append(req) + if autobuilding: + # XXX: This is mildly duplicative with prepare_files, + # but not close enough to pull out to a single common + # method. + # The code below assumes temporary source dirs - + # prevent it doing bad things. + if req.source_dir and not os.path.exists(os.path.join( + req.source_dir, PIP_DELETE_MARKER_FILENAME)): + raise AssertionError( + "bad source dir - missing marker") + # Delete the source we built the wheel from + req.remove_temporary_source() + # set the build directory again - name is known from + # the work prepare_files did. + req.source_dir = req.build_location( + self.preparer.build_dir + ) + # Update the link for this. + req.link = Link(path_to_url(wheel_file)) + assert req.link.is_wheel + # extract the wheel into the dir + unpack_url( + req.link, req.source_dir, None, False, + session=session, + ) + else: + build_failure.append(req) + + # notify success/failure + if build_success: + logger.info( + 'Successfully built %s', + ' '.join([req.name for req in build_success]), + ) + if build_failure: + logger.info( + 'Failed to build %s', + ' '.join([req.name for req in build_failure]), + ) + # Return True if all builds were successful + return len(build_failure) == 0 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/__init__.py new file mode 100644 index 0000000..a0aae81 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/__init__.py @@ -0,0 +1,110 @@ +""" +pip._vendor is for vendoring dependencies of pip to prevent needing pip to +depend on something external. + +Files inside of pip._vendor should be considered immutable and should only be +updated to versions from upstream. +""" +from __future__ import absolute_import + +import glob +import os.path +import sys + +# Downstream redistributors which have debundled our dependencies should also +# patch this value to be true. This will trigger the additional patching +# to cause things like "six" to be available as pip. +DEBUNDLED = False + +# By default, look in this directory for a bunch of .whl files which we will +# add to the beginning of sys.path before attempting to import anything. This +# is done to support downstream re-distributors like Debian and Fedora who +# wish to create their own Wheels for our dependencies to aid in debundling. +WHEEL_DIR = os.path.abspath(os.path.dirname(__file__)) + + +# Define a small helper function to alias our vendored modules to the real ones +# if the vendored ones do not exist. This idea of this was taken from +# https://github.com/kennethreitz/requests/pull/2567. +def vendored(modulename): + vendored_name = "{0}.{1}".format(__name__, modulename) + + try: + __import__(vendored_name, globals(), locals(), level=0) + except ImportError: + try: + __import__(modulename, globals(), locals(), level=0) + except ImportError: + # We can just silently allow import failures to pass here. If we + # got to this point it means that ``import pip._vendor.whatever`` + # failed and so did ``import whatever``. Since we're importing this + # upfront in an attempt to alias imports, not erroring here will + # just mean we get a regular import error whenever pip *actually* + # tries to import one of these modules to use it, which actually + # gives us a better error message than we would have otherwise + # gotten. + pass + else: + sys.modules[vendored_name] = sys.modules[modulename] + base, head = vendored_name.rsplit(".", 1) + setattr(sys.modules[base], head, sys.modules[modulename]) + + +# If we're operating in a debundled setup, then we want to go ahead and trigger +# the aliasing of our vendored libraries as well as looking for wheels to add +# to our sys.path. This will cause all of this code to be a no-op typically +# however downstream redistributors can enable it in a consistent way across +# all platforms. +if DEBUNDLED: + # Actually look inside of WHEEL_DIR to find .whl files and add them to the + # front of our sys.path. + sys.path[:] = glob.glob(os.path.join(WHEEL_DIR, "*.whl")) + sys.path + + # Actually alias all of our vendored dependencies. + vendored("cachecontrol") + vendored("colorama") + vendored("distlib") + vendored("distro") + vendored("html5lib") + vendored("lockfile") + vendored("six") + vendored("six.moves") + vendored("six.moves.urllib") + vendored("six.moves.urllib.parse") + vendored("packaging") + vendored("packaging.version") + vendored("packaging.specifiers") + vendored("pkg_resources") + vendored("progress") + vendored("pytoml") + vendored("retrying") + vendored("requests") + vendored("requests.packages") + vendored("requests.packages.urllib3") + vendored("requests.packages.urllib3._collections") + vendored("requests.packages.urllib3.connection") + vendored("requests.packages.urllib3.connectionpool") + vendored("requests.packages.urllib3.contrib") + vendored("requests.packages.urllib3.contrib.ntlmpool") + vendored("requests.packages.urllib3.contrib.pyopenssl") + vendored("requests.packages.urllib3.exceptions") + vendored("requests.packages.urllib3.fields") + vendored("requests.packages.urllib3.filepost") + vendored("requests.packages.urllib3.packages") + vendored("requests.packages.urllib3.packages.ordered_dict") + vendored("requests.packages.urllib3.packages.six") + vendored("requests.packages.urllib3.packages.ssl_match_hostname") + vendored("requests.packages.urllib3.packages.ssl_match_hostname." + "_implementation") + vendored("requests.packages.urllib3.poolmanager") + vendored("requests.packages.urllib3.request") + vendored("requests.packages.urllib3.response") + vendored("requests.packages.urllib3.util") + vendored("requests.packages.urllib3.util.connection") + vendored("requests.packages.urllib3.util.request") + vendored("requests.packages.urllib3.util.response") + vendored("requests.packages.urllib3.util.retry") + vendored("requests.packages.urllib3.util.ssl_") + vendored("requests.packages.urllib3.util.timeout") + vendored("requests.packages.urllib3.util.url") + vendored("urllib3") diff --git a/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70608d2debd811dc4528cf0ef6d8c10b347c6987 GIT binary patch literal 2818 zcmbW2-*4SC6vyo(H@Ww=cWX!YqrgV?t6MjgZfxZNO$d#4V$!q+5Zbt!6w=u3P3y#& z?Yr$}?Ni|qi3gscm3ZM_vUmasY5xLG94Bs>7`>gADE>J1Hz&5w@$sEruZ!U7|1$UZ zr(+2HX<qg&A1a^0Bmcq(5!6Qn6Nlm4={wleUFP=PnqI$E)9?Gl>j$*8-rnidWtUFu z;$7UIBrW29hx$Dl{D{RL)ZKCG{v&jf1iQ{Irv7^SBr+v&iTk~C8_^zVZ)0rOvFut- zSWa5@ERR?owVbk?wmfF}j^&Kyamy2yCoNA|&RV`}`JUzbmZvSxSbks`TAsB$XL;W8 zg5^caIm=6ymo4WluUKBS{Lu26Wn{TvdEN4c<wuq`EpJ&a8WQ&_H2-n+d$-KWD1J%{ z!bO<La23$JWyM-ZXbC;ENHZ!!z8Zo!R6HyN1&s;|N{Nv*&D};F@*<Qxr)prj=yOFy zk+7)Sy_+$xk`*!|)Ee9WvmEdtBjE}SQ(g-MC1IB5LzS#B8YTq^t%MhB1iJ39B#8nM z4Cg5oGK0^;Rl)OcSV|>ml1JT_Cbs9XKANmZ&W4J{SzdCX9^6eK#_P+2asr;u;gP>W zLGTVzcoXe9TX=LzIh$Cy+emrah&aUk!NcewDk=}D)<#$SjFGu(9r_>LjMaVH=)OV4 zCy$Ww*Mm(o+YsMIn|P;9Jkr{A9y?pkma96o!kI;z?w)qr#R$H39>LB8zxfZU;KlW= z=*5jKVP*nzY%y>N(>QurH*~cRp3D=a+i_eZIgMl8jqUuQ9;`9Gk}#=###6(Id-c*R z3&DkU<w)uv=VS;T)4q@;%ajfzRf$q!-qYQt&luLdCR`|~|D(N?L{jYyXhMENVg^R{ z_u_)e%LNFMYv6p9Fm^3{wpOgGC$~&v{n!XxfFTx{isPsp>Gq!C)5bX`pg?%iaqua8 z1lMK9cc$<Z7N)CeU5TCzn4V0NbU-19l;BLaQ_i?Z@<azDlZs_4+BX%!b$g(4wrE<~ zuml^c5S%dY?0MCJBFgzwDyymeYBUrKwAG3KwnSwjV7{F)NjH);i1=!HzZ%)VtY-dg zk|j;E)eIt5_sWg6SWwA_B86pcmx8asD=c_9Qap#z3#!BjY?|7WA(cv2(|a}evH2s6 za`v?*JKCGo+<{$D3`@gks?5fzE*z|br7Rj*b@@$HCFiU<J65R#tmKtLB~hUm1SOce zdbqY6aY$8CvT<{v&r@19GY$_n3Ep8uR_Dek7%jO}<23v3Svc6vo+jdgP{?>O$x=1W zY5O0TKwW$T!>}MRWPx-L4`94zzgEj{^;u+c2ctQp{lu(bb#aUt@L8S|5S(IMBv=FE z77?~X3Gqp*GY9`|s4`Z~kMECOiQ+MP!kCKohIQ!>llx;Evw5sR*u~ZPL(CaZjdOi% zN@Y3a!?AH!>mXa{ph;Ob=a1?jjtNhjBVcu?h60WQ;Xu~Zo;e3}z$K&;HP8;1V$!sC zmX_~){b1?-@{;!Io&e6!rb03}&mr%_!D5moSnWLgVtM&~ymar&Iu&bgoo7Xz`d=xI q8?)`(&B5_$0B^E@!h@9F#&EYhf5va0_T39^{chUc{%&l(_WeIqYjKtU literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/appdirs.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/appdirs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..75df8f28030f40be62f6571848efddbd72a60160 GIT binary patch literal 20565 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 H;P-z4yBsaX literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/distro.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/distro.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d7087409e87478711c7d0451e19bf0642f7b444 GIT binary patch literal 36098 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/ipaddress.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b29d55db5ae7dd551925994521c2e70d31d00d64 GIT binary patch literal 66408 zcmeIb4Rl<`btc$<XfzrP5CkdyiKd?@Q3Plb#2-NtmMB6LDN&XoS)y$jw$g6mJ&;WT z-Qep6NpzaFBPx!QNiv>{<FjXGHleh3CgWr>$(+QK*f|?*oXO87o9xN_B<bYjWM`f6 zXwU4NoSn(c#+!}z`)>WbpY8@hTk_A@fb8n(_v+QFx^?T;y|?bY_4vR*K7qf5AAk5m z|M7S-@xSwj`O6`58lT#7Dv@v#3kf&rrk0Z{sfARM`SfynAuZpTg^Zh7=<%{k$%Wqa zf|vDjOR0t4_a`dbGYPNnYTkc3nc%+<Br2&F6YDuIztE4n59zx%)m^W!(C-a+g{$dW zy*~JIQkBLVl2=py54t^W_LaoKmP*d;Rk`)Nm%TEyuoX4!MNPwa&lglpZqDsP*{!;U zyxWgo+q~^w)-Bvl`G4pRxP!QIAL`noa_+pl)g68%xv=BOguBh%{z}5#?(MvtUfAW{ zx3JsYv9Jf%ce=Z9eV2DXuJ6U~-R>Uz-Xp)?=HBn_MV<THXWf17+fmcoUB`U@R~&c0 z`yjp_a369H;CsLOuzL{S54t1nD83(Z54rEa_W}2?dj#JPyJPNAd>?ej-3fe;xRdS_ zzDM!KY4;f3c+A^{797Iw8TUATANLO7_dD?WgnJUdPs;DZ_&w{s6TjanJvoBkkGPNG z_oLns?;W=@3uCx)%6$x19`nXf!%_S`?atx%97-HUiE&(c+&zOUXQYk^Z^9cZPU7kl z?pa(tD_5uR`<(kEen06=NzK!^@|1fXSI&FWsQDOvKkdE?zu$!tta%1ko^jueEAN&% zj(f+w>EfiDejzdXT;oUQoTXB&e%M(qU%Fhs;W2g2KX-llD3TdxrBo@et}U19<!S{* zF8U>Z-6>a`=ho|&tCg{Q{=(&QEx1v0)@q*X)T_>-@0IG_(beiz@2IWBlbW4U#bsv3 zDY>ri)oNZX&r21rexvGNt)bR8I5kF-t)aC_d9mtx#pQC{^GnOM`9^kPY<z5Taxuvw z_~SP}XYi?IkTetMSaSZK@cHz`^}3(NMM=IobF{v)dUUnCdZb*b)l19EM;32fs$8jG zo90FN6t8;~x9T4)uj<B)t**EB6c?*2tEGAo)p@mIy(*dFbu{Shd@ZIe8sTS=M%u;e z(yl>dFuhW*pmk3qZYR;g^t>&~Vtn=md}@1<Ttcyzw%<zD6L*qsqM3X(<tBG0{$A=@ z1`np>bq_r5v)7}kR<>66*B0xo>{?~Dw0IR)Qe)$-<i()heh*51HUG$RxmIUKPCdvM zskb)9y7z7Dk>%<l`gjT%^QhE1n)C_j*c+t(`%Tq}<Rag|KbGZ3K=BANO`$ZkLOt;^ zfO0E!^I?MJrG2;3^<*<$Pu)({MtHB8a?__0&GgR1t<<$0?@u&S=znG&!&<&1-G76m zb2Qx=oC6m5MAEaqU-eu0a!p3Kvgoz8nhusL^<sT})vJwW7J4y~9KKc`hPzy<01I1b z;Nn8+;`La!g3)IMOMZ1F82y8IeXW2bkt`%L$$WA!Ih6Fb;rAl3j(_~-;7aFz7@0Z- zx1K~72kR;6B8YBnkK_Ri5a6ep2{(N;QJchf=4y}sNIiWg<MzCod^w36h;uXXDgXf> z_M-GFy0nXL5aVqLJW-J+^7e^-+$%hW_qqe86R%?8*R!_?dd`%=d7mA4Lk5&6wQO3R zNi;^#W$%*bJJq$iQ(bcWQst88ELDBy;Q536UMbZbPEduD=ieA&RUG#>K8B<*+Wq<W zyeC=#-}=CN-t)$3d@mDWzxGk}Z%bmd*WZE*J}dV*mHb{LtsYOtIzy~)ZJV#w&#$a5 zdn+EA><Su;rWdkk0LHnMUG^%M>X-eke44LP3E$HiG6<sQb!{A1Yder6FrI~E4r7{^ z@9p^Bk@DZhr}7ue^`ffPPGo|QotLpDYBm#h60a(HggLVhS3s1K<#-E*O$&lL=TO$r z6$g3y4%W{O$U7cJ=B7h3@hT?}NJbNQ@fc_gFeBdtow=5OKUfNqjd?>b`bbOb)he*R zXR*3gsgI_7k}-dnNfbD~gKJOVQzH&5c)Y=GTKp#7uuY5j2;?wnlUFlpayJvV(l_@s z)6L}7gny`+eji9Rex;7%`nBO$%aSs-qnTC@XtQ5$r7<;InOfajRn3dGtTkYOCP?`- zUoR|{o{8C{&)Lal**~`PG(I&ZUSa_=U;(WKa|J?!g&)k7+k<b+F}D}rS<T+`x{9&M zxdnFs*ZbT-Ky*uMTk%2_%gD37>-pu%rFWNamMa24OZxamg6j-EHDZL2Jc|+c;|d6N zrsgd#wR)=c%RuQ^H?zf}cdc0b04rc^iDY9>hu4m&V)n(Xg&%n_*A${6R+8kcR5Mji zUd{PC>OhZXs-PQ_^520{t-<I#8cqA7xa=R|y&mt{T4}jM11ny!_#u>#9wsnJav+A? zn#sbpnVW)7(1Z@}Ual957y0gufx}|<tr6fngooq6sqJW{Y7VZZ2r_~R<DHxbG>)RQ zf0zlu6#-9X8LLRA7NWx*3R~zD0HJQsSq?*obIT6m41UDhsRvQF^Hv&*Cx`a18rs## zX4(vITgx*csFL9MN0{(!DiP8M<humGUB%TJ39lL3jYpV|bcXfj5YfUo3|?Ov*`a*^ zSe@<T>@w}^2Hi_2JU^Om<%-2hX$3!8`C@UU>aG#&twOO#1lM=^ipAP;wO%V0WvKlz zRIi4Ag1Jd1Q%r(3NsfT?N02;^k3bExA)8C*)TdAGz2UIbP9%%?*gukr)A-c5)I|vt z5HQ`^I;S}1_m!5{JXzx!2j(34<;YLR_rR<x797;XaM)w>qZxl1b^6Dc5S3cJ#iCnX zMDIGa|0GI$6d##YxunnE_tw&Ruf9^MUEOp`!Tqy*hnD)YczMTGz7scYhg!+scA+FJ z`|vr#0#}f%=g4}I`Obg=tEZMykYk;wyj)MWm3TZ{qMiZs)&t3Qp$;Clnb?8)z?Nm* zl*x-+l_~uUUVou<6(dlAtmA-3#{zK_+=xg&zE@xKE4){|c*R>3-ipJuSoMAWB%2B` z$id&7f2lSrIsVc@$*eP{t8~DNX(sEi!z%DHBe^)v*)o?DC3RJOTZ<DDzaZwVI~P5t zwzj&uT=v{|nkpgMfu^Bev~=>&p{YsdMtONTR1Y3ntX67eEPx8>aDmdJb8+2qy`|FH za$Wc1dFgVfD{}<Q^=XaK><48+`%~azo-LIjBnD6jkZRT`FG;r#=}sSVR!fitT&G;C z9IQK@0zk<@lkf(7&xBg9pHYBr+&thrZq=(fl`2MQb=52Rlw{E(8ADY=SZ*D2o+!J{ zdUZ|SNwK(uenUcZMljxinCwiB;s+R+l1nDK<Y=i@5B_6~@q2yq{Ah2hKLkCQpFYuF zE*mHc+uZ7rHns8r)WC%H>b{5Ol~DYAd9|o-eIF+dDRyEgg%y1`nN6ARd@_|xrE;lE z(x1cq3zph*5w?@Af*<R7PP!)KoyfG?AD&bwgK5`R=3Kapop|4Mmx=ekehVj_)?kd? zZQ>bC$G39cfj(2)V&<Lwd5`l>5w@>m(v3OKVv4BAtKs2XF4dgN)mq(w98_~^o}nH0 zFg0~m--4;B-)yI*hG=|hn#&^5p27_AA438W>@>banNwa2>8wO|1AWG7QP=-dC}wA6 zUe8MP9h#MAQL6Jwcma3boRu(G|6H=i>Cz?4{=Z%GHnHZNhl;{qDlK|u_JuBd)8?OA z^&swrSJn%{L0o?<Xwc#^*V7tS^V*_cR*T`B;zAwhgiDzEP`oWdM;!1M8pjViwJI0q z^@G0WTrAbfP$n*~;}Iw!FP1Axsf-2jA_QMq#C5%Pg{D?m*X8JTXpW#Ux#=a7+>ro# zezd1Gz(vz`E;KiJV<xyEb22G&GQL6<Fc)o|zsK3Q9ZBLovo@M<tc_3Mdgob4UVI(; zPpIUe^t%m}9C^|!sd`$t(lNF4)iZ9I{H5Mq$zYcCls=3F?s@1$yc#rJWKHyP?SObr zV>A}8g8NZy2sjc=HJlNsOphpC=P0la{Mudk%ZlLvAyVj<*#R^BP>9!5*wn`45uXSw z>JUvkbrYqzn{Vgy8}NYV)iPpUgdK^BcL}Y%E)xu@E(h2N#iilqEP@FmJPpRvG)@D> z=a7nCwDGV(_RdvO7fPH0a*1A0RFnR0Jl-03_Bs%6xq3q+Gezb*qtwv#X`&Q278G#) zFFdaV+QAg`S=*C7^;>T?DmDJH8y-!}d@~VgrhNeJ5s}c|&0~^(-#rfQO#9&a=UK-F zRAT7*Oms-In6_$2^Lj|%6&_MD&S`wk;8UZvP06a*|Dnzf(kj?vZVzPqhwEt<?6Q(P zsp1{YH0GZ2mRB*wfZ#Pqa1bCd?=bZ#Q7eIyv&Ye>90&qrz$%{SdhS<~M}4Zi8+)Iv zfJRp<o^$Z%K?jwtl<QO|fR-Hap`7hEYFBW6(A4s6tu*xDLQ4%Bli^&C6V9DQDP63t za-*iSOpb;P++iV;qPo41^xuPqSY)SILPgjjJ~ir86l4ICBw>=l-Vl_`W6dNK;1A!* zG&5IH&GZ$hb$2GNru|2n__dT0#d8L_&kPjLd$^Nit}5Q8@q6dWSZqpQI<KvH*fye| zR;&8#IiRzKZZ3*m1#|sD4aSWKDArU|#$7X36naR@eB9)uJpX~Rx9o-_+c~F>cZpD4 zFO@6M8OTsBm3`F2<q)ee_h${g!orM!;b@zN8w&OyAO(eGD?@F6D^u}qVw{TQRV;#i z939zrZKW`JJyLrs!>Vy%H9l_Jic5fvkqV2VZr{f-qmn9-&tb&!vPF`Cl;|(uT0|VQ zn_o)NDq9l;;w{FJW0=^&RWP+HaT>Z5iixA?#-E?zzJ$W!wUvv&Y(TN$`H;pb8G!F# zmwnl+hHk=jsDbD>9u;{UgJIXRF-!ef*DPePo8^_Y6-Slii{u^L!)7CNtsMzc@W|cT z#%g6wN^{H@0f-5o1BE?+^a}P49F@<iidz}BBt9J6j7GbP(tCEk$d?ycbdsYY8#VpZ z!292Y>g-rhKgzkZh)?a`BjG&aMx?)8jRdwN_tr6Q$Z<3iSFmYwC5;($0@tA3Y9^Ob zn&u!6I`ov`PFNNjl_~$lde5y?WtaT!!SBoUEPm%uF01S8g^D_HC5Ks>MA~!nyPBD1 z&();=XZ5~%9{Kd`RK361)6DEjxV<}p4{q<S#O>6rEaofjHnY1DOR3w*TfNO*HKX0$ zX7*G9+ew)BEZa<7DR5Ktxx}?su)UN6HuaT0lg8fq+R94FFE^mfu{@F5&AbFQLE+N| zvrLcJ*_$QqF$S8bQ>RYJEFY<v`lIt?guH>K7b6EJPEOKzVQl>1=wXY6V`I=4Z1mT$ ziis&yGCI2XS{&y=sC&We*Jqt~%s>15yXT%czi_tr{-@4gIQznLb7#)lsy@gUYPLJn z=A)Cx&}_x*DBVGDb7Jzu(W!}Wuey|*8b3NUd2sY4Mg5|>O#%O`OcON{p^h6tNrTc5 zJsH7ZLX(223N)Ftu;2K3>3Z7?p99GN?JU*7;_2yYM_CM5My8uHqZXT#Cf5*lVOIk@ zxd4T(uz|rP4!LGrV~D3~a!L@JsEZ7f`=GO%e_oacY<D=|M{8JmgE|6EpkuoPidsWW zrW$RzBz8UEG^i40#nSem#!##D+YIb<C$;FPs}rs4jGkSMi5MVO)~E{#>$JVvVQGdI zYif-H2Wqk|@=Jruj8&+|jYAqC%)05Asw4f8*9-6e2B~Occ&&1^QoSJ>eBB!%*Yl$T zO0`-jK3=MM8Yx?Sc9dJarZ`zd|8XW~khBJiSZ<1tr<Te$$uv<L<A0C|X|>S*R$p=M znP-a6&Yyi@H0QscmtSPU9pF|kgiliXR-d$$EM_amzDcg9BKOjOPJGqaX;C*yps>54 zw(S#p^0IMDI~LkJ<Wl)$7FV)R^JbA_9@Y<7=(D&#nDn`&Vwp4=WPr-5#pS<4#xQAR zuxB@)X(s&_n@L(JaF6m%3g4M#>Q1_u0dw2a>;Y4d^H0$-pqY6jacvMw0GFOY{(cn8 z%^i^USCdKH0Z~uh%HEu=_u%>Lt5_ny_C17Jv#6ub|9CTdr5Eg9FRWlber?%U9NfxY zTjrBk4pOBx@Y>H*tE=4C@T+T=l<vXuM2E5NFE5u?VL^0>n;VO3*pmS>0-#=mJ(Sp| z5zFmbU<qe=b;5bHGvOOQIyrMNpw{Kp$!;ZQrsGAYx)mkWja56{wd~1BRo1o^Y=m^v zGYA38HcHSwSo4t&qA!OXG?U2`lj)a6og=60(~i@1nV7cponR6J!P@2O+Oo?H8O&yC zfyh>uxz)A2j?Jbzc5BS#>*Z4DCGBk-`QS^VnqEYg4?BR|91C&YW+^)ezESNl>9y@( zt&7rPvyVeESfxq@cmj^}#%0(--SF_=_iPW;W|VI4{AdnbHe`ZUdbPUR%3-?=(Dv~2 z5|S*poM7>iRbodgd!3uSwbs^)ezoK-a*pdR!XE0qm}0FQ^aU#(6dSGH+S)}_RP)QY z?ytyA?<U@awkhht$*E|9Z1e2hX!O@f6UeP6c9V_Fk{SqYz_veV!63GMhLgE;0h>Uu zvbm0O5jtS^e@>vDONm=ad{X$NZ+^K+E2TfVl>v3g2<v&FNqaXiox2kd+aS7O);|RS zm+YQgwM=Kq(tu%<1B-Yi3r6pk@%$%Z&wrxR^Xo&P7ZeVANk`tFxb~l*aLZu>_!pI` zP2cU~-4EdIi-~K)&9wjJCJe7bZTqsWTdvx+!9GvZC)hOA^I&1Yq=HR_sm&*o{^6Ss z*9*LYzVG=^>Q)cf+2oypI;mXtc8YKOWRjGvzNHECN3y*Xf=a&)@SV|f6kKb7(lHs* z5+ckt`Rg=kHsa|lwwemU-yI(m$^&*VP7}fpN`4bWqWdh4@?W8b#3phK9-Cq042S|g zP7{TAT`{erUEycRyXmdwU~E>(H$mAf<0HC!!x6smHT-RoUl|=z7LOms+=8)+VJ1rW z=~sCzAL1bvc~!WB!MQr@3@)zK6|dRa0-C^0K0`SCRX&@>#+r!ftt^xRAUU#>%RDxe zrH7OT7O~~k8dV1%EUZ7ojKs*vuz{y}lUMs3i3ru)iQx>0NG478VLNg|U>~T`WG;oz zU~+p({TfUc(piuem{@)fp0h*+H3hmcTGm*}b(khvG_aH_kRJVqa3v#GdN7HSrAaLI z3L!9su6paRaVXbI7olRI=9Z+E<ohDv<UtD5@KP+LT~N$&qgmJRu0)(wXN6LGVE^z= zvdP>6k!iNHR&l|YR%m?=6N&QD5|#^a7iy=(@orMrP9|NgO`Jp_F({C@ApJRybZ0iO z2CE8a(7<(fMcJaD|6Zl$LE^js!w?9=_|&Qp4eI3;=#nm1Z+Jkq!&uCCm!=Ig4Y^US zU6$5EDRQ|4t-7_27YMS0&@K|7e4<oYzfoEr;{@SP>KCb)bh#H)2LFzWQrRLT2)GN# zRR?fc6ek003s9`UP(6y)U0NfoM6W5zxRFk4KL%kou=KDK**E%5J*SnB5~B`Sbp7h8 zUxspz@6<y*nho>!x<*)%W1Tkpu(cwJ`yU22!ho39HM+=U8VJ(;04<9%;=?Q}bV7{L zS^Up9Rq}WwF-*fce*BN)7bmv;<BU6vPmSDl)HG}%<Mp^u!MuW%V<C&YIPf6fi+rz} zlj}L;``o<b``muF06W&acF*be3UJREl6!Cq5(gdDHHf^p=perZ`TN`*Qf3HwanZr` zt;#uPVc5MN6K*dgob%7kshL9AsIe7@=B$WmtJ=dG6Np46H|A(yAxj%aPT<jGV^+^x zBE)jFa!FKumbxm9S|A*A1FWRYqQ(IIy+zEXWqOZ*{q!lYy3l_XmBj+gu}AUN_~_*H zBktEYCTv$C-PjrJ(wHgJy$?$Ikv_aL)Cb#+V2QX(C;WG#1zp;jr!R--aor4BYFfKH z*4m&{_x1)bFP%rnIb^hgG@`ptqJWwD#QY1+YE^^;ne7~x0RD#^Z|u@oRFOdam?ait zfWDq3Bl{;Nk3$zWJ~pv`bWGP@)OAPrk%RR2K`|6BSB~)Uv68=9Iv6R`{WX*0;}f&) z#S^o$n|u*pwz+>N#x9PzY?_pxMDJ#F(`?&-g+s+y@4AfUmRPYqJEVP$eX${p6}96^ zd?lSYgHLS_5*IE+G-zB(?f@UIHcYhNM{2&Y?*O0!qK|n~salk*t$K^)C0GH{Fr9{o z{{5&4J3E{&P*c|~#U_n^5jVE8x!k5nU=ydYBi3L&XRR)pjiekR4LyfU6Z>3n5!gp> zAT$}fUC<K;8fX6E-q+)9I&`19<m6IXX{E)<A)}le8b=Pe&d4LqIPC6}+A7$`B9Rcw zLln`-2x9^iKlLb091pmgdj|HjC(&;ICKH#*A`)Y;e3}=2m<fBT5|O*$>2cXxyeeCR z`t7?3Ib~c;X=@ntpPodG2VyX6e{zwP^N&?iVI|<Coiad3`2)I^CMBvv(3wEqf=mVZ z0>A|@mog!+0T(`Uz;{NVk#Ycv2OdSbIWW9gc2)q~vuJk!Q*5UTeLjt=tpX@6bOoME zhnrTv1{{BM1oC|vRBA8XkevO5v#hd|XH%JUF4=gfGmN7TTC7C{!Sv$h7XYa~aJiXN zOV&?ZpkXfwqf+w0fR>I&G=iu)Fb^%)!A#k`*?`H5N<n1%tdbD=47+)yY<weCYnFwN z#CRKCf&sC8I8+iuh)BzQr$u_f*_Xu;b{m&WG+sHrsbYr-NdhC$-`F3AV0&>3KPm=D zA_Pt8FG4is9L5e0krMuXyQm<<_hV2H!oCdNe{K@jAns$IC=DedO1Y^$iCbCjh(qa@ zzMa0+>t=4{U_zQ}_Uauf`nL9z?#EK5SKkQ496IsI7{!Jo1fcfuP#tR@49E<!&5nIo zpedLP59T*|n3acIFv@ospu3E2Ocv$fh7|Z_Gof5rg|nV4(%4eG1Osl_ImOq*+}5wz z#Yt4z{s6{7Te^VHm7c)Um1;oj_d8@%W6y)~iLQE)57HG*nL+gVe;@f)R)MLtrS6x? z%Xq)+PI@)}Q@mSPh7B|?vLUS;WFVar>kUrsUf09M_j0Y{#NMW*UWJV6O(%(rv|LCG zaQ~UiGu790*rOu59YGZ;gsZR!nno?eYe7(&009NLa>|m#Elll6*Vqlv=#>Q~<)vkq zfon9t#G)BC=$U|{UtcEI*|AGI!5*xFJH;H6dW=!T^X!&dPeG?1j?c2r4@Ek{{a)$F zWn}7@H_Dj_u1yIj-eFaeqy-w51S+cF*}o48u^uSIPHTmjEoGtuG*cOnKkU|W7G|#| zYi=b4cRpKAoTO5vz71y`c3&aV`Q=5;s0VYSea2a$MCi>@Vl_?=pruqKS1VvFuq*_X zyy+86&x!8yOz{^nEC}WpfC2wiINMMddf#+wOYw=bXU=2uwfMyOC(mDafv(D;2c}Zy z$50qbmr7lxl;J1@kp?2bkl7R`)q5hdL!-HpcHU2H8b<AjEd@*s8X(bAc^CPN(Kv2} zCrG50&gex+b$yT$gmN#`sFVaM9k!?>esnf0MP85wnolu%%%J2ms-!|S;ZS<!G4Iyf zOMa|#oqBJFb}6y~%Pv2u*-;vl3t3a3Fe|a@nO>d)1Zu}ZkQs}9dNv1je!C;0ZK=h` z`Oz%=Ru%13L{Py+v0lVL{~s}tjZ5JXG$|uxM^XRNyh}<MVrzFqP)`*EnO`N^Q4UGK zjB$`C*OLOu4JNZ`A|Z2)0~?{At;vcwoKJkYP&UJZ(Ta#d&XRW1OkoeTC<eoDZ`(+M z#%&mPEyDTlN7z(+=wBO`po3ELquXL`bjmsHIG$_es7V4nTKB&nKm8wI@`Fq+GWokq zegsLYUs|@}A%ceM|0pjDzy<W5;m?1}<exAJz$`iP`99rp{t93aCjjuV_*dw`zy3l` zt}mA_3>0?b*Y3i8DY=N!_K*ELjZcl^8rLBy4HA5xRrnWpKvQ$H(5tjY3puSb>eD)- zywVsg^eb)Ag4Pr*3@9zp!l1hoOxP~bkTpIw=UnnCLiV9AP)bwHY{~v0E(%ac(rNdm zbbv<F1M4%{Xrm@jfvpAwWqI*3)t7?U5_JSBSMJ$DwHxRpJZRs^CkZ4YNJK;uB%<Ji z1x?uZc`V=DlJ6p;!)21JaPbZRX^>@m*aQGx*iyh!N<!Q&#FO~3PV*>G$}5ShsVei} zFs{H`Unn6R5;e`NgN1!DA^b*?&YNtN5;hymiGopy<l>th!W2OgIw$`RY^4%-NbpJW z8{1;7rE7Vlv1B;}EFVUO{J9BLq3!jcV@GTb^5(c_H^36ukV{@6hyDcaftQcm!*&<= zg|z=6@(q#)u$7<Wd}IFsrETXIRL-<92^(-w0kO$VlXE6c1ZRly(Pk(75)+ZrWoS2m z+EJAJ9HA!sB<K?badMH0m*jUF1S5{+9BvCi2S1_^<g!Ocw%Zu=oe3^~bSm#rdp#s( zs?|Tq+-pd*(xuY~(|s3maIyGHY%g(`zR&QwkK>~h>O8~_9_rq}UEg>Eu`69H{*QNQ zpcINsO$$NIf@8v5p#?N)JZumFH7G2y2WlfQNCu-V;F?BXHX`-#_@*C2vG^r62Okpp z`(m>}mFV0S4iA8ZP#eHvur9Jmi_uHVTd}07Wi%{T+=Z0jfnxF3L(Pc~ofPQY8uD^= z@nS}6;3L9+3Y#*m3>12oTj|T*O+liKS^=oAaIyGXp=QLPqDn;CLHG%kAbCLx@G)y| zQl?sG0_wkl;=dDm)!U*25ZgxS{7S0I)GML<3zmF^1~S7ts`h0;{k_n;cShfBIf41n zEnU}m|EKYC6%K&3!vCjCeul|EWAbxMex3<C+I<QCFz$YuP1%J^F3Tkx@d0{sTXH@4 zmsbB|<%}%fX_P*VPtC>R6<xmXHGGM?MYey2+^zWTcZc0=_%68H-TUx8;O=mD;(O5B z;_h;H>n)!x?jHAk$#2E=z3$s2Ka4!1uwiZ@?%Ng>i4FPf$V)Uf<nKdXBC;XB19^$c zhWt()mu;7h%eLE9aoP4Dq8THyB^T~@&r3|U<icJ&Co$RZ+}pf;Djpm1Zn5c^Fc zuq`}*auRzD_x2+%QP+@v5P6BXhWtawORP2I4<IiQ){uV~d5Nxu{6Y69=F`*u%Yb*| zBN6rmLV)s|4ZG^SscejXgRvZlP;a13F!joq2}R2#BwN|yVhIXnvu+SsVw?d(U%;;b zOw1n>0a=?RgphUFF=1j@A~OHp0-`LF=1(_hMhAM#IUtmW^q5?TXkbI@LeGKPQE0DI z{&%B*$jM!35hv^a7J9j&z5xuP)R*1ohZC~)2okOZ&|K0thdElMr*7_t77{xdJF$at zI|Xx}A!svUkI+oNnxwt@wTEDYs5~5g{7Le|+;u*0ZH&S1VnbZa2Pm|PYlpQ~59uZa z*Pwn{E+f7Kh7%POi%>o;daF?U)g_1l_xyboWrE6RjZsz##8$mED>K_5<dtm!ZRgsf zmJorZk6uemCG7DU6})imU{9&5Z}sZ8wEAq_t>n!(0`^GXzD&rIGfwm>!;r?X&|?FC zDP$4w9-vQSFqlwvgTCS(l+#7W&iVfWZPGpRe-U~AmzaEk36W1FWU^%{3GDyEb_P5c ztz0x`VLD^R$WCO_AHn2h)Mc@Wsz!xPf=MuAJ;mKHU{o6WU*j}CQ@#|yD!DG<i4Y?c zJ`mj85!}O0+CrqHTxZG1F4=ZHijnAUok7#epN9~3Q+YCmAk<1$LO_barytRSygJZx zrC9v01QGc;vZ+Q%JD5_++QzQP*oPjo5X0jEXH8}vaC*yR6O2GF<dj~>EOncIi)5CZ z;{F4f<z;j(B(rep$;_e-%MkWMEE9#cgeFSkno_s`#_hsONPr1YvrT}p^6ELfW&JP! z08op(%Dk3WtB1*ullA0A48OGuOKqN3A=hDo709qzC4&hmd5!IVoyn%9*<p6AfJYLd zzN7`2m1l#_h&)Tto`3x2Ogn>*uv+Ap(P+#d`9`DXz_)0=+5hJ#79w}A<7bzpgDl=2 zwue~RVfoY?v)n}iextN%$1})Skf!}1DlX9)fDzVf`{Wn*wKHfVX6=<8dN@++UVWTF zQm(+0>MEW{p>ujRr{*d6ihR2TbqmK5>c$0LBkA4%cNqD~XkLoNw^>N1Aos!zAd}fe zr5H8X0i=WSkvYn~3cN><QT@D{T}6CPB97#MO3j4MVKlC03IE2S3*PcF-BB3|k9#W& zD*y{Q{Tl44VSi1mh{nv?ez#8Ls#s8I$bX0(lC=h%;lCJpHs$Pc!%mRGOGmiavm?e8 z7Ylp>-U=tMu)|#+chpcp1#&z2IAms!VPQ+$<Rh3j=o}(1N>j7`FQ6*F!h|F=7^GIt zD5=dLby#ksl8Nxxka!NVJNqJIV;5huN=N!-C&Y=){hAK<3%%=^>(Zw$;d$7}b?VdW z?48T|TG`U6JA8hY-4PWPP%Q`VlD4rifU$kxq{dTfY&ORPuCpZ_g~Hb04Fre^Y-t~7 zdt}<C8uv$l8ZGyAw5Ddz_Vw<qDaczYY8&=ks4daS7cTXUwB$?OTQVT;Fu;F0)RaB# zU@^ryw`CXJV%QtQ+`zpPj0)#Q<KcPh;LCcfKeKVWQJxKBiY-a2Im78B{C$^E9l#!= zL4L0`Z(E;6T);3Dixji1kC5v<c-6*MR0kqfR0x(*U8FUsYuIX~*~aMq5L<me5;H4) zm>1Bv5Kk$D;RQCB^EA<eB`%7Grdw)z!?u~Tf}b<^h>EOD$|kzdQbmeDpyJpA-zY z!thahWZ0IsB%ZAzWnAQYw&RU_kKzvCJPgq%tokKqP^ZFp5_gc-#u@bH0!^tsQ-{?m zX{A*ob2)$;v72FZ<2zZGN@X%)2y(weQK7`0zE>0Qp`gqEMKZu((f)*NuY9v+sOJ37 zX}_;jQ2JU^yvQJk`M=pz;Q-R%yY)QcDkCTW6xZ6I>{?U81Td2Be^T{T_RE`6{@<t? zD#PthvF)S1r7r+b&wDFaS!iu$_-wH|fww>jK06S==uH+9xz0f-^NfSB6~wrE!RP5( zhV3vA2g>LnL-3=MCqkZOra1k}Iu)M~|Jz9IbSxQ>SB&X~!f<wRdCm3Y>g4FC^JwG& zzN4FC2fcf{I0;Y2U4&T=|3aP}LBFPt(!;q+Rq%T|8Syd$=upedY#_k0;!bc28HBcj zf)B(Y7k&VKFELnueZUKkOk4edYdHHLf1S%u9)(qG#OZqD^3x~}FT_pPe*)#{^W8T1 z4t&<zFLrF?iShCA+1aC0Q<33n-(?rpPK>KU*wER}r)_^IG>5v{e^@1pF}S`i-rJg= zHC{h@TM_Ih+0aNAVN10J4?-wYOynd2J06vY*P=c`!q3uWM47;Ij|=--%JBocm4-G% z-sKo$TzE?Wv%wXshpowxrUG^+m9I5_F;kVule7h2_Uc}QvF5%hdK-e`CO6y~d$4KO zrA>_;xW~=B2m^lr2RMj=uGW}R@oKSQP9r%&LWmAsUuK=!#H@qoYm@RNU0`msU&%Qo ztUgL?ei^w|pW+dU)g@)M@RPhPa^|O)t25!Qfzj$vdTym^6ZlNV*5B5a7zr$Lah$;e ziHBqp5E4WIpCNFobZIJpZ>7a9ydqVa&ZOWQss16~*c(|;W0l)wl`IFBR$0D3jEr4Y z(|+5sihC5fQ_%7prZ&<3&iIdTR~5f0IpPQb{~3K>{m%Fw;(b}7dP<+g3(xRa3t%MH z6mFWUjrp(|(5M=#3<`vyT%^M)SeuJH5P*tBVie+P)ZhTCw{2;8h~>>9G?lm#tIUQE z3n?TG`a}1qU4>V?l5GFOnHJ@2E#wVVU>3BO%1t!Jgq=lESQ1h|tn)MyWg>w3v;)$O zQl)O|fx(VyvKK^}6qh9UAH#qXLF&*^uOe>Y@K_3bkq<tF7R-&oa>jYYVg7OE4+aa) z#x%`NRojw|qzX+YbTAg$_yHtG%fwL{!csN3XdKpBUc?ZxHIot?nXtn2BZ_)N9Wxxq zy96J`?vXyw%Z_)A>u2O`vWCxSVmfj#w4{OjV-<lrn)68P3AU1Jc890%ynZV3%((5+ zqmQaSMQ(50B{l(%b?g(o^XV|h76pG@+BRX^hU#LE@Zq~Y7I`KZrBnCTBQp%nsjgkZ z(j9r1>ROlf1t53APW}NnHq*1v>pCrrp{0={8Ao&yBI^(tUX3<kBI4fw(G(d`opO;0 zEflg6ypH=u?&_dDZ4GIvU>NM$=ScV|yCxn`gkRZ!z}QMGLNdvQ+Pv22I~IRFBATJD zKw%-Yo%%4)@g-WSCmX-5YdIox7A}F-A2I|7O)w}>C_)Vgg7hKsRi#dc9U4u6{OL93 zpxN_5dDjk1Md=pCR9FV<bjim8&)EHF!2ZDbl75{kCc#L6P^3oWeaCpmdSwz_U=bn8 z$N=meRWJT+z@$YWi@qfnQ)0EdT0V&K^Va2sz64ef{kQmGpbBvf7S7ylqb`-ZK?n=- zG(<ZHs#p=n8O=&|P_SnLq46|+LxIPGcvu3y22kI*J+gz6vT>^*j^Yd=y3=6Xun+SQ zJcTeLf#_-!fpD{78K?qXo?6snbhiA(gIN%|WTf6pZw9#jr?Er03$d&cci_3ecyv%6 z=9)R#Dg3++SCT9JE5PUisl5vEpjp%_aKocptoZeECdKq6!D?_`xuYO}1YK=`Fv5{) zwv4gVu;4M=-}&b(mW&8L7^uZaI1&4uh(P*Dp0q;=kR)4!E;<7NZk-|Sh_p7C5_L<? z6~^|duEDJ^!g{u^qE-n}Byni>zbLKPSaDIC-Z1TQ92J6uX5-}w4<}=c_>1sT77j<> zB)^IRFvSLavVBqYRJ<D+AY^%QbQD4@GC+0sEkPM&t&W(v2y#N-fE!VFApKesgec%L zRBc*80QD3@-;LB(7%|1yRg7{J)tH(PANo$TF`A$1)HPimiXDMzv_rN>9T}9l&^UrK z0XnECSnaH1rxhS9n-Hg?W6O3hSgZ7xNM<9q#(U;C&pvP4NtnedB6SJ|LktTg$S_A1 z^#->hl{f+j^?HC?gWp2i%rK2*W>{iX=%*ALYjr)KyHwj~r+l_}zOg%m76udO<?Q*g zkTpiYkrE@>=neZPOI~B2ZkKjA<7BZ>u1-1Qjqwim5Ad7>ObBs3k@<~=ie8G+R-b4N z#SK9TR<D81D#1!LuwUZOgG?xKp}1H93`X19$_LPH4Fq{K(|?H19$@k?l2(p)xqP*H zHLPROnTT><=9+OB<r8}fkh@?y1<6ZETzTa23-TF`ClEPp5YpK&HwvTH9h#Qf)r7K_ z-SGJYesC?o%8^0{DyUJhilnfLJg!%fj6VW}CUy_8Y9tZ)kTDXmW~hC6s6*++CaZgs zzH3-D#J6<`WpH#GWjCwv)b^lUFK8Fa-Mwb=RN^#t`?(s3D)G0mJ}UYTSsBAa$tN5e z)S#tCu@J-X=Fw6JAu%-PlB3@kBCW0$Caumn%r&jiJnX1Ai*Zs1&fC_*S&Mk$CODd+ zO&~IeKSl0DcVAYI_G%_rjre&0qkXY_@!SwFx=}M(&`eJvmg$_OcOznu*JJ^+jdqU2 zI{-Ii#KIW!#*~=J_!%)+(#A)JtB%akyHY*8-M&~sYtw{JNL{QQ(PgJA-HR5}gf3Q< zS+X=>Lv&Aw)qG=52jVB;5$>7#HQs4vfQ1D+heKW|(vyHn$dXQo1v{}`MdQTVMYKht zJPHWi>mUY3Z}h()@Bc27-(vzg6yCX6!Oz_wBsB+_#C_N{k5DGkC{m?Chz~pBJJ1HX zBSM4S&*3g73DT8h73Anj>Iw-%vhl?W2<B-7Db4k>=hU|N*THs>30uJlJP2Kkg7A^J z>vTXU{wiEFD~Fv6{u($XC8UMwE`=)8m!nwvg6BEUpF87BP92|eCdZCTBeYLv==Bg1 zC?B*6<yz4;QEiiVmKJ^=rRNA;lIlbsd?KTJqTzZXYPB4SpTVd0AtdWKQ&aC(g%oSI zwLk#U4CuntVv_1J<kMGS!2-8P+O)h+`JKs57Fc;h!nJcG_uA6)o7J06y|*G(e&F93 zkX5txhOkS-8xxTTT2Rhutj0ZYkyh4V+Rwm?JBia5kc;6Y&PW7YtakL>gddS9kxD^~ zRl&B2kFjmh$U_le68Hj48sb21!3R!%;&s)SP!u+VIlx6jSdlH6Zi1qVMi((!{C|yl zHW17G-^Be7u-RAy(d^j%r0v;V8i~bNH*#tdjnwPRJv6h`ZzeEw&@Y9W8?|c-6}qR1 z{tI0ux<FCF37kKB;hdfKp=s86(Yxy`=MqbE8%TwK0+#v+b+`0|sw8_phlJt{tB%bS z?*|H+M>d+_6yi&S9g$3Ccoce}YVHYopX>rX(<Y%%@KnEgL{2;Y#-V2`1|kV9oSr;6 z5vtYzW&l0ndyDekjX?7U0LY33O%B8_YR3?%=$?S{uLIz4ih}p%d2h@vvsE->;3|Ru zS=VW+tfzB$n7>XG3j-;FT{w)nbfmm`efo$5qA4vO@x4n>H2Kg{U@J`DooTz<0l;vr zhR7~0-w3*Y2<YCl(B;yiTtnuyIebt{XV7wm;j*HR+HCy6CPBJ(5oZd#i4Y~H^Oiz2 z=@U|2Om6xBrAy1zi>2jP2udN>eKB%vi*$x#7dGc719-xiBEZnKij7nh8vD(oBaj^b zDaV9rvM)fGAe>)V=4My95<$=qcXJG}+yh0Mnb(8pXQ;}JP_G4m{@n=bMXi0JHQf`~ zey$7HpproB<BK>Z$n-VTh0Q}RG8FA~G8Wrr;5QX|xq%-S4AaJqfcM7$-am{0uWi9F z)qur#5T)ns_ee(<ug{}Q$dl`f{Q1jFeuas6e9^I1xp@6g%>62p&oK!!BEQC;|B}hC zGx-fBV(%&P#c%WH?=ZQ|L^h`>I{4&pTLm0_4Sroahm$)J7RdiM%yEVExfaMo^#6!C zVvtWrgjl~ce^Q+xw!r@ibFoHK?p!Ydq$uaI0uG}cfV)`^zXx)?g}y?rkdc2q%;nyd z8_(tQ$MPcu{N*ya48Ho+N9tTeb@q>p=V^RuKZ7LdmWC6x)9@(Ic-d_Uw`Ui;$-Nwv z>I;4NhJQJI%js86pK^E0r9Rxrd)bBlGM&+sbJ~D6sNB<VZwvC`qK5ns^5Uk3{8r?R zquQ`?Q(M@kT-4x*cAs@n+kw2}J|NC&JKg=@*&p<O9F1<Q)9Ov@wxeEM3~Py{@CFSO zjPE%&s*K0E(ub=+uiSxFYDVLRE`&qVEbPxH>0C5{W(ifpwjGU-<97s2Tlw*c$*JjM zGsjPyeB*1l^~T>Y`D-TsH<Q0$@@Gt5M<T}vi&z~Y5G288@Da;r8eSSp_v8kCvi>LV z#IINi&Inlq&HJXuHVUR_*>5};xVu;ILzzNf?e$%2<G!Z}PpQh7gbaaQ0`@#i^cjj- z`p{3v7BK$fJtbh(p*g$LOXEHh)@(`kYnn+IS&K-wTg)9xTOc*RTVkC$Bj8r35IU@t zB#ajZ<++@%V<SLmt&|Ql8lpx}o~hWQP$FPcAlN-WB6}J7OtTTL9}%TZutkP~CSHxT zfgl>SJ>rZoaH6w+a(e$gJ+1p^A3uimNPosdH6iNwpb0Ca`~yP{=bynKNyH)*b%Mt3 z5|aWt4~aXIF8P;Kw3*j=OGt|(q%V*!x&LG;|5f4*Q902^D|;Lli&%hzX@>ZP23ENh z6O+QvL{Nv6L{OF+h|OdT2juDFXmECb%k8lgY)T=m%huf(?jn4VvMOC4u8V6u0ujKG z0?JqjrI6gSKq*X(Tj^w?fn#o<fTe|}KF9`JY`rdyr1?ntMa2BBq~NR43!0D<B(ibb z6o$Ye13V~)5B4pv3$a1fgg*|fV4@flI@yWZL|Dk75^Q1Vy6lO~>PG0<jtlVx;2PSY z3QM$8+lug`9m0goDYhxR{Q}*Nu1KAfY$6y5LDS_!wKjI@YeuPteKK!lwZ7g;j>(A` zjh$z8kUpG3$b)8-Dfa<i1sBUfkpc2}z{mNhD%8w8##jaY+lCwhOO{sQhXP}wnpc$P zWzRw5q5l&slU4P$(l8Z^p`!m;7O)67h^3CETG#}j(rpO;v>`PS5FKZj4iW+FwjV)5 z;<upT4<HjkL#W_%6s?gUQl&yb?DT>*0WmZF6NpErqgd*DKvSZm>;+^|!pHC4-8i2J zI}E<t7cGtbf;`H69O&BL)W*n7+6fd&1yHv$D(aO}0)w?!#@3*Mb{sE5W7ob9AaLx2 zi)PQOO8=X?D-4N|QrA6UV+;*R4^<@!6FJX#Fhr<_LaskJK1TZXQmAK*-Din|`f*A? zkh#@?b&Us~<<7Q&kz2lmV^f0L3K`$vP&Xc$LtGi!mrXf~mrH&L$m_QkC2@MA7l|yj zt>k!PY7WPkURtZdE_4JPC@mk=ZyRMyIO<O&hF+vu{-5%V`<~?lVXV!OQx5usQ-s28 zhptZ)(s%f_SD8G^<TWIQF82w<ID`^buBCqit>Y8p|G-m!$%(NKnS@LXF=4^^4G3+L z%4ZmSo!&PHZlZR{I7LG9(9R8V6a;|GjlIaY$vg08X6ym3?rsJ+o_+#+hU{Er8^2E) zO2yyQ<Pk(fB!<#5P+_WDm170X_@Mt{9~c_kcC=OVw%r5(L{T$Yp~p8Op}KT9Vl)Tq z?rrk_1G;V5ECM8pPmP~(B+bN2BXkJ2%nlsF?_^w2lJXph3O4_4D_3xADN<)FlJWzO zt6dR{`@2z#TAoiaC-_DM10)xkymZp?ezorr23JDl_)`b4Doc%-bYskNZffBQM<yA2 zM08HIQ)Bkg;K)<P{iS({1b4)H$p>_b`sM#DZtUS3fnA6NnooyFZ2LPc8nHCH#JN|y zj0Bz;Kqap3>wCX1v4oW#D3z<zvsB#Z$?_qp+;*(zX{_h7N)t~r))%3h$DwiDJOx*P zjo9aS6$G?rH`DBHn*6w2)y3#F*Z8BbR2*8<iKR3#l?}uZ_~paQ8;ly3c^gR1M4snD z-Vrs?<@nORiqn;0oCO+fD!&_o&UIGKc4=y;wsy=UoVm1$L+~Zy<}i($J^^<5YSzb+ z^!HNN04<>x2vj{>6e|F5XSJ(p0jA5EAl(;GOGNKO=Fjg(GGh=fn`n$!go6NY`x{^y z&Be$lojNDjE+%^yfbzl!yulht;1uN}y))ZxT>AZ&khFS0mGps#ra5d0*oM#>53xzY zh307ouot{%7Rx`6o4`&-K;c4<L?$%Bb_So?!$_3eq+CCNmO#w!P4C9;J}4ii@~fbE z;>Om~_#Q=Wgt^z@xg+7yC7e1{sa)-Z$7-ioVv1Czg+8}{lx|ANoLI)x>D%H43k}r7 z_|!3HYV24X0p<m&je$t4bSPGYtO%h03wnidRi+vykhm-+@slR~zk{NW5t;-^A`2&A zrC{OuV4l<=+bsmapmcXcTf|K>aB1Y#QYAw;5IGm^DZZ7|6<a=5ZitlF+zTm3bbg@( z<$EUdnk@!<wc+(VV%JTxjmMbGFqvg?oC)hiNQCF!H~q}n`6n+t<-5Gl2R5a_<2CC3 z9hUk_ChW8S=S)7q<foW?g~?}`aB&to>i;+92yvxO`YYxxG6?`BIW##TN{gSwsMPl3 z7xX%*40fBbhNt(WGVnUU*-X0%_ZJQnhI04i`U)8-&xY7PR&^SmS`$gT&W2}6EcAHr zz;m;rE$Kx*I7uQKoFswka+ZYB+^E=q$oJ#AIZ>j3{8o2Z>KQ=ZoG3Bq-iH-%hfkTa zarAlPCLmgpl~Sd=iZkW0=U`*{!SGPaAn+Cd3SYo;IF7h@!z*2d%}6Ma9r2Z)Gx*dv zR+z>TEW+OhHG)iB1g^!dU=gM{aKGo>4BYRZQECTBnh0zQl>?OxDVS?w+TVt{L6^?S zb)2_>kQ`YYa@t2fMeW;|xRYnF7gKgLTlzW72&+GCUpF)r2o?_6<<N{$o7w<2nzk;k zLs*Gix2%p+US5Zpj1>sQodGhMI-=+>40vM?k_KsT22OW4!qXVZn|o7}lM|DZ$4;I& zh6PZ))1*}#6thx=GE8DSV#jDbRv`QiFn^s7L&ZDkVc2d<AAZ^%or=-{2s&Bk=yr!? z44BE-Gbo_*r}s!i+AS&RI7Cb518&G?z=p>5_maVq81!;3ws7`vN7{m$J~u8@d{3gJ zFO1udFh}0d=Mt>w?@8u3?aj(|8u?cG;&q0?MjM2i=gbV~qED6d`!VNLRFAEqS4oQJ zk#Ovp3@zTsxrd<DIe-(%sZ0n8GF;afy$BPKu@|r=T`X5h*kiLO7xLB#b_O}^o@N8t z(awaml~vL6znhKbJ8^)@aJX^mc7%T0rYW-mD)eAxtpY>*Y?x!yBgKuIyKjCw9VGy# z3x^e|T5o@2rH<mW-CbjMq8r~K+yVQXXEY6H^0A2H&>-`eaV_W!H_`5Y%mS^iu`>)b zFe|2-2;@lRh%tg5^@MQG;GbW~fy;x77=<wz<aFcn0UU$z{5IX`4MEfPmN>$mPO-N; zkbs{ZyajHSVMWAbKBc3jDu!0Gu4R;r02~lb`2QKnrwpt!iN<IQ)_T{tgP4R9)zdiO z$|sY9vDF35(AL7QGI@F9AL5OF$GkCtozc#3wB02iWv9h<{D7s6nijoPoO*U8rFNSc ze^Q#VrMM~^%BCe7?A6M~(WluKVow5kfX02X)~KD_&W-6XNB?PnTakT1gR-I{wPs## zjwPC{F1jii`?INu;}i1Q4z_101+wA5^2|WZ3|Wi_b8GG&g$8d|3|zJ?n}8Ul{$%4b zT_6_PHx5mLj)bfu9mCYdf65r4nv8PfE}OE)j*CnYEUzH;f?M0e+u21;D7%1)`;q@R z1gbqTP=%Vc31F!u;D@>Zt9{$~>w;MXWkYou^PQ=wsqs+71}a<aCiPvghr6@?+=3+6 zM%c|J^`_zRBVFJTnQm{UMN?206{up<G<6aOa<!w%uvj#Sa_KHm;Xd{+hoG`MhA4q$ z)P@0B$sZ|+i5sPAi=4Dp?T&NehPKH0&W`dFMUeNfF<e+wO!eGD5>vgukj2h-e<3eo z$|7#tKN5-4_|&c-31ld&zKMmjj;0QkC?zQDfvafhT5{q(_?15Fg3Io=NJjn0V;5ZV z1>}wNG=RL3o(A1*pdQ=(b9kXur?DAmy5jAqT~@+QJ+;J$Vv|%rDl1KhG(A{3=wpy5 z!t3lx4&QxTH06mrN`Kmvrm|9mpnloa;MrT3afmHgi``%;_*?}~s~S)%_C4Ip4^c#7 zy}efkki!Q#7%UeD<sCTOR>UdQo|Jt<`_p}_zgs<{J?e}v*(pB<D)a=pY|cv+)?3(d zj;Jut>hN`8%zu&BID}&J-RhC8;6SzRzs_4<V)7m&SXrqg@lP{(jtL<hW6ghyNHc=# z32jb`umBPsppYEG!RZVNpbWu>n8zKp@Slf(=P#8Oz0Rz<m0fqCV#d_DBkVfmN?3ox zHN*tL?oq)`GfIUJbn;Vpt_y)?*wa5}t7Y-0=pc)KxJ6K8hJ<PMn(Ep!_|zUpQkNLm zwEN`&$NsJ+Hf0eIZ7<J%Sudc8D%t>kY18RPw89qBh7JeFm~}leqf{{E!>Crpk!&Dm zAb$w?)_`7bir%%g(sFzZ-hm=-us4IqB+wgfYB1XUU`B~V;eJJe-AB4b%~-Ts(xqK> zc4@EeQeqX+(M<QM)9kSB;!_)S@hECnk=+FY+qzgVUBp>UZAv&k{Fm$@(V9KvA#v;> zw$;<^eUxa9WFGm)Z}wA$j<|%@3ntAapj$^z7`tvx3?~?dUhs#(qLd<58vEV&*#(n+ z9=DPZag~(U0kiKGI6N$b(lkrvEF00~g&)AJtbJjsF~lV!7~t}1WCgX8h%`MuiDFZz z29*0*6bnGmr3t@=LU}epW)D<ujlI!EP<9L)XWyg-y^gnbY0$sKtu2uT3C9&cMH-|n zMc$<5e5reLejT^AN1Ahg2l$xHfetIXtmmXrp(yJ_G&#&fMO6PBe-ambjz-ARj;J0d z5a)31H#mK^Ba=(z_QIMCCT_WOHU)b(oSUK+Q{1$FtmZU6HPWA8U0+Ch8LZ<uS=o8c zZm-pj!j=u|G8_c)K*__b6HUH4(ZniLl=)Yn*sPgtQ3A-=0Xy$7%sO<On!mD#de>&1 z4{CS1n#eYMQd=npIy?lkKv1Zctm<M6gHPX6!?>%cA9G6Q6?!ZbEn>_JP^_#v7j=p{ zIHLm`Yl}7+duHO~B+f^j9AjXx;3<uev9iW`NxmZ?ImWDS*Q_&nT=AV3totSqE?|M0 zfPX;C!Sq1iOWPn}haMrbA`FZ&C<6=gYVt#5T*!3fMH|fW{a}WElMD|`I>`KdNU=V* z(iOUJ=5D1G)1#RoRTuQWK}~hCKVY?PWtthu!?y8sqDg1bU&EsLv-Lsfj}uC3T-lD= zLZwvuq%DeR>cRcQouMY;<$*2J?MLevW}pWqBwxiHFlIsPP#OUR!tH6MJ_%N--ecMo zw25!y@hoyb)T(Y}i-Z8q<+_q{;plpm_1?s<t$^P!+YFueFb3qjQh>?9+T26Ep?1AA zGPZ}q`Nmb_&Icbh(+D;q20_)g)gMc!mkn-)ZRnzB3_Fgl1lW93%>>|SybNtap$WI~ zJE#>Gd7Qy|Xk)-RJLbGlUMa(m5<2^CZJCJIY`ZXVG%`=x+Yl;=Sr>bOY9OK)nBX7M zLNHhGlYoI_ouLUBRfMkih%kgrg(Y>6BYwxK!g*KM5q-odY0oa%Jik#!@971Mts87d z=tw18g-}jPz@-S0_d>#>8X{=vskcx&@H`R`k-(hN5*TH<ew4stfs!`Nlmlv&abC<q z-!X<9;26b!W#ur#;<HQAE?3!oXc|N>N8E+F7JJJ$>Yfdab+l5g9BFtyU?#CFl)0vi zg5UwSOpcxym5nPNFKjpaRn@V|A}^AoIV05qy8;~4H6K>ZYEwv?y)hN~pYQ@~X|u4r ztlFzaM2^ae^*+`p0}J+q?#fF%5n7(ca{^@gV8f!n1b<S#1tUm+(hRz7B(b)9{d-dL z@c@^hJt=c9v?mqo$ELQVEORtc)|*nnm0<2{v@O-Se4q|_vp1%~#0)^-z{EDVI5W&3 zsx2<D<{+C80}=2;I1VjzL@8ygR$B2a%FGdeVCA5X*N~quj0({J)?2Z+z}Ing8Hb36 zkYip%cCr0vY==20#DgFP8>3u^1w2mJdl}2QlHG&tHIeK^K%hjTcF-4@d!300Ej)NM zB+ZKj9R+!{)BelMeGv&_RtIwZ6TJHGnTYzRo0va}1x;k%#DPMZLOrZWQWW$H$$Xlz z{}=;s7*_|e6AwER?8<G2aF9=Blf(Eht~Gw)nPI(Cr!l#+_@735&fp^!C|FuyPDV56 ztJ&%v{7RW$g+%os{7%bGK&tUefmRSBqDPm518NX<<@+}AI}0I3V*o+b#%89$CnD_I zICe*6jLA(ax0*jhu8aKhN4WJ7jt)MsJLjpUN}*vOjGZ&Jn}M_aE`Ud$MzOd}hv3z} z;Eh0?$cjV41jj`A)Ua85_(m#4a{WBKDgRz!{fUqEkEnYZpW3I87%9Soy#cHvGWdqQ z8Z0cJC&YIa-;l(i6@=y5?Icogj!01kDV{*uD``$r@RGQam$YBff}{hI4obR3(xKbQ zOM?qJl*Vt-H*Uo@4txTiwhe9pqy#W1R(q9=!HJoZSbp?C%ryEDUzUS{VL8$0pPZB% z_%R(Du|}U1l4ALZAU`m1d~$4JMvd!aqo8B~RyTPPFB8dNd~D+QI3fd^yO0(T6GYve zm^q=IoxuxFo*0|ZKaVxG@aM6KF(QsCKRG^yvJ(?X`F#K6v}wn5V>q;=a(Tt#)#%l? z=SK^1oDjszk(%@}>0y##l4g=*A{djEYZ%@To<P*ZaoV`?gG3Q(1|f8+e;^dy{^irT zlspwdA?g@T<5T-FBnE}tB$UgkcE>6=i(&2~nglLX-T+;!M5R24Je19n--0|`t|UK% zJY26NzZLoWMcGUw#hGC4cBrnm=>t9KNVU`5B_-)dwcFhz`JL_%kZG?u;&>)-rkaUz z`4_N6-PM`OJR{x$U!OBo5zq>pspNq3){elVYVPqfPn<nhy0{2##wyVXYJP<5K8=iZ zTsm!Sd6namI+0kcRT;7eZc2aalq7t)_JT4@i1BF(nAx$2Q&LtL#RV(;XE<z+GWk&? z+Rk0A%_N~}p%*eNiA*#a(tU{&P1L{I>xjn+2mVGgUHpysL>?a*@qd@%h<EZga?_CY z#pejtUN8Zq)tB-hLa0B;^9=d~`!9qFgspMb|9Sc$HB)youO@Ee@RnOWuv?yljyM6k z<sX0_5=e&lA@w$4T^8~~%DK5)*^gw69};T7P7$Q~{9|weISoAlk88JAgDco#aSI4E z*sI&v3th#(a|fEZx(hwx8$#{O-OAlOUC+4%RhnhwpsYi;`ViWxZ+D{h)h1eUwGT4A z;||iQEqJ=wcPn@8tB8qjO8n2w+^xKRZw@Cqptf86fW(&FiBBeLm1f>8oJictH}j~i z;tr{rtfibl4COxEg#94O^*8%b?$hqpSUDcWlyCO$WN5}hv)~r4CO(<+r`=&)P9R|V z%F(D?(QU#V(Q5pKyDcaiKwY;qRm*p2TdMX@yfv!kTiBhu)sIhMy^eI?=HYr@6RR=8 zIXZwO2<^KPw+5Qf0Kpni;QDIvSzP&K>e>^4AMQ5`+Y>Bva~x0h_b0GA!&c|6PruBk zWzV7iY93Jdlg(q4n*)*F-uNqZIJ$@cGu8nt>d_YB%-WSQ%4aMvS2Qkchy<c;g`Vzg zwjd^op~p0*de6cW#dh(h1CJXs>6<ZzqM^ogbzu8ya@PMpK?oWS+<*}L2!25D%MnX+ z1TWJze`4<^Cicp}I&f!eqz>Hl@5A%uuR(+m5vTEhaVSDXi&ez*Yx5?Omx<32gRC5! zojn+LO;U2w_%mL~rPtv>l#o!J*1?HN47QTexKto*Y)oA6wZ3N4j~un0dr<sHqtI@# zuhU=<rAX)<htJ-GlN1zN?SNuY#s&{cgTFcn@F+9?XPFb`X_>hTOsYuWN&3{;7cZQ> zP(1VOd*?5xV+MO9rVMVOn{W!mfwpj(QeJ_B$}8n3`22t6^Z6oT$g?2)1Adqna*QED zH$VSB>ieae>V7L<yDFYUIMB|2yOfpZikHhc!<{w2vZFPiaxA*)xgGsqK8t7n4OgF! zBcnX4@@aKkG%T>ONjD5>WIv?8;U3C=jQy3%WRknEg{LAF<}!Ja7a1E2kqkvfG&v<@ z?&_h}0;NlJS9xmD+B=0OQ6Fk!1bTk6obkZHswZ9S?BvJ=lpk69C|Og;#KFekYHHZ? z#AcbcXVy-Q)PPT8B^2*ldyh_yu$l&4=_x%7j@LRSYU-lK3yQT)ZnL48*-m8ClW&rL zqHYEibJjXK^!84wny?lGWQMwxa%B}*-R7W(%1xY5`Y6VfAoN%~hrfu+;@ib9kq>tE zNfguLz$bBf1D`~pJEJ`?g2&`3K5_oZ^A}!F{(_HTPy<~Eb~pb%F0}FiU}ciT<(6TL z;wiYCsdM&*u$!)(1dS60&<fMS&PB^U_n~&nK66sKFr0^nEQHrvI1m0-&&{W4V<JoB zDIDLEMbzV7_{ygI=fLD-aCRj&KqTJgsb&^iCOvZ6<%`W8c+A3=_SzoS!Md*P!4e2z z83_3rmR81CM#N;Y=sbYXe;Fv*b18}X<Qq(Us+s%V6k-IRHMsv8?@BCZq(Izk>C1w+ zD_~x0HAZNVpw=X*3REUc0~K&*;JegTOkp?9>A*hUa%s`{_e&gCtR%1luH)bkxQJTR zs6p3`6O|;i*8cJRMy*ZnD5d7zzh7yRp+yDZ7bj~yiO{}4&ql1gh|oxt3X8$B2*jJ$ zJcNrw`<c~KueP>$8NYEK0n^m$LA-5)7NH<w75iuRkJ0aMM0b4@&4Df-T7Gv8&1Hpj z-x3hG=6nLY%2vb@P$<k8<x^;ub(`bZ(wws(x3FYIx)I!kFmDaj*O|45*A#j{1&GIB zC;Y!)@*t8HBj@#b@OhS#cxApoLnKqBSHHit<02yT72PV-W}d9&AWK*yTHD*MWA~)B zwY}h$@FkY%Df1}RR#v^CLq!<D*vy2bu>pc!25T>Jo{pgxiLF=;<exrx1PcR9*bsh! z-wZm5t!^wJJZv?e(qR+dhnXC&ao$d6t__s0_+48-f@zh6iO;aH*wAMja$R`H95l<b zymlnMU)i9;?hPKC8CSf9lv6N_g|xH`($IGYr)`OwaK3aHqhdUT5ktJ)RTzLOeUtr! z=k(lBd}_D>c0WJlAc0M(HW!k+tt%IR;~^z29Leb#EiR`3f;#F1(-?D;arnY?2$7@1 zvy3WU8z>v6>x@rL-n51ukZZ+wYa2)MVI<-Qx)0<LGAV86IkGzw-;3R2Xd59dDxc8N zw6L|?@qk)mlFIo!;t$&590`0@L?G|S6aPIilP`u(=uzcW2W(T5yNeUDbq!UXp(prW zc{#(mAYjC6ydcb?%bcukTXD-L-{JokT+>UO;?wr=Dv=jT<Acmg+i2kP3ASwrnZ%$9 z6wMj3hjw`?@D}GqdrK`ixyIRv@q_rm2~khNSYQW4L+IkM;h(JRldE(nQ-|b2rHiXM zmS7Ik0Kz}roxx}U<a)}$$qZAbmtOQx|B4?yR1d5l6G@C0UZxT0oj&DYb|tTDn9LQd zW_^vH1}CpJX;ds-hA#`_N{Aq~Q)DGgbrkJ7ptnR=j>R{L&Kd|$XiN7Nbi!3|(+R=V zy~qfzZdX1Yz|(}nQ;nfXg&;D@5wuhz&g*K}iITq%Ldg>rCDFj;s_PX6R`B(9$uq0b z4|#rc!%Z}wC(ZkUqS_Pe4Bslgwz7lqB!7N@$!D1e#=guPF;+IMj3*d*CWX6{X4-N0 z6S(>sJFx?q1RR@5(F@QkQ*_t^K>%lt>rhR=;0-!vQJE9evTURblmT2&12;t%XSh6r z&4P(17%A=QoE2B+-g|a+?!*t=gRAq@v6C~1Bph~iR$k5md4DhG_kTe98+~Kt)tRx9 zzghw@_<mez^(v;!QxrlwJr5YyWybnwGq<D%?iUDX!Y1tV46vF9-z1-B|F7_dFB!}X zJe_C8-h5Bz-w3@%dpggIX;0_T<mP;xXF|Tt{t&_b|DXf@9_ALA`*S8g#pEkY1m`JI zC@M|zt9+md<IQ+E58&B<28vL72oGp4XCOY<8tkyb-+8!DF6=3c!x(mVZkPBu^9eS^ z{*erv#;5kvNZPkh+{`z_&lx_?_qjV{vt$eMW)o!yd9#VK75V$!y;5e_eH)1RKGB75 z$}ifgy8^#x|F6+s%g+&)`5}4wR{KL|KzKUZhFLNZ-8G`*)xK8g1u0mpzKL$rGjqmv zGC1c<{HCoS#5VJfORp(BjeXVe<1;hU6JYP)Pd$0!*v!fCsgozBPad0?IW~1-a^~2~ zcwi!_YS@fDi+zQ*X0g9R=df*H%+k5|J*#73GNcEklRj483h^KF!dOahu(#U9+W&un z_x|57Aw5tD**Mwm|9z6iJ@}Ov-q5?+z^Sv%2A5NrUffeMViKnDy?R%_3y%w@+r{1i zI_AWGv&3AvR@;`{qigkd^Z^3OH&Hg{yMT($Uw>^u)z_fcrUezuLOOeGl1>s!?(R|j zof(!r!T_?PQ|v6+%FQ`ce*q;U0GEmMpK)~v1~DS{!J+z44A#aqF~nD!m{nlb5N#u2 zd~!`m<38BkrTX9EoxSFraH*!le0Y3KO}58)OTy060)AMZYUOA8?H4ItBROqRA}|*+ zCV;0)<FExnPN@d;nllC@58Nm>3x?8%@wUL0ETW|_AQkU}8V+=8i<v)<h*wJ2NF`oS z#4Zjs5GiQ)ppL)jc?h}2urDgmJkB9zZ0)HN$4>@EiSI>RUUb6*pf@LGh*myo=BCYq zRsGPMtX0ZTv?AIy^qY2N*6R>8y+MF#{o?6~li_gGT~v&BJ0Zn_$a=~io8U<($Hrzt ztDkWq9xf6@oA8%y@w5PzRi_2)wL@NL8}gu3WXLy9*uH&3MQj-M-}aVs{Oh1>Wjq#{ zWtOr{8EETJ5n(E`QK*Q3u=(lO6gDrCchJ7^ka>p=4$<Kqwu2;O{G7o@%n&KN>*ELB zax>6+=aYdLz%q>ccFK{F-Q2Ma8yzqp{@lkxFrwFL7)Bd~tRPRO)Eig1U72cp$DAo3 z`cU8sb)N=hg!l(5Knu4{hX6zWzc66#8gZcwI^TIm2gr8L#$ftmfazT!FvYorj!_s0 zWtn6SG75uWkd=ZH*Dy~~$G#(#W|`B_>jJNO8lP8-hU}GL7^dMuLF)mt_=OgLj;jk~ zsQ4ZlwfhKG6|c!0`_1x^nbzs8IuMdGF9-VI37>}sg&N~i;V$+o^ULh=*FO5SkER(V zP*m<T*XWFUt$s1GP@Q}qfeUSoSYc;yh)M(xX^f%DMW~q7N=)Oq?f?eRdkAC&@Gbh+ z5+`%E@y8b=q&t>;59g)2)HuUw$iwOF=bsDjn{))ZeU^a7xwkkt4N=V&;kr<%kFo+P z76fqG5I}Pf5um$OPnjTLuuIs)sqz%rl4*s0!Wl8eWCKz5dLy-nHenXF$)N~mZ+sYV z!NQbu=KWpB-rMkG6&w~hGWbAo%+tPLA<uwZmPY78Tu}JOZz91Nd_?nh_hFG?_}w_} z&(y2a!H{Sugs`sjcwiU=hxzmoJD>)J7zA!WV{l^Q5`m;CZ2-<msK$l+@g;DICFgFf zdt(*-FQ*)w8uG?-$le>|`)cKz_39GNH}+%GBC>ATQuA<o;S`8_CLHIr&olWP6H5Pb zP)O)3kRuqdjt7E_@y0llDJC4#P$G;6&24{&BJw_Dblj5zI_^onFes5v82x0Rutn67 zizsIQSm9}WYA+)RbgOS={1e1NG0`KpAaAs)L+(zX;4c43G{h=B**tdg3_i6#MFOo1 z2*`JET$CWHN)RE%##h;7Tof^|7K9>P6oLOm<`$W(Gl}_8z0PZ2VzTL|C@&M|NAO4} zDhl17pu9&^6zo>ns3<xwQBh{BS6ycnn_VkN2;%`A-h`+q|A4LLOBiKCoQNVV!p7h? zB`S)H&^yqI4MK+a`RI(6$;@YdjC~Mec=RC_3nkK<Z$T^+>DbY`bgaKa$N0?W*fH6- zN4MHSphUX%O%8$bdA5uqXF`QQiL~WjL!bzZHemL-nfyijLKOlf^ulje2$Wx86J)BG z5GbKW&;<CK9RlUoA`KD|D4-_NAnljZnfs*rGfq)93=u<m*qJBxe;v1eE7BZ>K#9Z0 zMA(S5hgd|iTpLEB*siOo>JV~><%tz8r9xjpV=9cf&~1u;U0T9hzZ*gphN=m*0}7?P z%7)z=@*v+EZU_aeE)C(W-w!oJ?3aS^p_)>kNjE>bHO>dgV)b=KgdqgFpN>X$;bUwT z7Zex*?TW{S0VkAEOa%(qzcg~E@u^KB3HTlzA0}_&!|2FwJn>9oztR8F?ZYVc`yAua zbx^v^#fdRSaU4Dq;lc<u8wQ7&83}Cx!c`L9wT!BAm)I~yFo-`Kj^AR?R|2>M56sRk zg-dmg4HFa(_D|8c$dh`u#;RY!-|StJ@o*C$Ei9F9!t8R^LEpa(0>{AmD;An18cN0l zX!-wT;FzyqP3dABp#8bu3gduaR#B*oYgD+6F9z8Pm5yrE47MoLPJL*mVV0eUhg}J7 zV;YXnc1t#XbT(e=W}?l^j5+a;E)ikb2?cnevG=`%bct0I3h)9DghYJ>qPcG%F35}? z|1eSNZggP^zlBB@<`u^1!u$>fdUhkDi;l$uqYDCzmWYdWnz-maCyC2K_4{EM`PbGE zX-JIvZ*V*9I-LQqpQhsd$Hrw2fp4%CR*44gKrNRJI}sWz3xps$)%m4Lte)VUCD<f8 zaxxAhfwWb`WhONGolK#D3((`#!k#wJej3G12ai5|D?04}#Wx`qinTn7Rvv4c8V=_M zHV!ukhQix#X*3kNYpD|lL{|82{`?A)MJBH^=_JLA$@H5P4dpB3nI6ZR5{`|AB4JN; z#1j$fBhgS&8%9GhbGu#ar-;E1`&K)R#8}qwkS(yq2#|3rb@O4msnLubUOq_0m39c8 zLkUE_MG!Oz4nKm!9?3$d8?QZy!?JL~6ZDMGe3t4U`Bf-=5z43p7Y~U@Bf$qOdWSHX zloSei{9i6#^_*f68?w*}z)y71TZMaA9g(M$D%cnM=-6WN!rDd5!6VPZK@u-S82Lqd zn_A4avrV=$7?JZebXf&M@tHfwgmFrY*|10ezr?FwV3M|pC<MNUpEGdHQo7$>DqV1f z&sMULn*2zhzgk2F0avPI5DMFrL9QgLP%<IzEVnq4e`_6}*0PSuYfGsQD-sdiG9cQ7 zcSx1BLr3d?v>J3#?Q-P1$W^@mI0sln@d8e+7s<*DZp30h!r$cM!qqG)S3wto@Ha#o zrEZq@2S_D3!K^bV@&}{>+&e@J9Gp3ne>PVT!DbPc>>rWnG(NRoMPg(nM5AGVkysQQ zTtzemq~QoS8%MoCEtm2VJ!gaXH>eRYZ;%d4x=qsUlHMoj4oP=Px=YgClI}t6TO=mW z{b+5@-3$DGn~Iq;6U5BvTk=kf&(0!lQ6sms1lDdAv2uE6XD7(YHL|>e?*T|g6kfpj z9X&bI$U)x0otf!IpWgMEoI=Q&@$re-NnD@C1Hrn?Xf*}-Il+feTW)Dlo<H8m-~wK! zszV0FaOHTTcUrxm(R)HN$K;i~H{HnL9&=NT+>Fhkn7%e=b7ySstjgipb1H}W&Z(Nw znRB>}`c5_gi$&%p#^>83EfHsYiK-(3b<$Myy@Lt;ze1!dz_MxFc%JBe2#-n-oem*% z@);^RgMaz7&*v~>9>i0O`E<f3mcv85xU^OW*HkR}DYoSSCcV6cL!`7VJnjk2CEm6& z^x|yw%_DN-S>LbvtzOs^Ey80&Ts&H7a0KeGA1Yksu%A|5&Xm2lUiWJ1;GYI>y^Xc? zLKj%7;}M6KNXl`ZtsETgkMPP@nH(Z4WUW5QpYLQc$K))Nr<gp=M9f5GIbYz<?_zR= z$#o{*!{p;kzK_X=nY_&8$C-%x{W<0yXTo4bVtnThFehBale{4VMp$+loL26U75IfN zd#5l!iP|ejV3D83X+$`IEDNVYgy4oxdkVT*?m5ymkwK19Sc4Fqr7yPy!O+vWY(6(M z3g^Z2P-ZBTdno@<?!nyl+z`&CXL>w0k(<fw9{Olv-_WB-`R_%19~!<s^un+|<Yd!w T_3gtSO&l9~|L}JYJ@EeliXAyc literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/pyparsing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1d0782994e6628a59890cc83fd67a39c44bafbc GIT binary patch literal 203012 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%0DD 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/retrying.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/retrying.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1e33738cbdd97c52f6967f580a190b324b101555 GIT binary patch literal 8046 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3e612ea97b09e735f026f6a89ceb7d4697a24c45 GIT binary patch literal 24951 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 KZz!3bq5lVumZfn3 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/appdirs.py b/env/lib/python3.7/site-packages/pip/_vendor/appdirs.py new file mode 100644 index 0000000..2bd3911 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/appdirs.py @@ -0,0 +1,604 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2005-2010 ActiveState Software Inc. +# Copyright (c) 2013 Eddy Petrișor + +"""Utilities for determining application-specific dirs. + +See <http://github.com/ActiveState/appdirs> for details and usage. +""" +# Dev Notes: +# - MSDN on where to store app data files: +# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 +# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html +# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + +__version_info__ = (1, 4, 3) +__version__ = '.'.join(map(str, __version_info__)) + + +import sys +import os + +PY3 = sys.version_info[0] == 3 + +if PY3: + unicode = str + +if sys.platform.startswith('java'): + import platform + os_name = platform.java_ver()[3][0] + if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. + system = 'win32' + elif os_name.startswith('Mac'): # "Mac OS X", etc. + system = 'darwin' + else: # "Linux", "SunOS", "FreeBSD", etc. + # Setting this to "linux2" is not ideal, but only Windows or Mac + # are actually checked for and the rest of the module expects + # *sys.platform* style strings. + system = 'linux2' +else: + system = sys.platform + + + +def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user data directories are: + Mac OS X: ~/Library/Application Support/<AppName> + Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName> + Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName> + Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> + Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/<AppName>". + """ + if system == "win32": + if appauthor is None: + appauthor = appname + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(_get_win_folder(const)) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('~/Library/Application Support/') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of data dirs should be + returned. By default, the first item from XDG_DATA_DIRS is + returned, or '/usr/local/share/<AppName>', + if XDG_DATA_DIRS is not set + + Typical site data directories are: + Mac OS X: /Library/Application Support/<AppName> + Unix: /usr/local/share/<AppName> or /usr/share/<AppName> + Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. + + For Unix, this is using the $XDG_DATA_DIRS[0] default. + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname) + else: + # XDG default for $XDG_DATA_DIRS + # only first, if multipath is False + path = os.getenv('XDG_DATA_DIRS', + os.pathsep.join(['/usr/local/share', '/usr/share'])) + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + if appname and version: + path = os.path.join(path, version) + return path + + +def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user config directories are: + Mac OS X: same as user_data_dir + Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of config dirs should be + returned. By default, the first item from XDG_CONFIG_DIRS is + returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set + + Typical site config directories are: + Mac OS X: same as site_data_dir + Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in + $XDG_CONFIG_DIRS + Win *: same as site_data_dir + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + + For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system in ["win32", "darwin"]: + path = site_data_dir(appname, appauthor) + if appname and version: + path = os.path.join(path, version) + else: + # XDG default for $XDG_CONFIG_DIRS + # only first, if multipath is False + path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + +def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Cache" to the base app data dir for Windows. See + discussion below. + + Typical user cache directories are: + Mac OS X: ~/Library/Caches/<AppName> + Unix: ~/.cache/<AppName> (XDG default) + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go in + the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming + app data dir (the default returned by `user_data_dir` above). Apps typically + put cache data somewhere *under* the given dir here. Some examples: + ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache + ...\Acme\SuperApp\Cache\1.0 + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + This can be disabled with the `opinion=False` option. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + if opinion: + path = os.path.join(path, "Cache") + elif system == 'darwin': + path = os.path.expanduser('~/Library/Caches') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user state directories are: + Mac OS X: same as user_data_dir + Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> + to extend the XDG spec and support $XDG_STATE_HOME. + + That means, by default "~/.local/state/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific log dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Logs" to the base app data dir for Windows, and "log" to the + base cache dir for Unix. See discussion below. + + Typical user log directories are: + Mac OS X: ~/Library/Logs/<AppName> + Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs + + On Windows the only suggestion in the MSDN docs is that local settings + go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in + examples of what some windows apps use for a logs dir.) + + OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` + value for Windows and appends "log" to the user cache dir for Unix. + This can be disabled with the `opinion=False` option. + """ + if system == "darwin": + path = os.path.join( + os.path.expanduser('~/Library/Logs'), + appname) + elif system == "win32": + path = user_data_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "Logs") + else: + path = user_cache_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "log") + if appname and version: + path = os.path.join(path, version) + return path + + +class AppDirs(object): + """Convenience wrapper for getting application dirs.""" + def __init__(self, appname=None, appauthor=None, version=None, + roaming=False, multipath=False): + self.appname = appname + self.appauthor = appauthor + self.version = version + self.roaming = roaming + self.multipath = multipath + + @property + def user_data_dir(self): + return user_data_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_data_dir(self): + return site_data_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_config_dir(self): + return user_config_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_config_dir(self): + return site_config_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_cache_dir(self): + return user_cache_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_state_dir(self): + return user_state_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_log_dir(self): + return user_log_dir(self.appname, self.appauthor, + version=self.version) + + +#---- internal support stuff + +def _get_win_folder_from_registry(csidl_name): + """This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + if PY3: + import winreg as _winreg + else: + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + dir, type = _winreg.QueryValueEx(key, shell_folder_name) + return dir + + +def _get_win_folder_with_pywin32(csidl_name): + from win32com.shell import shellcon, shell + dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) + # Try to make this a unicode path because SHGetFolderPath does + # not return unicode strings when there is unicode data in the + # path. + try: + dir = unicode(dir) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + try: + import win32api + dir = win32api.GetShortPathName(dir) + except ImportError: + pass + except UnicodeError: + pass + return dir + + +def _get_win_folder_with_ctypes(csidl_name): + import ctypes + + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + +def _get_win_folder_with_jna(csidl_name): + import array + from com.sun import jna + from com.sun.jna.platform import win32 + + buf_size = win32.WinDef.MAX_PATH * 2 + buf = array.zeros('c', buf_size) + shell = win32.Shell32.INSTANCE + shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf = array.zeros('c', buf_size) + kernel = win32.Kernel32.INSTANCE + if kernel.GetShortPathName(dir, buf, buf_size): + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + return dir + +if system == "win32": + try: + from ctypes import windll + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + try: + import com.sun.jna + _get_win_folder = _get_win_folder_with_jna + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +#---- self test code + +if __name__ == "__main__": + appname = "MyApp" + appauthor = "MyCompany" + + props = ("user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "site_data_dir", + "site_config_dir") + + print("-- app dirs %s --" % __version__) + + print("-- app dirs (with optional 'version')") + dirs = AppDirs(appname, appauthor, version="1.0") + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'version')") + dirs = AppDirs(appname, appauthor) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'appauthor')") + dirs = AppDirs(appname) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = AppDirs(appname, appauthor=False) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py new file mode 100644 index 0000000..8fdee66 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__init__.py @@ -0,0 +1,11 @@ +"""CacheControl import Interface. + +Make it easy to import from cachecontrol without long namespaces. +""" +__author__ = "Eric Larson" +__email__ = "eric@ionrock.org" +__version__ = "0.12.5" + +from .wrapper import CacheControl +from .adapter import CacheControlAdapter +from .controller import CacheController diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3314c278db7f97277c8f25da7cb355fcd0907231 GIT binary patch literal 506 zcmYjN%}N6?5YD#SZo5_#e1V*V9=fZd;6bEXJP7K=+aiRxNozEJ&ZZXoGM;^<y?XK$ zJULq}biz!&Z^(Qznal0%l%N$K`wv+}$X7$w)<Q5wuTC)tQV<apk!Tey(JtB|79Aa% zPSJ@7;;!zRq)1jc(LK{I`iOh?WY}LmPI&nwC(Z_NnkwTR1bS_Qgefm&mZrD-MN$>0 z<kdS3ZvA8m&d{={E&pp5Dm=M)pxW6PwcN<cqe7LX%dIO=CB5NLIlJ7INXE)paOF$p zV7BZYWQRxD$v1wH45NCmIT7-`O@1M`$JsEwvzgWs?uKcdFeY5dSe-J)=Qs`^?lUG0 zR~q3KV{Z~FY>p&Z0QX)3G^?x={-+G>hNb_XLS2Y4@kwBS*DCy6=E3;fD?d`U3S8?^ wxtQ7K@Os=NSB`D0aFA~<C}&Jr6&TC>d)+%TPRzADZ`7+sJC0VTHHZe$FU1Cz!vFvP literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/_cmd.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..210cb1200729e100cf426d19b1ad1ce43a7b401b GIT binary patch literal 1509 zcmZ`(%Z}SN6y-w?T9!Rd8Wd?!r0xSnyvTTyRS*o4Op0a^7)58Y5ef)`N!W7r3PmT4 z;jAXxd_z3T{t~xc^%uJ8y_9Ae1PB3AhnEy}&$)+sG8#n$TJqti-;aDk{>I5w;{YB( zZ~ufr5=je^;FA@!WC^2)dBICB@f`LFzYLPVVZR7VkqC!_Vo*j&1UQu99Z80AAR~Cj zawubXj^sp+<oF#;#_C8O{lT<R;|l`&=^2^b_y@jD7BgyvRxh`zH7(#TPP64&oz|7n zb@5ncjZqrHgQxk@xFwhbMZH?N@c6M_ZA(>|Uo+h*y~Go-QRv9>6ngtT42B%2VH<u) zDKYHeU6QvL^Y;WJl0ZImF$*+EMXYF*d9Gfm!iM;zyjofR>CaDI{9;FEMysrRmQ}J) z+D4g_J%+Txbr=4N=n)+A@5$Vh&AiE*dwJEGtSIg+U$3f-d3hg$uBWe5C2KujBI#vE zdY&#zdEC6QBS>T0q<so8QVC!nG^T>;BS6=D8BB1^@jU@xh@lstGgK1l`rZS!?7)FF z-P407Iq-%$JM8tCZ2Ub<gFV*9U!2dl9lEqqWwKRkBhWX`ihKvW2Wz#}d290JE?gVa zJebdS0znIC7HX7UdpKZXHat^po7a`~%X(WG8}&?4!b$gy|06SI!>p^j^;&q*iP;Tf zJZ-pACdCCf@g@XXj1tP|gb9!)hEab7k!x|#448})=NkZqTtNBvWJ5t9Ci#1mf*jZ- z+Q3^_zSYI<_W4>(U;OrbYU-)cZ>CV&smm2A?X6YO%(zC$Z44$zv)+d`YS4)|M>hv< zraz@1kOFSG0|)d)4d|HaZ(+W~e6gX5*Lk1Aq{|x%>&nQ00T}u%Gag>5J>B?+V9z!o zbkUU;A_I(EQvJ+Cl3sw>D*=cha<=D-U3iN2li%$|i`sM~<@CYb+0f<V#Izhz)?Y&s z&UpGuKz7{KPOG-5t5(^tzsHvA>~+5?)2pE0=)5vuD-W6L+jxS9?|!O|S7v$jBP_QQ z7zhn$z+)cpn|w?ortjj5B295un&P#cXo0aI+^XaLMmggp(~ly@F4^8^$GyXxQ<FQN z-R9nLPELOK{HE^Sf}8u_2k`6aj{fNMLPK_HUZr1UrApI}xZ^)VJBN#hWi7XbIzcD2 VD79cQ18al1V=e*_iy*os=zpuAd$a%m literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/adapter.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a8a8e56cf3cd44ebe1416c29fc953f8b54c58e1 GIT binary patch literal 2992 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 Yetlv{7C=ADRX{(0K$mqPW9d5o1F0baJOBUy literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/cache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de9a96843d9837153cd6c037e189e01a1403687c GIT binary patch literal 1722 zcma)7OK;Oa5Z<*N$8noBw4w+JkPm=liKdqx5tJ5$Dxrv%1d5O>*Sl%m`qlNOC{a$d z_x=RhBY(+PPW%N<%&hA;jZk5uoqdgWzM1)Ev)yjn1X}<5<1deNLVn_+Y6eWUpy!() z80iy6nHJGl>uZ#}CQN6>8DR$3PxZb5>jpDnZE^$F4c7cXTx+~%e>~t$;0GYny+a;I z=f&GyXOIdfjI)TxJdt6tUuxuC2ela=_`^s#Vea^jJP_PxcJ2?j6DI31k5e&nSQyAK zO?)xx+P?rDacN<^NrR&R7gf_>vIRYV0)mr11t&Cg;*9k55`Nz(VIyE>!M@2_0NgHG z+kVb>5O;vrV8f9@-+`WE*d#e6-{4aCfc5~vYA=<$l~<g-5+W6@Rv0;t28DjaM?Z*Y z!gs%)Z^$^?$ii$rOmgW*(R%Q8KRJ}go4BdEcfu2viVYRIAWfu5qjJ&BMuoo5B_hZb zHac!k(RSe^(BTLhjyE9|m||BK4H$$8qG+7>(U2>YrLb^U&$(>F<S*vn<i7({n$v1? z^L9+eBQAMo##E>FtUL_RA#6BKokK^i5}_`2X=w$+J>y6th|-*|!e-^la(%x#>$%Os z^1Q^4x#tzO=fx=-MmS&eyyKxCl_#Qw7cZb#M1j$n@kW`&&<RWdPI45MX6g7-y8&!W z8>($V&$}R|RJEDL^fL-%1)2gm4Q8??j16Y7mLe+!?kyCpmrxIiti5Z=Kz8ilt!p5V ztrOzW3C)&5oM{zvb%Bb75kUbJ2J@xwmPsmFVG>FYt8K<PMG1(JI`i)0{TO~iEjnJA zBI#BN*AStiLbL>v2{|MefQOMwt*jwUU~W`!uOKK|&KXzd_d&5rV!O6FPk+plGWht) z;Q1Ow!}LO%(1{k(OG?Qn;Lbbpo_wx21U0dOKoCt~4l{@epRE&t#W#-%+2BC0qcMYP zzD}mN@NL3CoZkan6p<a7;z5P*-{|x#&2EYn((@sr!urM>*>v2g<5d<FzF$p&IT6b! zumZ(x6mvYU>#3&rEzr9I{fgqY0Ted`?)F@>XnGz?1E`-?`IN(JU((Gi{|{6xDD9be WPA@O4r)2>?L*^(S47#Xymj3|C{6;+h literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70a17034a431fb1a984593cc930b15bec91afa60 GIT binary patch literal 713 zcmZ`#&1&2*5SC;+>ukK+rKcQn$SJUecnj^Zgit6nmk`oGT2WYBd73&aONyjzyYJ9< z$hl9DTOP!xKp@ap$SLEWY&V6<Xr!6%$1{3681xA)e!27ciV<>KCyy(}%RX**hhZ_w zNlqmxDW{a2615!?V6(n`NlE=RXwagch+-efBEcGyA&-!~)v@`K&1A%*j#+yLa;@y~ z-V^U%OLidR7F|(<a=q;H{u9OZQW46H7VQ)<Bz%CKY+@%v?E9u=!ZSW-89Dnv#?c>~ zm5gcCn_GFV3w4P1<o(IX(J?rqm4iAj-1MuN3aK6B<586$R~BDVlUWBApOI7>2c^;0 zzq3}`Dn`7)s-8G1#7si9W}1_yrZDOBJE&aS)WXFaoOfs>X4x6Iv^9Q(Nc(depgG@K z75z)$FILh2Th4tUZCKlFt_mLQY8W3u6+-7wt$X<Cr+#7ZdYF~a&J{Rse-k@IlP28n zPkd=6Xt!G^=QAmH#g8*}?k`@~#b$T2PDCcYfzZlZEhj>kCiAITRPmcq=W_{r6iwX@ X21ZA8NS_CcCU_2`E@yx1G1eadCi=d& literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/controller.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8341d4593f8b72389e8ae967b844448afe6015db GIT binary patch literal 7592 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 UK&}=Uz~b*}_!BkP9Nn(|9}0g3^8f$< literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/filewrapper.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..608f4c109c42a290d6d077041cf16fb813519efd GIT binary patch literal 2110 zcmZ`)&2Aev5GJ`RX}y+R^)GdTAZ2nWA|SDWqQ|swoH|7>?!g7x3IzyiNm*;Jb~hwt zS%!MD-=p@iue8^qhrB{ho#9HhV{9pK$mI-&-#470_BJ+R0&Vc;SHJ(WM#$gzv1%bq zcA;AiLJ>tXGNA)X$qz&^6<iV(Xm$|{0u>&Te(OD0kv^?DdvmAlk3S{&y=nnWcA?un z5Sk3AA_Jx<?Dd`op$b*&k_=j^tvWEaRixHn?5K~_y6RriL8La+CakQf7*6X|pT3b< zHk8T9+ceX^7+IFu$Wuy4%%L4lK+9+KGMA>9=88)`DtR$H)`{b@ahi<zECnm4HP@%w z%-uN6kGRoN@icb@m)_NIIvQ#7f=lo)8|$3Av2=U{r}EVDBrB{2d+><9^qEekPQy{j z5+1C(G3?RaSyJRq=g#tCRQsvDZ^vHy8aznnOgaP~7GP^$n&K>l0{{;A;6Ov0Y>qfR zf||{8`_E$!NLtIM7WPl{WT=g;5lF6z=@3AB7d9!t`Ew!qJOjSyuQYm;o^cDjtw)m= z4v&>dk}ALqeCFJar7C6+i(8!AH8H$lY&bILZ=l;P5RP1s1rc;XL9zt{87KmGNDum< zLDTA?Xt+!vAU4%jvuadUPntEWxc7r9v^pDA3~Zy->R-fQ!vDL!<0j=!nU*ip+#<D? z$?PaUcJIEyMc>7#&Q)P{5}AxO-kT}19Sr(1tG3H|6$z2%sS~1yY}+6RjcA*mKW-qj zy)sUaG&YPCb|0(HV6q@rP-oZl59TODie4~?6FV?1(Dhl>6XHm_n+y@6>MXzef$4xv z73OlHO$1ZVvli>9S-;sU#OJVJvAoGzOwYe;#=7(@L;^+S8;<DO!~Gs6^X`HilVd36 zljx9y#Icjua7ys^8_C(PWFC2o;70r1U9F;?-do56Wax2Mo3B?Duy0IZs&-vsed-zB zr?m+|wPI9?+UhB|v7dk-l+iBRq;1A%gkyOAteNNC?H^FZ0C}n$CP>3P!25w2y<*qo z8eT$$nGLee=D=VE7~EGy5WZ8HP4)laZr6an2HR!cv}vz%{-_b7=XTJXHZPXouAsm$ zaR45>3Kk6E0o?GKnCCFIuHjA=m`+f3Z6EF`#HX%?+nSlw>FQZ?P2CNV!Q@$`TOcQ{ z3YB#7-o2OyVD&AM^Zzfj3%>|1;(V)#AmV6dw+k*X^f&CNq9@Go1yigZ4^e-g@v9FQ z2M6!5;w*}dc*Q;zR*tl|iGle7)COOyyA;hsTzG^6ncNnXc?_TX(CsD&0{nVG$d)Xh zG_kxr5APtx#{;VssyG&6QmAQ$^R5u@rZQV<Izp%-5yEug41=%CEkYk-591Cr4-yOB x;KPEc=<!8y$f8!%jXsXn<H+ma^{rT1)Gu(m{v+{<CT~^rszwO)yNqNv_z!&t20H)% literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/heuristics.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a24a4318f058fe7c632b26145347913b77350d3 GIT binary patch literal 4630 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/serialize.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c3a4193216f15640a8a717f04a4dcc95290d3fe GIT binary patch literal 4194 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 OKT+Z(v0!<&Xa5_W4Vmr$ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/__pycache__/wrapper.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b5da00dc1d94d139b1cae3b3eebbda9d13a2c073 GIT binary patch literal 614 zcmYjOy>1jS5VpO4zCXB#CQlG)i?9t9LWty2Uqh-B(rH;+xkcVxWBZ6W`6_66hJ=z= za!Zw0pkl_CC^y!8`aCl`{$}=aHX9SL)!o^rJ4VP~ygXR}<O8@p0}w<|MLN2o6gg9@ zOI8W+LS!QUNmr>zK9Z6@P$({Gc(tgTja&@9GlRMiwRX}#cy!e^E~b{(4Tn;+5jgS% zxV;4MRC7mukUjOeo;$kFeeS7eKJlr~d?Dzse9t|(XM%bDn^6*Z^29+%x-7FWX;8#k zy86b3v6ZH+RlAcWj5cy>TI<>-%$tKoCC$1~wYA|SepP=~a@|R{8HC*x8|U=fs@icR z7Fd~>1e6+B8VOl9Y<pLZLTV*6$YKMNVm?F25pbPhRv%Vzc*@|^p?Hk_A?5|#|6NqB z)0J-ZdD~l8D|O!7-t=GG*Ebl9zWyeAF_<bo^f*9uYig~fd9A;P>EdYnD8Zfrkja>G z%8m|aQ#xg44!N>eUN6zg%*@~(Co>adaZs#@`i|fw!~%cU4PvY0d;Iej%b;gQ==1px DEE|*; literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py new file mode 100644 index 0000000..f1e0ad9 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/_cmd.py @@ -0,0 +1,57 @@ +import logging + +from pip._vendor import requests + +from pip._vendor.cachecontrol.adapter import CacheControlAdapter +from pip._vendor.cachecontrol.cache import DictCache +from pip._vendor.cachecontrol.controller import logger + +from argparse import ArgumentParser + + +def setup_logging(): + logger.setLevel(logging.DEBUG) + handler = logging.StreamHandler() + logger.addHandler(handler) + + +def get_session(): + adapter = CacheControlAdapter( + DictCache(), cache_etags=True, serializer=None, heuristic=None + ) + sess = requests.Session() + sess.mount("http://", adapter) + sess.mount("https://", adapter) + + sess.cache_controller = adapter.controller + return sess + + +def get_args(): + parser = ArgumentParser() + parser.add_argument("url", help="The URL to try and cache") + return parser.parse_args() + + +def main(args=None): + args = get_args() + sess = get_session() + + # Make a request to get a response + resp = sess.get(args.url) + + # Turn on logging + setup_logging() + + # try setting the cache + sess.cache_controller.cache_response(resp.request, resp.raw) + + # Now try to get it + if sess.cache_controller.cached_request(resp.request): + print("Cached!") + else: + print("Not cached :(") + + +if __name__ == "__main__": + main() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py new file mode 100644 index 0000000..780eb28 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/adapter.py @@ -0,0 +1,133 @@ +import types +import functools +import zlib + +from pip._vendor.requests.adapters import HTTPAdapter + +from .controller import CacheController +from .cache import DictCache +from .filewrapper import CallbackFileWrapper + + +class CacheControlAdapter(HTTPAdapter): + invalidating_methods = {"PUT", "DELETE"} + + def __init__( + self, + cache=None, + cache_etags=True, + controller_class=None, + serializer=None, + heuristic=None, + cacheable_methods=None, + *args, + **kw + ): + super(CacheControlAdapter, self).__init__(*args, **kw) + self.cache = cache or DictCache() + self.heuristic = heuristic + self.cacheable_methods = cacheable_methods or ("GET",) + + controller_factory = controller_class or CacheController + self.controller = controller_factory( + self.cache, cache_etags=cache_etags, serializer=serializer + ) + + def send(self, request, cacheable_methods=None, **kw): + """ + Send a request. Use the request information to see if it + exists in the cache and cache the response if we need to and can. + """ + cacheable = cacheable_methods or self.cacheable_methods + if request.method in cacheable: + try: + cached_response = self.controller.cached_request(request) + except zlib.error: + cached_response = None + if cached_response: + return self.build_response(request, cached_response, from_cache=True) + + # check for etags and add headers if appropriate + request.headers.update(self.controller.conditional_headers(request)) + + resp = super(CacheControlAdapter, self).send(request, **kw) + + return resp + + def build_response( + self, request, response, from_cache=False, cacheable_methods=None + ): + """ + Build a response by making a request or using the cache. + + This will end up calling send and returning a potentially + cached response + """ + cacheable = cacheable_methods or self.cacheable_methods + if not from_cache and request.method in cacheable: + # Check for any heuristics that might update headers + # before trying to cache. + if self.heuristic: + response = self.heuristic.apply(response) + + # apply any expiration heuristics + if response.status == 304: + # We must have sent an ETag request. This could mean + # that we've been expired already or that we simply + # have an etag. In either case, we want to try and + # update the cache if that is the case. + cached_response = self.controller.update_cached_response( + request, response + ) + + if cached_response is not response: + from_cache = True + + # We are done with the server response, read a + # possible response body (compliant servers will + # not return one, but we cannot be 100% sure) and + # release the connection back to the pool. + response.read(decode_content=False) + response.release_conn() + + response = cached_response + + # We always cache the 301 responses + elif response.status == 301: + self.controller.cache_response(request, response) + else: + # Wrap the response file with a wrapper that will cache the + # response when the stream has been consumed. + response._fp = CallbackFileWrapper( + response._fp, + functools.partial( + self.controller.cache_response, request, response + ), + ) + if response.chunked: + super_update_chunk_length = response._update_chunk_length + + def _update_chunk_length(self): + super_update_chunk_length() + if self.chunk_left == 0: + self._fp._close() + + response._update_chunk_length = types.MethodType( + _update_chunk_length, response + ) + + resp = super(CacheControlAdapter, self).build_response(request, response) + + # See if we should invalidate the cache. + if request.method in self.invalidating_methods and resp.ok: + cache_url = self.controller.cache_url(request.url) + self.cache.delete(cache_url) + + # Give the request a from_cache attr to let people use it + resp.from_cache = from_cache + + return resp + + def close(self): + self.cache.close() + super(CacheControlAdapter, self).close() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py new file mode 100644 index 0000000..94e0773 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/cache.py @@ -0,0 +1,39 @@ +""" +The cache object API for implementing caches. The default is a thread +safe in-memory dictionary. +""" +from threading import Lock + + +class BaseCache(object): + + def get(self, key): + raise NotImplementedError() + + def set(self, key, value): + raise NotImplementedError() + + def delete(self, key): + raise NotImplementedError() + + def close(self): + pass + + +class DictCache(BaseCache): + + def __init__(self, init_dict=None): + self.lock = Lock() + self.data = init_dict or {} + + def get(self, key): + return self.data.get(key, None) + + def set(self, key, value): + with self.lock: + self.data.update({key: value}) + + def delete(self, key): + with self.lock: + if key in self.data: + self.data.pop(key) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py new file mode 100644 index 0000000..0e1658f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__init__.py @@ -0,0 +1,2 @@ +from .file_cache import FileCache # noqa +from .redis_cache import RedisCache # noqa diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b213dc6030f6a7a15854cf289685bd396f6eb0f GIT binary patch literal 250 zcmZ?b<>g`kf~fgwF=0UZF^B^LOhASM5Esh;i4=wu#vF!R#wbQc5SuB7DVI5l8OUZ1 zX3%7L$p}=U$#{#?Ei)(8IWajS70BTVN=?Zu2J`$hS#EKq0p;S8L6Suvqi=B+f#jhg z%s`Qq3`J}}3QYX+)Gx^`&@ad=(9O&%E=kPE(M>K-&&w()Gyw^MaeP^7UP^wEKG@9U q{JfH){2U0USU)~KGcU6wK3=b&@)n0pZhlH>PO2TqmBk>tc^CmLr$K%I literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/file_cache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ab8948331ee8c2fbd2e9f08675ee6086716bcce GIT binary patch literal 3184 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 aeoA$s_y8o}0d8k4G=WhY^(N>nz4$MWX5|Y2 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/__pycache__/redis_cache.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..213c37305bbae27157aa4676ebc049936b32ac74 GIT binary patch literal 1506 zcmaJ>OK;Oa5Z;IFxM@OzsCZn;A|a$mkX|@&s0sokKtefy5Xb^q#=C6|j-Bpq`iRVl z{tucXf5}%)`~^<TtP>I{#7et6-r4c@&1)ZbyKMp^`gZ62J5I<C{8$VRghw#V16U-H zG$$h(QHnCl*@#8V$vo#HFY+jPMx-bGGa`NEedUoagV&_r`U%#gPwP--N14gW!pVtM zHXA9B*B&QEJxS67mEz6C05%Q!E(nT5RFa5ED%lx{xa87<-IJGOAX{e?utK>8CxL9s zb=X_7BfGGN(gzM3b^Dc)nQ2hi90GToPhc7hLq#hRgLhy-hrrBB%cAJB+A}KO(*fN0 zPIL&{ub10)G~OO(<9k_QY?9~q(&PQ&lRdnThi=A4s*t7LPMv3EVRe}|A7)!4nb>It z<I_5f<E+SR9Iqi0M~_agEEx|L`gD~#2FOwGfKZW7<eXM?MjP_X(XIKuvVEpoaHHm* z)v06OEQqDoVL|f+=%p1<Fde2?12}NU064%M5Grmq7oZiJK_wKoD{k32pONe23wJuN zqSmkYc`zeiDcs^%FAc%goS;!wqbGGRv1w5r*FK!6lbUCRt-H2_;KoKlBBbei&Jm4- zYyT+8C#r6#lX0e%x#(CI?rgv`m@Yy++G8C$U3Cv&{vFO97%V)SxoZC_q=8g9Fq}u# zk+}%I34gc>a}m|cD^YE%QwnMvm{5$Zi|cI=PPQ8C8F@-R^u9nvLSh*vmXgEHTj)Yy z!=^8ut9-1q*ekV2bCu|<*cVWT!X79Ai8dlDL?UEjlaJ6|1M$Wvah%zMwwRAJnOJDX zTf;tYQsJSQM(+Rdt@a(-4Y*}oZSWqQ_E!9J>ObzGn>d|&cz;g+p|cPZql~~NQz>#0 z<Fd@bk-MTOMWK`wwgm4=ppI@WFAjz-<bB!{1m<{I)JPFbZo*-c0Cs^OD6zlSu<wdw zq~f@4$ML9?lN{wv93M`SywPZU7hIcYEGZWrjk(p=a9JWd$@P>E3T!xobsDmehrHc_ zHPEOT_5(!Qo7jm4G>rw|8X($&mt!!0H3sR*tI>RD44?bOzfkLNr*U8x!)>rtJ5cc* F{u_Y2N7DcR literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py new file mode 100644 index 0000000..1ba0080 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/file_cache.py @@ -0,0 +1,146 @@ +import hashlib +import os +from textwrap import dedent + +from ..cache import BaseCache +from ..controller import CacheController + +try: + FileNotFoundError +except NameError: + # py2.X + FileNotFoundError = (IOError, OSError) + + +def _secure_open_write(filename, fmode): + # We only want to write to this file, so open it in write only mode + flags = os.O_WRONLY + + # os.O_CREAT | os.O_EXCL will fail if the file already exists, so we only + # will open *new* files. + # We specify this because we want to ensure that the mode we pass is the + # mode of the file. + flags |= os.O_CREAT | os.O_EXCL + + # Do not follow symlinks to prevent someone from making a symlink that + # we follow and insecurely open a cache file. + if hasattr(os, "O_NOFOLLOW"): + flags |= os.O_NOFOLLOW + + # On Windows we'll mark this file as binary + if hasattr(os, "O_BINARY"): + flags |= os.O_BINARY + + # Before we open our file, we want to delete any existing file that is + # there + try: + os.remove(filename) + except (IOError, OSError): + # The file must not exist already, so we can just skip ahead to opening + pass + + # Open our file, the use of os.O_CREAT | os.O_EXCL will ensure that if a + # race condition happens between the os.remove and this line, that an + # error will be raised. Because we utilize a lockfile this should only + # happen if someone is attempting to attack us. + fd = os.open(filename, flags, fmode) + try: + return os.fdopen(fd, "wb") + + except: + # An error occurred wrapping our FD in a file object + os.close(fd) + raise + + +class FileCache(BaseCache): + + def __init__( + self, + directory, + forever=False, + filemode=0o0600, + dirmode=0o0700, + use_dir_lock=None, + lock_class=None, + ): + + if use_dir_lock is not None and lock_class is not None: + raise ValueError("Cannot use use_dir_lock and lock_class together") + + try: + from pip._vendor.lockfile import LockFile + from pip._vendor.lockfile.mkdirlockfile import MkdirLockFile + except ImportError: + notice = dedent( + """ + NOTE: In order to use the FileCache you must have + lockfile installed. You can install it via pip: + pip install lockfile + """ + ) + raise ImportError(notice) + + else: + if use_dir_lock: + lock_class = MkdirLockFile + + elif lock_class is None: + lock_class = LockFile + + self.directory = directory + self.forever = forever + self.filemode = filemode + self.dirmode = dirmode + self.lock_class = lock_class + + @staticmethod + def encode(x): + return hashlib.sha224(x.encode()).hexdigest() + + def _fn(self, name): + # NOTE: This method should not change as some may depend on it. + # See: https://github.com/ionrock/cachecontrol/issues/63 + hashed = self.encode(name) + parts = list(hashed[:5]) + [hashed] + return os.path.join(self.directory, *parts) + + def get(self, key): + name = self._fn(key) + try: + with open(name, "rb") as fh: + return fh.read() + + except FileNotFoundError: + return None + + def set(self, key, value): + name = self._fn(key) + + # Make sure the directory exists + try: + os.makedirs(os.path.dirname(name), self.dirmode) + except (IOError, OSError): + pass + + with self.lock_class(name) as lock: + # Write our actual file + with _secure_open_write(lock.path, self.filemode) as fh: + fh.write(value) + + def delete(self, key): + name = self._fn(key) + if not self.forever: + try: + os.remove(name) + except FileNotFoundError: + pass + + +def url_to_file_path(url, filecache): + """Return the file cache path based on the URL. + + This does not ensure the file exists! + """ + key = CacheController.cache_url(url) + return filecache._fn(key) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py new file mode 100644 index 0000000..ed705ce --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/caches/redis_cache.py @@ -0,0 +1,33 @@ +from __future__ import division + +from datetime import datetime +from pip._vendor.cachecontrol.cache import BaseCache + + +class RedisCache(BaseCache): + + def __init__(self, conn): + self.conn = conn + + def get(self, key): + return self.conn.get(key) + + def set(self, key, value, expires=None): + if not expires: + self.conn.set(key, value) + else: + expires = expires - datetime.utcnow() + self.conn.setex(key, int(expires.total_seconds()), value) + + def delete(self, key): + self.conn.delete(key) + + def clear(self): + """Helper for clearing all the keys in a database. Use with + caution!""" + for key in self.conn.keys(): + self.conn.delete(key) + + def close(self): + """Redis uses connection pooling, no need to close the connection.""" + pass diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py new file mode 100644 index 0000000..33b5aed --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/compat.py @@ -0,0 +1,29 @@ +try: + from urllib.parse import urljoin +except ImportError: + from urlparse import urljoin + + +try: + import cPickle as pickle +except ImportError: + import pickle + + +# Handle the case where the requests module has been patched to not have +# urllib3 bundled as part of its source. +try: + from pip._vendor.requests.packages.urllib3.response import HTTPResponse +except ImportError: + from pip._vendor.urllib3.response import HTTPResponse + +try: + from pip._vendor.requests.packages.urllib3.util import is_fp_closed +except ImportError: + from pip._vendor.urllib3.util import is_fp_closed + +# Replicate some six behaviour +try: + text_type = unicode +except NameError: + text_type = str diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py new file mode 100644 index 0000000..1b2b943 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.py @@ -0,0 +1,367 @@ +""" +The httplib2 algorithms ported for use with requests. +""" +import logging +import re +import calendar +import time +from email.utils import parsedate_tz + +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .cache import DictCache +from .serialize import Serializer + + +logger = logging.getLogger(__name__) + +URI = re.compile(r"^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?") + + +def parse_uri(uri): + """Parses a URI using the regex given in Appendix B of RFC 3986. + + (scheme, authority, path, query, fragment) = parse_uri(uri) + """ + groups = URI.match(uri).groups() + return (groups[1], groups[3], groups[4], groups[6], groups[8]) + + +class CacheController(object): + """An interface to see if request should cached or not. + """ + + def __init__( + self, cache=None, cache_etags=True, serializer=None, status_codes=None + ): + self.cache = cache or DictCache() + self.cache_etags = cache_etags + self.serializer = serializer or Serializer() + self.cacheable_status_codes = status_codes or (200, 203, 300, 301) + + @classmethod + def _urlnorm(cls, uri): + """Normalize the URL to create a safe key for the cache""" + (scheme, authority, path, query, fragment) = parse_uri(uri) + if not scheme or not authority: + raise Exception("Only absolute URIs are allowed. uri = %s" % uri) + + scheme = scheme.lower() + authority = authority.lower() + + if not path: + path = "/" + + # Could do syntax based normalization of the URI before + # computing the digest. See Section 6.2.2 of Std 66. + request_uri = query and "?".join([path, query]) or path + defrag_uri = scheme + "://" + authority + request_uri + + return defrag_uri + + @classmethod + def cache_url(cls, uri): + return cls._urlnorm(uri) + + def parse_cache_control(self, headers): + known_directives = { + # https://tools.ietf.org/html/rfc7234#section-5.2 + "max-age": (int, True), + "max-stale": (int, False), + "min-fresh": (int, True), + "no-cache": (None, False), + "no-store": (None, False), + "no-transform": (None, False), + "only-if-cached": (None, False), + "must-revalidate": (None, False), + "public": (None, False), + "private": (None, False), + "proxy-revalidate": (None, False), + "s-maxage": (int, True), + } + + cc_headers = headers.get("cache-control", headers.get("Cache-Control", "")) + + retval = {} + + for cc_directive in cc_headers.split(","): + if not cc_directive.strip(): + continue + + parts = cc_directive.split("=", 1) + directive = parts[0].strip() + + try: + typ, required = known_directives[directive] + except KeyError: + logger.debug("Ignoring unknown cache-control directive: %s", directive) + continue + + if not typ or not required: + retval[directive] = None + if typ: + try: + retval[directive] = typ(parts[1].strip()) + except IndexError: + if required: + logger.debug( + "Missing value for cache-control " "directive: %s", + directive, + ) + except ValueError: + logger.debug( + "Invalid value for cache-control directive " "%s, must be %s", + directive, + typ.__name__, + ) + + return retval + + def cached_request(self, request): + """ + Return a cached response if it exists in the cache, otherwise + return False. + """ + cache_url = self.cache_url(request.url) + logger.debug('Looking up "%s" in the cache', cache_url) + cc = self.parse_cache_control(request.headers) + + # Bail out if the request insists on fresh data + if "no-cache" in cc: + logger.debug('Request header has "no-cache", cache bypassed') + return False + + if "max-age" in cc and cc["max-age"] == 0: + logger.debug('Request header has "max_age" as 0, cache bypassed') + return False + + # Request allows serving from the cache, let's see if we find something + cache_data = self.cache.get(cache_url) + if cache_data is None: + logger.debug("No cache entry available") + return False + + # Check whether it can be deserialized + resp = self.serializer.loads(request, cache_data) + if not resp: + logger.warning("Cache entry deserialization failed, entry ignored") + return False + + # If we have a cached 301, return it immediately. We don't + # need to test our response for other headers b/c it is + # intrinsically "cacheable" as it is Permanent. + # See: + # https://tools.ietf.org/html/rfc7231#section-6.4.2 + # + # Client can try to refresh the value by repeating the request + # with cache busting headers as usual (ie no-cache). + if resp.status == 301: + msg = ( + 'Returning cached "301 Moved Permanently" response ' + "(ignoring date and etag information)" + ) + logger.debug(msg) + return resp + + headers = CaseInsensitiveDict(resp.headers) + if not headers or "date" not in headers: + if "etag" not in headers: + # Without date or etag, the cached response can never be used + # and should be deleted. + logger.debug("Purging cached response: no date or etag") + self.cache.delete(cache_url) + logger.debug("Ignoring cached response: no date") + return False + + now = time.time() + date = calendar.timegm(parsedate_tz(headers["date"])) + current_age = max(0, now - date) + logger.debug("Current age based on date: %i", current_age) + + # TODO: There is an assumption that the result will be a + # urllib3 response object. This may not be best since we + # could probably avoid instantiating or constructing the + # response until we know we need it. + resp_cc = self.parse_cache_control(headers) + + # determine freshness + freshness_lifetime = 0 + + # Check the max-age pragma in the cache control header + if "max-age" in resp_cc: + freshness_lifetime = resp_cc["max-age"] + logger.debug("Freshness lifetime from max-age: %i", freshness_lifetime) + + # If there isn't a max-age, check for an expires header + elif "expires" in headers: + expires = parsedate_tz(headers["expires"]) + if expires is not None: + expire_time = calendar.timegm(expires) - date + freshness_lifetime = max(0, expire_time) + logger.debug("Freshness lifetime from expires: %i", freshness_lifetime) + + # Determine if we are setting freshness limit in the + # request. Note, this overrides what was in the response. + if "max-age" in cc: + freshness_lifetime = cc["max-age"] + logger.debug( + "Freshness lifetime from request max-age: %i", freshness_lifetime + ) + + if "min-fresh" in cc: + min_fresh = cc["min-fresh"] + # adjust our current age by our min fresh + current_age += min_fresh + logger.debug("Adjusted current age from min-fresh: %i", current_age) + + # Return entry if it is fresh enough + if freshness_lifetime > current_age: + logger.debug('The response is "fresh", returning cached response') + logger.debug("%i > %i", freshness_lifetime, current_age) + return resp + + # we're not fresh. If we don't have an Etag, clear it out + if "etag" not in headers: + logger.debug('The cached response is "stale" with no etag, purging') + self.cache.delete(cache_url) + + # return the original handler + return False + + def conditional_headers(self, request): + cache_url = self.cache_url(request.url) + resp = self.serializer.loads(request, self.cache.get(cache_url)) + new_headers = {} + + if resp: + headers = CaseInsensitiveDict(resp.headers) + + if "etag" in headers: + new_headers["If-None-Match"] = headers["ETag"] + + if "last-modified" in headers: + new_headers["If-Modified-Since"] = headers["Last-Modified"] + + return new_headers + + def cache_response(self, request, response, body=None, status_codes=None): + """ + Algorithm for caching requests. + + This assumes a requests Response object. + """ + # From httplib2: Don't cache 206's since we aren't going to + # handle byte range requests + cacheable_status_codes = status_codes or self.cacheable_status_codes + if response.status not in cacheable_status_codes: + logger.debug( + "Status code %s not in %s", response.status, cacheable_status_codes + ) + return + + response_headers = CaseInsensitiveDict(response.headers) + + # If we've been given a body, our response has a Content-Length, that + # Content-Length is valid then we can check to see if the body we've + # been given matches the expected size, and if it doesn't we'll just + # skip trying to cache it. + if ( + body is not None + and "content-length" in response_headers + and response_headers["content-length"].isdigit() + and int(response_headers["content-length"]) != len(body) + ): + return + + cc_req = self.parse_cache_control(request.headers) + cc = self.parse_cache_control(response_headers) + + cache_url = self.cache_url(request.url) + logger.debug('Updating cache with response from "%s"', cache_url) + + # Delete it from the cache if we happen to have it stored there + no_store = False + if "no-store" in cc: + no_store = True + logger.debug('Response header has "no-store"') + if "no-store" in cc_req: + no_store = True + logger.debug('Request header has "no-store"') + if no_store and self.cache.get(cache_url): + logger.debug('Purging existing cache entry to honor "no-store"') + self.cache.delete(cache_url) + if no_store: + return + + # If we've been given an etag, then keep the response + if self.cache_etags and "etag" in response_headers: + logger.debug("Caching due to etag") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + # Add to the cache any 301s. We do this before looking that + # the Date headers. + elif response.status == 301: + logger.debug("Caching permanant redirect") + self.cache.set(cache_url, self.serializer.dumps(request, response)) + + # Add to the cache if the response headers demand it. If there + # is no date header then we can't do anything about expiring + # the cache. + elif "date" in response_headers: + # cache when there is a max-age > 0 + if "max-age" in cc and cc["max-age"] > 0: + logger.debug("Caching b/c date exists and max-age > 0") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + # If the request can expire, it means we should cache it + # in the meantime. + elif "expires" in response_headers: + if response_headers["expires"]: + logger.debug("Caching b/c of expires header") + self.cache.set( + cache_url, self.serializer.dumps(request, response, body=body) + ) + + def update_cached_response(self, request, response): + """On a 304 we will get a new set of headers that we want to + update our cached value with, assuming we have one. + + This should only ever be called when we've sent an ETag and + gotten a 304 as the response. + """ + cache_url = self.cache_url(request.url) + + cached_response = self.serializer.loads(request, self.cache.get(cache_url)) + + if not cached_response: + # we didn't have a cached response + return response + + # Lets update our headers with the headers from the new request: + # http://tools.ietf.org/html/draft-ietf-httpbis-p4-conditional-26#section-4.1 + # + # The server isn't supposed to send headers that would make + # the cached body invalid. But... just in case, we'll be sure + # to strip out ones we know that might be problmatic due to + # typical assumptions. + excluded_headers = ["content-length"] + + cached_response.headers.update( + dict( + (k, v) + for k, v in response.headers.items() + if k.lower() not in excluded_headers + ) + ) + + # we want a 200 b/c we have content via the cache + cached_response.status = 200 + + # update our cache + self.cache.set(cache_url, self.serializer.dumps(request, cached_response)) + + return cached_response diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py new file mode 100644 index 0000000..30ed4c5 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/filewrapper.py @@ -0,0 +1,80 @@ +from io import BytesIO + + +class CallbackFileWrapper(object): + """ + Small wrapper around a fp object which will tee everything read into a + buffer, and when that file is closed it will execute a callback with the + contents of that buffer. + + All attributes are proxied to the underlying file object. + + This class uses members with a double underscore (__) leading prefix so as + not to accidentally shadow an attribute. + """ + + def __init__(self, fp, callback): + self.__buf = BytesIO() + self.__fp = fp + self.__callback = callback + + def __getattr__(self, name): + # The vaguaries of garbage collection means that self.__fp is + # not always set. By using __getattribute__ and the private + # name[0] allows looking up the attribute value and raising an + # AttributeError when it doesn't exist. This stop thigns from + # infinitely recursing calls to getattr in the case where + # self.__fp hasn't been set. + # + # [0] https://docs.python.org/2/reference/expressions.html#atom-identifiers + fp = self.__getattribute__("_CallbackFileWrapper__fp") + return getattr(fp, name) + + def __is_fp_closed(self): + try: + return self.__fp.fp is None + + except AttributeError: + pass + + try: + return self.__fp.closed + + except AttributeError: + pass + + # We just don't cache it then. + # TODO: Add some logging here... + return False + + def _close(self): + if self.__callback: + self.__callback(self.__buf.getvalue()) + + # We assign this to None here, because otherwise we can get into + # really tricky problems where the CPython interpreter dead locks + # because the callback is holding a reference to something which + # has a __del__ method. Setting this to None breaks the cycle + # and allows the garbage collector to do it's thing normally. + self.__callback = None + + def read(self, amt=None): + data = self.__fp.read(amt) + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data + + def _safe_read(self, amt): + data = self.__fp._safe_read(amt) + if amt == 2 and data == b"\r\n": + # urllib executes this read to toss the CRLF at the end + # of the chunk. + return data + + self.__buf.write(data) + if self.__is_fp_closed(): + self._close() + + return data diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py new file mode 100644 index 0000000..6c0e979 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/heuristics.py @@ -0,0 +1,135 @@ +import calendar +import time + +from email.utils import formatdate, parsedate, parsedate_tz + +from datetime import datetime, timedelta + +TIME_FMT = "%a, %d %b %Y %H:%M:%S GMT" + + +def expire_after(delta, date=None): + date = date or datetime.utcnow() + return date + delta + + +def datetime_to_header(dt): + return formatdate(calendar.timegm(dt.timetuple())) + + +class BaseHeuristic(object): + + def warning(self, response): + """ + Return a valid 1xx warning header value describing the cache + adjustments. + + The response is provided too allow warnings like 113 + http://tools.ietf.org/html/rfc7234#section-5.5.4 where we need + to explicitly say response is over 24 hours old. + """ + return '110 - "Response is Stale"' + + def update_headers(self, response): + """Update the response headers with any new headers. + + NOTE: This SHOULD always include some Warning header to + signify that the response was cached by the client, not + by way of the provided headers. + """ + return {} + + def apply(self, response): + updated_headers = self.update_headers(response) + + if updated_headers: + response.headers.update(updated_headers) + warning_header_value = self.warning(response) + if warning_header_value is not None: + response.headers.update({"Warning": warning_header_value}) + + return response + + +class OneDayCache(BaseHeuristic): + """ + Cache the response by providing an expires 1 day in the + future. + """ + + def update_headers(self, response): + headers = {} + + if "expires" not in response.headers: + date = parsedate(response.headers["date"]) + expires = expire_after(timedelta(days=1), date=datetime(*date[:6])) + headers["expires"] = datetime_to_header(expires) + headers["cache-control"] = "public" + return headers + + +class ExpiresAfter(BaseHeuristic): + """ + Cache **all** requests for a defined time period. + """ + + def __init__(self, **kw): + self.delta = timedelta(**kw) + + def update_headers(self, response): + expires = expire_after(self.delta) + return {"expires": datetime_to_header(expires), "cache-control": "public"} + + def warning(self, response): + tmpl = "110 - Automatically cached for %s. Response might be stale" + return tmpl % self.delta + + +class LastModified(BaseHeuristic): + """ + If there is no Expires header already, fall back on Last-Modified + using the heuristic from + http://tools.ietf.org/html/rfc7234#section-4.2.2 + to calculate a reasonable value. + + Firefox also does something like this per + https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ + http://lxr.mozilla.org/mozilla-release/source/netwerk/protocol/http/nsHttpResponseHead.cpp#397 + Unlike mozilla we limit this to 24-hr. + """ + cacheable_by_default_statuses = { + 200, 203, 204, 206, 300, 301, 404, 405, 410, 414, 501 + } + + def update_headers(self, resp): + headers = resp.headers + + if "expires" in headers: + return {} + + if "cache-control" in headers and headers["cache-control"] != "public": + return {} + + if resp.status not in self.cacheable_by_default_statuses: + return {} + + if "date" not in headers or "last-modified" not in headers: + return {} + + date = calendar.timegm(parsedate_tz(headers["date"])) + last_modified = parsedate(headers["last-modified"]) + if date is None or last_modified is None: + return {} + + now = time.time() + current_age = max(0, now - date) + delta = date - calendar.timegm(last_modified) + freshness_lifetime = max(0, min(delta / 10, 24 * 3600)) + if freshness_lifetime <= current_age: + return {} + + expires = date + freshness_lifetime + return {"expires": time.strftime(TIME_FMT, time.gmtime(expires))} + + def warning(self, resp): + return None diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py new file mode 100644 index 0000000..ec43ff2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/serialize.py @@ -0,0 +1,186 @@ +import base64 +import io +import json +import zlib + +from pip._vendor import msgpack +from pip._vendor.requests.structures import CaseInsensitiveDict + +from .compat import HTTPResponse, pickle, text_type + + +def _b64_decode_bytes(b): + return base64.b64decode(b.encode("ascii")) + + +def _b64_decode_str(s): + return _b64_decode_bytes(s).decode("utf8") + + +class Serializer(object): + + def dumps(self, request, response, body=None): + response_headers = CaseInsensitiveDict(response.headers) + + if body is None: + body = response.read(decode_content=False) + + # NOTE: 99% sure this is dead code. I'm only leaving it + # here b/c I don't have a test yet to prove + # it. Basically, before using + # `cachecontrol.filewrapper.CallbackFileWrapper`, + # this made an effort to reset the file handle. The + # `CallbackFileWrapper` short circuits this code by + # setting the body as the content is consumed, the + # result being a `body` argument is *always* passed + # into cache_response, and in turn, + # `Serializer.dump`. + response._fp = io.BytesIO(body) + + # NOTE: This is all a bit weird, but it's really important that on + # Python 2.x these objects are unicode and not str, even when + # they contain only ascii. The problem here is that msgpack + # understands the difference between unicode and bytes and we + # have it set to differentiate between them, however Python 2 + # doesn't know the difference. Forcing these to unicode will be + # enough to have msgpack know the difference. + data = { + u"response": { + u"body": body, + u"headers": dict( + (text_type(k), text_type(v)) for k, v in response.headers.items() + ), + u"status": response.status, + u"version": response.version, + u"reason": text_type(response.reason), + u"strict": response.strict, + u"decode_content": response.decode_content, + } + } + + # Construct our vary headers + data[u"vary"] = {} + if u"vary" in response_headers: + varied_headers = response_headers[u"vary"].split(",") + for header in varied_headers: + header = text_type(header).strip() + header_value = request.headers.get(header, None) + if header_value is not None: + header_value = text_type(header_value) + data[u"vary"][header] = header_value + + return b",".join([b"cc=4", msgpack.dumps(data, use_bin_type=True)]) + + def loads(self, request, data): + # Short circuit if we've been given an empty set of data + if not data: + return + + # Determine what version of the serializer the data was serialized + # with + try: + ver, data = data.split(b",", 1) + except ValueError: + ver = b"cc=0" + + # Make sure that our "ver" is actually a version and isn't a false + # positive from a , being in the data stream. + if ver[:3] != b"cc=": + data = ver + data + ver = b"cc=0" + + # Get the version number out of the cc=N + ver = ver.split(b"=", 1)[-1].decode("ascii") + + # Dispatch to the actual load method for the given version + try: + return getattr(self, "_loads_v{}".format(ver))(request, data) + + except AttributeError: + # This is a version we don't have a loads function for, so we'll + # just treat it as a miss and return None + return + + def prepare_response(self, request, cached): + """Verify our vary headers match and construct a real urllib3 + HTTPResponse object. + """ + # Special case the '*' Vary value as it means we cannot actually + # determine if the cached response is suitable for this request. + if "*" in cached.get("vary", {}): + return + + # Ensure that the Vary headers for the cached response match our + # request + for header, value in cached.get("vary", {}).items(): + if request.headers.get(header, None) != value: + return + + body_raw = cached["response"].pop("body") + + headers = CaseInsensitiveDict(data=cached["response"]["headers"]) + if headers.get("transfer-encoding", "") == "chunked": + headers.pop("transfer-encoding") + + cached["response"]["headers"] = headers + + try: + body = io.BytesIO(body_raw) + except TypeError: + # This can happen if cachecontrol serialized to v1 format (pickle) + # using Python 2. A Python 2 str(byte string) will be unpickled as + # a Python 3 str (unicode string), which will cause the above to + # fail with: + # + # TypeError: 'str' does not support the buffer interface + body = io.BytesIO(body_raw.encode("utf8")) + + return HTTPResponse(body=body, preload_content=False, **cached["response"]) + + def _loads_v0(self, request, data): + # The original legacy cache data. This doesn't contain enough + # information to construct everything we need, so we'll treat this as + # a miss. + return + + def _loads_v1(self, request, data): + try: + cached = pickle.loads(data) + except ValueError: + return + + return self.prepare_response(request, cached) + + def _loads_v2(self, request, data): + try: + cached = json.loads(zlib.decompress(data).decode("utf8")) + except (ValueError, zlib.error): + return + + # We need to decode the items that we've base64 encoded + cached["response"]["body"] = _b64_decode_bytes(cached["response"]["body"]) + cached["response"]["headers"] = dict( + (_b64_decode_str(k), _b64_decode_str(v)) + for k, v in cached["response"]["headers"].items() + ) + cached["response"]["reason"] = _b64_decode_str(cached["response"]["reason"]) + cached["vary"] = dict( + (_b64_decode_str(k), _b64_decode_str(v) if v is not None else v) + for k, v in cached["vary"].items() + ) + + return self.prepare_response(request, cached) + + def _loads_v3(self, request, data): + # Due to Python 2 encoding issues, it's impossible to know for sure + # exactly how to load v3 entries, thus we'll treat these as a miss so + # that they get rewritten out as v4 entries. + return + + def _loads_v4(self, request, data): + try: + cached = msgpack.loads(data, encoding="utf-8") + except ValueError: + return + + return self.prepare_response(request, cached) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py new file mode 100644 index 0000000..265bfc8 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/cachecontrol/wrapper.py @@ -0,0 +1,29 @@ +from .adapter import CacheControlAdapter +from .cache import DictCache + + +def CacheControl( + sess, + cache=None, + cache_etags=True, + serializer=None, + heuristic=None, + controller_class=None, + adapter_class=None, + cacheable_methods=None, +): + + cache = cache or DictCache() + adapter_class = adapter_class or CacheControlAdapter + adapter = adapter_class( + cache, + cache_etags=cache_etags, + serializer=serializer, + heuristic=heuristic, + controller_class=controller_class, + cacheable_methods=cacheable_methods, + ) + sess.mount("http://", adapter) + sess.mount("https://", adapter) + + return sess diff --git a/env/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py new file mode 100644 index 0000000..aa329fb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/certifi/__init__.py @@ -0,0 +1,3 @@ +from .core import where, old_where + +__version__ = "2018.08.24" diff --git a/env/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py b/env/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py new file mode 100644 index 0000000..ae2aff5 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/certifi/__main__.py @@ -0,0 +1,2 @@ +from pip._vendor.certifi import where +print(where()) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6313534b7ccdb1440108cbd05c859bac69e0cc3d GIT binary patch literal 233 zcmZ?b<>g`kf~fgwG4??EF^B^LOhASM5En}Ti4=wu#vF!R#wf;IrYI&xh7_hK<`m{& z22GZij6i8krdzD#8L367w>a~2QsTkPDlQ`fLkm3v3q2zfKTVcfEXnyrsYM`Di<p7L zE$;aEvecsD%>2Cg_>~MrY#<2`@yk}fB)34nAhSR>Gq1QLF(*eixja2DtEA8bBnZYp vop~wwMf%C9MJ1VOnfmeZnR%Hd@$q^EmA5!-a`RJ4b5iX<4l4%PC%^;%!`?dw literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2130634d04a5ecfa293cad391ffc243dba34900 GIT binary patch literal 216 zcmZ?b<>g`kf~fgwF{VKJF^B^LOhASM5En}Ui4=wu#vF!R#wbQchE%3h#%6|QAS;C_ zm_d{IB~YG0lkpa7c}8kcs-GtFE#ZR90=@XM)V!4ZBE96)qLR$C%p#C^w^$2`GV@AS zG8C}_d0^s~t$s;vfj&@&Zf0I_Nn%cpZgP2gURFt=2}lr(p+@OLjna>g&rQtCi;veU YsJz8tlbfGXnv-hB2sE)6WC;%=0F}cxBme*a literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/certifi/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..810b26a6a2fd2b0299c641fe77b5f22283061c62 GIT binary patch literal 1168 zcmZ`&Piqu06i;SmcV~xIOF;y^<RtE)yDA<OL`p3R9*ST^7=$pLWVdN&lWCIKrA57L zuYLyGqo2g@Fjr501y8;=`=>>0ATKY;%lq?tzwE59Cj>_N{lTZ*kdR-vS&j&lZJ6#Y z2tiUJs0a$0(q;|P;0+O>h|Y<KWH<}cNVG)zoTM$$5izW7*%962z`mBTY|Y4wQX+!) zq?eq1NOEbt8mfMIntWZ2B-uYyj*X3|3dyYWmDP^<L&=nOJ}ZjME2CLq^0{J$EYHwW zzm(&C@*C15dpXMGprCBSbQ>Tffz(MF2%3gXB4K@ZSC&?SJ1KT5EeiQDvs&rV*|&tj z*oV+lnH@7H^U5lJ$_^SU23a0Ruw!ENzR%tjGINq07|7VNQ&U-ZXD2F`jkD64i4t(* z4I4?1b&XMX-ju9z=q<O#xh<zgS_)>3@vh%I-Rnhl%(>3SlJh#@d=3%lYn-1{S+Th3 za4t;F`43_{P;evuJRkURIVe@RwLozzpN{mAKY5CW&EylQg|UN0R|dJU5?W&eaB>Ub zLnV%y{R&^i7Af)y4eo*P<cMAbKD?w~=6duQD07J|5BAQIt5)?|bzoc_m6<=RJ3?7Z z9}66+0t<|ejM6<?)8SPaHiigwYYNcHI~Wl|6S@}I+pw;Z!oyWko3QcZ0{H5K%YYIe z&d5BOpEq{)FvHeL4fGqEi4=Xdq^c<dZ^A$9VgI$6vP`qAQ1AkoxM1|cWJQOn6hN;z z9daWiw!8wG{A1rxTxK`Ko2sIKw3bPMF?;gp@v}biVmhZR;E7t(qXv^}*fnHm0PL=+ zxDVhsJR>xsLD&u~!i8NJXG(M4>)JLP*e(kEKK17Ev%n`@{F7_Z@U;!mu2ov4{eQ#9 YFXqgBiC!I2E21%t!;Mbdj=M4a3kD539RL6T literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem b/env/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem new file mode 100644 index 0000000..85de024 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/certifi/cacert.pem @@ -0,0 +1,4300 @@ + +# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA +# Label: "GlobalSign Root CA" +# Serial: 4835703278459707669005204 +# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a +# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c +# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 +-----BEGIN CERTIFICATE----- +MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG +A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv +b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw +MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i +YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT +aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ +jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp +xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp +1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG +snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ +U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 +9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E +BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B +AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz +yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE +38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP +AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad +DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME +HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 +# Label: "GlobalSign Root CA - R2" +# Serial: 4835703278459682885658125 +# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 +# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe +# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e +-----BEGIN CERTIFICATE----- +MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 +MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL +v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 +eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq +tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd +C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa +zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB +mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH +V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n +bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG +3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs +J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO +291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS +ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd +AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 +TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only +# Label: "Verisign Class 3 Public Primary Certification Authority - G3" +# Serial: 206684696279472310254277870180966723415 +# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 +# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 +# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 +-----BEGIN CERTIFICATE----- +MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw +CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl +cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu +LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT +aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp +dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD +VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT +aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ +bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu +IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b +N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t +KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu +kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm +CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ +Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu +imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te +2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe +DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC +/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p +F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt +TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited +# Label: "Entrust.net Premium 2048 Secure Server CA" +# Serial: 946069240 +# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90 +# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31 +# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77 +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML +RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp +bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 +IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3 +MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 +LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp +YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG +A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq +K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe +sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX +MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT +XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ +HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH +4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV +HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub +j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo +U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf +zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b +u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+ +bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er +fF6adulZkMV8gzURZVE= +-----END CERTIFICATE----- + +# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust +# Label: "Baltimore CyberTrust Root" +# Serial: 33554617 +# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 +# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 +# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ +RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD +VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX +DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y +ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy +VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr +mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr +IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK +mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu +XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy +dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye +jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 +BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 +DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 +9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx +jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 +Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz +ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS +R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp +-----END CERTIFICATE----- + +# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network +# Label: "AddTrust External Root" +# Serial: 1 +# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f +# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 +# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU +MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs +IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 +MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux +FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h +bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt +H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 +uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX +mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX +a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN +E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 +WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD +VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 +Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU +cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx +IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN +AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH +YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 +6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC +Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX +c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a +mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. +# Label: "Entrust Root Certification Authority" +# Serial: 1164660820 +# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 +# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 +# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c +-----BEGIN CERTIFICATE----- +MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 +Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW +KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl +cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw +NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw +NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy +ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV +BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo +Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 +4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 +KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI +rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi +94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB +sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi +gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo +kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE +vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA +A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t +O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua +AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP +9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ +eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m +0vdXcDazv/wor3ElhVsT/h5/WrQ8 +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Global CA O=GeoTrust Inc. +# Label: "GeoTrust Global CA" +# Serial: 144470 +# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 +# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 +# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT +MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i +YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG +EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg +R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 +9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq +fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv +iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU +1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ +bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW +MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA +ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l +uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn +Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS +tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF +PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un +hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV +5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. +# Label: "GeoTrust Universal CA" +# Serial: 1 +# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 +# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 +# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy +c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE +BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 +IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV +VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 +cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT +QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh +F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v +c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w +mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd +VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX +teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ +f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe +Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ +nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB +/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY +MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc +aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX +IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn +ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z +uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN +Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja +QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW +koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 +ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt +DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm +bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. +# Label: "GeoTrust Universal CA 2" +# Serial: 1 +# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 +# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 +# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b +-----BEGIN CERTIFICATE----- +MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW +MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy +c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD +VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 +c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 +WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG +FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq +XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL +se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb +KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd +IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 +y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt +hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc +QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 +Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV +HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ +KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z +dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ +L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr +Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo +ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY +T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz +GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m +1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV +OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH +6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX +QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS +-----END CERTIFICATE----- + +# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association +# Label: "Visa eCommerce Root" +# Serial: 25952180776285836048024890241505565794 +# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02 +# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62 +# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22 +-----BEGIN CERTIFICATE----- +MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr +MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl +cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv +bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw +CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h +dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l +cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h +2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E +lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV +ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq +299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t +vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL +dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF +AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR +zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 +LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd +7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw +++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt +398znM/jra6O1I7mT1GvFpLgXPYHDw== +-----END CERTIFICATE----- + +# Issuer: CN=AAA Certificate Services O=Comodo CA Limited +# Subject: CN=AAA Certificate Services O=Comodo CA Limited +# Label: "Comodo AAA Services root" +# Serial: 1 +# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 +# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 +# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 +-----BEGIN CERTIFICATE----- +MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb +MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow +GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj +YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM +GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua +BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe +3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 +YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR +rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm +ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU +oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF +MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v +QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t +b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF +AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q +GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz +Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 +G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi +l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 +smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority +# Label: "QuoVadis Root CA" +# Serial: 985026699 +# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24 +# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9 +# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73 +-----BEGIN CERTIFICATE----- +MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 +aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz +MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw +IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR +dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp +li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D +rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ +WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug +F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU +xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC +Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv +dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw +ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl +IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh +c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy +ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh +Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI +KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T +KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq +y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p +dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD +VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL +MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk +fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 +7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R +cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y +mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW +xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK +SnQ2+Q== +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2" +# Serial: 1289 +# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b +# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7 +# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86 +-----BEGIN CERTIFICATE----- +MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa +GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg +Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J +WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB +rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp ++ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 +ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i +Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz +PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og +/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH +oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI +yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud +EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 +A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL +MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT +ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f +BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn +g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl +fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K +WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha +B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc +hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR +TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD +mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z +ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y +4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza +8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3" +# Serial: 1478 +# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf +# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85 +# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35 +-----BEGIN CERTIFICATE----- +MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x +GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv +b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV +BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W +YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM +V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB +4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr +H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd +8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv +vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT +mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe +btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc +T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt +WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ +c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A +4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD +VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG +CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 +aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 +aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu +dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw +czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G +A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC +TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg +Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 +7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem +d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd ++LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B +4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN +t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x +DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 +k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s +zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j +Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT +mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK +4SVhM7JZG+Ju1zdXtg2pEto= +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1 +# Subject: O=SECOM Trust.net OU=Security Communication RootCA1 +# Label: "Security Communication Root CA" +# Serial: 0 +# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a +# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7 +# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY +MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t +dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 +WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD +VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 +9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ +DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 +Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N +QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ +xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G +A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T +AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG +kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr +Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 +Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU +JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot +RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== +-----END CERTIFICATE----- + +# Issuer: CN=Sonera Class2 CA O=Sonera +# Subject: CN=Sonera Class2 CA O=Sonera +# Label: "Sonera Class 2 Root CA" +# Serial: 29 +# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb +# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27 +# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27 +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP +MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx +MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV +BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o +Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt +5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s +3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej +vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu +8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw +DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil +zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ +3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD +FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 +Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 +ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M +-----END CERTIFICATE----- + +# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com +# Label: "XRamp Global CA Root" +# Serial: 107108908803651509692980124233745014957 +# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 +# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 +# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB +gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk +MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY +UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx +NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 +dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy +dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 +38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP +KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q +DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 +qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa +JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi +PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P +BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs +jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 +eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD +ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR +vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt +qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa +IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy +i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ +O+7ETPTsJ3xCwnR8gooJybQDJbw= +-----END CERTIFICATE----- + +# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority +# Label: "Go Daddy Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 +# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 +# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 +-----BEGIN CERTIFICATE----- +MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh +MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE +YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 +MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo +ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg +MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN +ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA +PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w +wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi +EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY +avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ +YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE +sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h +/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 +IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD +ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy +OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P +TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ +HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER +dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf +ReYNnyicsbkqWletNw+vHX/bvZ8= +-----END CERTIFICATE----- + +# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority +# Label: "Starfield Class 2 CA" +# Serial: 0 +# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 +# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a +# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 +-----BEGIN CERTIFICATE----- +MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl +MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp +U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw +NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE +ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp +ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 +DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf +8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN ++lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 +X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa +K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA +1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G +A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR +zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 +YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD +bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w +DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 +L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D +eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl +xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp +VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY +WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= +-----END CERTIFICATE----- + +# Issuer: O=Government Root Certification Authority +# Subject: O=Government Root Certification Authority +# Label: "Taiwan GRCA" +# Serial: 42023070807708724159991140556527066870 +# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e +# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9 +# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3 +-----BEGIN CERTIFICATE----- +MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ +MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow +PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR +IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q +gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy +yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts +F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 +jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx +ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC +VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK +YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH +EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN +Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud +DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE +MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK +UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ +TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf +qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK +ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE +JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 +hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 +EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm +nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX +udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz +ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe +LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl +pYYsfPQS +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root CA" +# Serial: 17154717934120587862167794914071425081 +# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 +# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 +# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c +JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP +mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ +wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 +VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ +AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB +AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW +BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun +pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC +dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf +fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm +NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx +H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe ++o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root CA" +# Serial: 10944719598952040374951832963794454346 +# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e +# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 +# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert High Assurance EV Root CA" +# Serial: 3553400076410547919724730734378100087 +# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a +# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 +# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug +RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm ++9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW +PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM +xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB +Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 +hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg +EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA +FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec +nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z +eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF +hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 +Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe +vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep ++OkuE6N36B9K +-----END CERTIFICATE----- + +# Issuer: CN=Class 2 Primary CA O=Certplus +# Subject: CN=Class 2 Primary CA O=Certplus +# Label: "Certplus Class 2 Primary CA" +# Serial: 177770208045934040241468760488327595043 +# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b +# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb +# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw +PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz +cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 +MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz +IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ +ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR +VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL +kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd +EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas +H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 +HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud +DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 +QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu +Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ +AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 +yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR +FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA +ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB +kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 +l7+ijrRU +-----END CERTIFICATE----- + +# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co. +# Label: "DST Root CA X3" +# Serial: 91299735575339953335919266965803778155 +# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5 +# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13 +# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39 +-----BEGIN CERTIFICATE----- +MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow +PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O +rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq +OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b +xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw +7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD +aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG +SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 +ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr +AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz +R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 +JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo +Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG +# Label: "SwissSign Gold CA - G2" +# Serial: 13492815561806991280 +# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93 +# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61 +# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG +# Label: "SwissSign Silver CA - G2" +# Serial: 5700383053117599563 +# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13 +# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb +# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. +# Label: "GeoTrust Primary Certification Authority" +# Serial: 32798226551256963324313806436981982369 +# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf +# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 +# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c +-----BEGIN CERTIFICATE----- +MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY +MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo +R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx +MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK +Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 +AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA +ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 +7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W +kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI +mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ +KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 +6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl +4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K +oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj +UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU +AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA" +# Serial: 69529181992039203566298953787712940909 +# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 +# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 +# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G5" +# Serial: 33037644167568058970164719475676101450 +# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c +# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 +# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df +-----BEGIN CERTIFICATE----- +MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB +yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW +ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 +nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex +t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz +SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG +BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ +rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ +NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E +BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH +BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy +aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv +MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE +p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y +5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK +WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ +4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N +hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq +-----END CERTIFICATE----- + +# Issuer: CN=SecureTrust CA O=SecureTrust Corporation +# Subject: CN=SecureTrust CA O=SecureTrust Corporation +# Label: "SecureTrust CA" +# Serial: 17199774589125277788362757014266862032 +# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1 +# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11 +# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73 +-----BEGIN CERTIFICATE----- +MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz +MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv +cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz +Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO +0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao +wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj +7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS +8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT +BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg +JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC +NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 +6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ +3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm +D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS +CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR +3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= +-----END CERTIFICATE----- + +# Issuer: CN=Secure Global CA O=SecureTrust Corporation +# Subject: CN=Secure Global CA O=SecureTrust Corporation +# Label: "Secure Global CA" +# Serial: 9751836167731051554232119481456978597 +# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de +# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b +# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69 +-----BEGIN CERTIFICATE----- +MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK +MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x +GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx +MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg +Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ +iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa +/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ +jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI +HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 +sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w +gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF +MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw +KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG +AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L +URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO +H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm +I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY +iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc +f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW +-----END CERTIFICATE----- + +# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO Certification Authority O=COMODO CA Limited +# Label: "COMODO Certification Authority" +# Serial: 104350513648249232941998508985834464573 +# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 +# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b +# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 +-----BEGIN CERTIFICATE----- +MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB +gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV +BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw +MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl +YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P +RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 +aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 +UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI +2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 +Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp ++2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ +DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O +nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW +/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g +PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u +QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY +SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv +IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ +RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 +zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd +BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB +ZQ== +-----END CERTIFICATE----- + +# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. +# Label: "Network Solutions Certificate Authority" +# Serial: 116697915152937497490437556386812487904 +# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e +# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce +# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c +-----BEGIN CERTIFICATE----- +MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi +MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu +MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp +dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV +UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO +ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz +c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP +OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl +mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF +BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 +qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw +gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu +bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp +dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 +6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ +h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH +/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv +wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN +pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey +-----END CERTIFICATE----- + +# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited +# Label: "COMODO ECC Certification Authority" +# Serial: 41578283867086692638256921589707938090 +# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 +# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 +# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 +-----BEGIN CERTIFICATE----- +MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL +MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE +BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT +IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw +MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy +ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N +T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR +FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J +cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW +BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm +fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv +GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GA CA" +# Serial: 86718877871133159090080555911823548314 +# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93 +# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9 +# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5 +-----BEGIN CERTIFICATE----- +MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB +ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly +aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl +ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w +NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G +A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD +VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX +SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR +VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2 +w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF +mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg +4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9 +4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw +EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx +SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2 +ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8 +vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa +hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi +Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ +/L7fCg0= +-----END CERTIFICATE----- + +# Issuer: CN=Certigna O=Dhimyotis +# Subject: CN=Certigna O=Dhimyotis +# Label: "Certigna" +# Serial: 18364802974209362175 +# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff +# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97 +# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d +-----BEGIN CERTIFICATE----- +MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV +BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X +DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ +BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4 +QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny +gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw +zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q +130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2 +JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw +DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw +ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT +AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj +AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG +9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h +bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc +fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu +HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w +t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw +WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== +-----END CERTIFICATE----- + +# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center +# Label: "Deutsche Telekom Root CA 2" +# Serial: 38 +# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08 +# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf +# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3 +-----BEGIN CERTIFICATE----- +MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc +MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj +IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB +IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE +RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl +U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290 +IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU +ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC +QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr +rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S +NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc +QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH +txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP +BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC +AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp +tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa +IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl +6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+ +xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU +Cm26OWMohpLzGITY+9HPBVZkVw== +-----END CERTIFICATE----- + +# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc +# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc +# Label: "Cybertrust Global Root" +# Serial: 4835703278459682877484360 +# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 +# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 +# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 +-----BEGIN CERTIFICATE----- +MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG +A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh +bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE +ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS +b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 +7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS +J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y +HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP +t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz +FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY +XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ +MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw +hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js +MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA +A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj +Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx +XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o +omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc +A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW +WL1WMRJOEcgh4LMRkWXbtKaIOM5V +-----END CERTIFICATE----- + +# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority +# Label: "ePKI Root Certification Authority" +# Serial: 28956088682735189655030529057352760477 +# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3 +# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0 +# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5 +-----BEGIN CERTIFICATE----- +MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe +MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0 +ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw +IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL +SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH +SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh +ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X +DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1 +TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ +fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA +sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU +WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS +nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH +dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip +NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC +AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF +MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH +ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB +uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl +PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP +JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/ +gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2 +j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6 +5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB +o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS +/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z +Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE +W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D +hNQ+IIX3Sj0rnP0qCglN6oH4EZw= +-----END CERTIFICATE----- + +# Issuer: O=certSIGN OU=certSIGN ROOT CA +# Subject: O=certSIGN OU=certSIGN ROOT CA +# Label: "certSIGN ROOT CA" +# Serial: 35210227249154 +# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17 +# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b +# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT +AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD +QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP +MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do +0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ +UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d +RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ +OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv +JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C +AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O +BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ +LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY +MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ +44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I +Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw +i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN +9u6wWk5JRFRYX0KD +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G3" +# Serial: 28809105769928564313984085209975885599 +# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 +# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd +# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 +-----BEGIN CERTIFICATE----- +MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB +mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT +MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s +eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv +cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ +BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg +MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 +BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg +LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz ++uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm +hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn +5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W +JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL +DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC +huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw +HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB +AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB +zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN +kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD +AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH +SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G +spki4cErx5z481+oghLrGREt +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G2" +# Serial: 71758320672825410020661621085256472406 +# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f +# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 +# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 +-----BEGIN CERTIFICATE----- +MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp +IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi +BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw +MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh +d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig +YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v +dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ +BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 +papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E +BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K +DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 +KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox +XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== +-----END CERTIFICATE----- + +# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only +# Label: "thawte Primary Root CA - G3" +# Serial: 127614157056681299805556476275995414779 +# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 +# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 +# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c +-----BEGIN CERTIFICATE----- +MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB +rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV +BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa +Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl +LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u +MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl +ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm +gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 +YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf +b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 +9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S +zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk +OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA +2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW +oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu +t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c +KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM +m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu +MdRAGmI0Nj81Aa6sY6A= +-----END CERTIFICATE----- + +# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only +# Label: "GeoTrust Primary Certification Authority - G2" +# Serial: 80682863203381065782177908751794619243 +# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a +# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 +# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 +-----BEGIN CERTIFICATE----- +MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +rD6ogRLQy7rQkgu2npaqBA+K +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Universal Root Certification Authority" +# Serial: 85209574734084581917763752644031726877 +# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 +# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 +# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c +-----BEGIN CERTIFICATE----- +MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB +vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL +ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp +U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W +ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe +Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX +MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 +IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y +IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh +bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF +9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH +H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H +LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN +/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT +rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud +EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw +WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs +exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud +DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 +sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ +seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz +4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ +BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR +lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 +7M2CYfE45k+XmCpajQ== +-----END CERTIFICATE----- + +# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only +# Label: "VeriSign Class 3 Public Primary Certification Authority - G4" +# Serial: 63143484348153506665311985501458640051 +# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 +# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a +# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 +-----BEGIN CERTIFICATE----- +MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL +MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW +ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln +biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp +U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y +aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG +A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp +U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg +SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln +biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm +GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve +fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ +aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj +aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW +kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC +4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga +FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== +-----END CERTIFICATE----- + +# Issuer: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Subject: CN=NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny O=NetLock Kft. OU=Tan\xfas\xedtv\xe1nykiad\xf3k (Certification Services) +# Label: "NetLock Arany (Class Gold) F\u0151tan\xfas\xedtv\xe1ny" +# Serial: 80544274841616 +# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88 +# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91 +# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98 +-----BEGIN CERTIFICATE----- +MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG +EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3 +MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl +cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR +dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB +pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM +b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm +aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz +IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT +lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz +AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5 +VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG +ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2 +BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG +AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M +U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh +bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C ++C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC +bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F +uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2 +XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G2" +# Serial: 10000012 +# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a +# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16 +# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f +-----BEGIN CERTIFICATE----- +MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX +DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291 +qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp +uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU +Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE +pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp +5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M +UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN +GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy +5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv +6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK +eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6 +B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/ +BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov +L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV +HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG +SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS +CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen +5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897 +IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK +gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL ++63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL +vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm +bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk +N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC +Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z +ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ== +-----END CERTIFICATE----- + +# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post +# Label: "Hongkong Post Root CA 1" +# Serial: 1000 +# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca +# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58 +# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2 +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx +FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg +Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG +A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr +b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ +jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn +PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh +ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9 +nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h +q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED +MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC +mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3 +7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB +oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs +EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO +fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi +AmvZWg== +-----END CERTIFICATE----- + +# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc. +# Label: "SecureSign RootCA11" +# Serial: 1 +# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26 +# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3 +# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12 +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr +MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG +A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0 +MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp +Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD +QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz +i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8 +h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV +MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9 +UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni +8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC +h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB +AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm +KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ +X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr +QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5 +pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN +QSdJQO7e5iNEOdyhIta6A/I= +-----END CERTIFICATE----- + +# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd. +# Label: "Microsec e-Szigno Root CA 2009" +# Serial: 14014712776195784473 +# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1 +# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e +# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78 +-----BEGIN CERTIFICATE----- +MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD +VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0 +ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G +CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y +OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx +FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp +Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o +dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP +kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc +cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U +fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7 +N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC +xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1 ++rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G +A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM +Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG +SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h +mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk +ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 +tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c +2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t +HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 +# Label: "GlobalSign Root CA - R3" +# Serial: 4835703278459759426209954 +# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 +# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad +# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b +-----BEGIN CERTIFICATE----- +MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G +A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp +Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 +MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG +A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 +RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT +gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm +KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd +QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ +XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o +LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU +RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp +jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK +6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX +mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs +Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH +WD9f +-----END CERTIFICATE----- + +# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068 +# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068" +# Serial: 6047274297262753887 +# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3 +# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa +# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef +-----BEGIN CERTIFICATE----- +MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE +BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h +cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy +MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg +Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9 +thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM +cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG +L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i +NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h +X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b +m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy +Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja +EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T +KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF +6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh +OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD +VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD +VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp +cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv +ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl +AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF +661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9 +am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1 +ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481 +PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS +3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k +SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF +3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM +ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g +StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz +Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB +jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V +-----END CERTIFICATE----- + +# Issuer: CN=Izenpe.com O=IZENPE S.A. +# Subject: CN=Izenpe.com O=IZENPE S.A. +# Label: "Izenpe.com" +# Serial: 917563065490389241595536686991402621 +# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73 +# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19 +# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A. +# Label: "Chambers of Commerce Root - 2008" +# Serial: 11806822484801597146 +# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7 +# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c +# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0 +-----BEGIN CERTIFICATE----- +MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz +IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz +MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj +dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw +EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp +MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9 +28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq +VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q +DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR +5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL +ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a +Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl +UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s ++12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5 +Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj +ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx +hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV +HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1 ++HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN +YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t +L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy +ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt +IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV +HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w +DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW +PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF +5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1 +glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH +FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2 +pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD +xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG +tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq +jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De +fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg +OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ +d0jQ +-----END CERTIFICATE----- + +# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A. +# Label: "Global Chambersign Root - 2008" +# Serial: 14541511773111788494 +# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3 +# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c +# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca +-----BEGIN CERTIFICATE----- +MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD +VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0 +IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3 +MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD +aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx +MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy +cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG +A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl +BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI +hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed +KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7 +G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2 +zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4 +ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG +HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2 +Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V +yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e +beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r +6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh +wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog +zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW +BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr +ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp +ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk +cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt +YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC +CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow +KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI +hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ +UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz +X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x +fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz +a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd +Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd +SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O +AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso +M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge +v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z +09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B +-----END CERTIFICATE----- + +# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. +# Label: "Go Daddy Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 +# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b +# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz +NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE +AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD +E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH +/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy +DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh +GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR +tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA +AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE +FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX +WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu +9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr +gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo +2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO +LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI +4uJEvlz36hz1 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 +# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e +# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 +-----BEGIN CERTIFICATE----- +MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs +ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw +MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 +b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj +aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp +Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg +nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 +HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N +Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN +dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 +HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G +CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU +sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 +4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg +8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K +pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 +mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 +-----END CERTIFICATE----- + +# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. +# Label: "Starfield Services Root Certificate Authority - G2" +# Serial: 0 +# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 +# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f +# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT +HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs +ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 +MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy +ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy +dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p +OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 +8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K +Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe +hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk +6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q +AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI +bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB +ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z +qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd +iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn +0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN +sSi6 +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Commercial O=AffirmTrust +# Subject: CN=AffirmTrust Commercial O=AffirmTrust +# Label: "AffirmTrust Commercial" +# Serial: 8608355977964138876 +# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 +# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 +# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP +Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr +ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL +MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 +yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr +VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ +nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG +XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj +vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt +Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g +N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC +nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Networking O=AffirmTrust +# Subject: CN=AffirmTrust Networking O=AffirmTrust +# Label: "AffirmTrust Networking" +# Serial: 8957382827206547757 +# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f +# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f +# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b +-----BEGIN CERTIFICATE----- +MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz +dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL +MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp +cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y +YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua +kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL +QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp +6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG +yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i +QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ +KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO +tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu +QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ +Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u +olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 +x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium O=AffirmTrust +# Subject: CN=AffirmTrust Premium O=AffirmTrust +# Label: "AffirmTrust Premium" +# Serial: 7893706540734352110 +# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 +# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 +# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a +-----BEGIN CERTIFICATE----- +MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE +BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz +dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG +A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U +cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf +qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ +JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ ++jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS +s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 +HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 +70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG +V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S +qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S +5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia +C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX +OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE +FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 +KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg +Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B +8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ +MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc +0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ +u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF +u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH +YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 +GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO +RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e +KeC2uAloGRwYQw== +-----END CERTIFICATE----- + +# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust +# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust +# Label: "AffirmTrust Premium ECC" +# Serial: 8401224907861490260 +# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d +# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb +# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 +-----BEGIN CERTIFICATE----- +MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC +VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ +cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ +BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt +VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D +0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 +ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G +A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G +A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs +aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I +flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA" +# Serial: 279744 +# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78 +# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e +# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM +MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D +ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU +cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3 +WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg +Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw +IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH +UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM +TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU +BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM +kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x +AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV +HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y +sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL +I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8 +J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY +VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI +03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA +# Label: "TWCA Root Certification Authority" +# Serial: 1 +# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79 +# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48 +# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44 +-----BEGIN CERTIFICATE----- +MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES +MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU +V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz +WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO +LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE +AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH +K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX +RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z +rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx +3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq +hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC +MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls +XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D +lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn +aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ +YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== +-----END CERTIFICATE----- + +# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2 +# Label: "Security Communication RootCA2" +# Serial: 0 +# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43 +# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74 +# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl +MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe +U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX +DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy +dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj +YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV +OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr +zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM +VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ +hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO +ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw +awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs +OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF +coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc +okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8 +t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy +1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/ +SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2011" +# Serial: 0 +# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9 +# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d +# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71 +-----BEGIN CERTIFICATE----- +MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix +RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p +YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw +NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK +EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl +cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz +dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ +fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns +bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD +75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP +FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV +HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp +5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu +b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA +A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p +6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8 +TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7 +dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys +Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI +l7WdmplNsDz4SgCbZN2fOUvRJ9e4 +-----END CERTIFICATE----- + +# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967 +# Label: "Actalis Authentication Root CA" +# Serial: 6271844772424770508 +# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6 +# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac +# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66 +-----BEGIN CERTIFICATE----- +MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE +BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w +MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 +IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC +SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1 +ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv +UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX +4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9 +KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/ +gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb +rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ +51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F +be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe +KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F +v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn +fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7 +jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz +ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt +ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL +e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70 +jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz +WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V +SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j +pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX +X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok +fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R +K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU +ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU +LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT +LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== +-----END CERTIFICATE----- + +# Issuer: O=Trustis Limited OU=Trustis FPS Root CA +# Subject: O=Trustis Limited OU=Trustis FPS Root CA +# Label: "Trustis FPS Root CA" +# Serial: 36053640375399034304724988975563710553 +# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d +# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04 +# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF +MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL +ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx +MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc +MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+ +AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH +iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj +vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA +0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB +OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/ +BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E +FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01 +GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW +zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4 +1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE +f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F +jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN +ZetX2fNXlrtIzYE= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 2 Root CA" +# Serial: 2 +# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29 +# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99 +# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48 +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr +6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV +L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91 +1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx +MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ +QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB +arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr +Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi +FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS +P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN +9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz +uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h +9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s +A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t +OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo ++fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7 +KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2 +DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us +H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ +I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7 +5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h +3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz +Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA= +-----END CERTIFICATE----- + +# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327 +# Label: "Buypass Class 3 Root CA" +# Serial: 2 +# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec +# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57 +# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d +-----BEGIN CERTIFICATE----- +MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd +MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg +Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow +TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw +HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB +BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y +ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E +N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9 +tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX +0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c +/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X +KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY +zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS +O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D +34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP +K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3 +AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv +Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj +QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV +cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS +IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2 +HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa +O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv +033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u +dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE +kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41 +3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD +u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq +4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc= +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 3" +# Serial: 1 +# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef +# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1 +# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN +8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/ +RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4 +hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5 +ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM +EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1 +A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy +WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ +1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30 +6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT +91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml +e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p +TpPDpFQUWw== +-----END CERTIFICATE----- + +# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus +# Label: "EE Certification Centre Root CA" +# Serial: 112324828676200291871926431888494945866 +# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f +# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7 +# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76 +-----BEGIN CERTIFICATE----- +MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1 +MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 +czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG +CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy +MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl +ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS +b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy +euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO +bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw +WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d +MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE +1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD +VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/ +zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB +BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV +v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG +E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u +uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW +iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v +GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 2009" +# Serial: 623603 +# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f +# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0 +# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1 +-----BEGIN CERTIFICATE----- +MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha +ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM +HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03 +UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42 +tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R +ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM +lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp +/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G +A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G +A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj +dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy +MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl +cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js +L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL +BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni +acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 +o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K +zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8 +PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y +Johw1+qRzT65ysCQblrGXnRl11z+o+I= +-----END CERTIFICATE----- + +# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH +# Label: "D-TRUST Root Class 3 CA 2 EV 2009" +# Serial: 623604 +# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6 +# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83 +# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81 +-----BEGIN CERTIFICATE----- +MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF +MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD +bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw +NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV +BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn +ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0 +3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z +qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR +p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8 +HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw +ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea +HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw +Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh +c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E +RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt +dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku +Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp +3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 +nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF +CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na +xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX +KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1 +-----END CERTIFICATE----- + +# Issuer: CN=CA Disig Root R2 O=Disig a.s. +# Subject: CN=CA Disig Root R2 O=Disig a.s. +# Label: "CA Disig Root R2" +# Serial: 10572350602393338211 +# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03 +# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71 +# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03 +-----BEGIN CERTIFICATE----- +MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV +BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu +MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy +MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx +EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw +ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe +NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH +PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I +x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe +QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR +yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO +QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912 +H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ +QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD +i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs +nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1 +rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI +hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM +tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf +GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb +lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka ++elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal +TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i +nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3 +gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr +G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os +zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x +L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL +-----END CERTIFICATE----- + +# Issuer: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Subject: CN=ACCVRAIZ1 O=ACCV OU=PKIACCV +# Label: "ACCVRAIZ1" +# Serial: 6828503384748696800 +# MD5 Fingerprint: d0:a0:5a:ee:05:b6:09:94:21:a1:7d:f1:b2:29:82:02 +# SHA1 Fingerprint: 93:05:7a:88:15:c6:4f:ce:88:2f:fa:91:16:52:28:78:bc:53:64:17 +# SHA256 Fingerprint: 9a:6e:c0:12:e1:a7:da:9d:be:34:19:4d:47:8a:d7:c0:db:18:22:fb:07:1d:f1:29:81:49:6e:d1:04:38:41:13 +-----BEGIN CERTIFICATE----- +MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE +AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw +CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ +BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND +VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb +qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY +HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo +G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA +lHPrzg5XPAOBOp0KoVdDaaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhr +IA8wKFSVf+DuzgpmndFALW4ir50awQUZ0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/ +0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH +k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47 +4KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMO +m3WR5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpa +cXpkatcnYGMN285J9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPl +uUsXQA+xtrn13k/c4LOsOxFwYIRKQ26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYI +KwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRwOi8vd3d3LmFjY3YuZXMvZmls +ZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEuY3J0MB8GCCsG +AQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 +VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeT +VfZW6oHlNsyMHj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIG +CCsGAQUFBwICMIIBFB6CARAAQQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUA +cgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBhAO0AegAgAGQAZQAgAGwAYQAgAEEA +QwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUAYwBuAG8AbABvAGcA +7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBjAHQA +cgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAA +QwBQAFMAIABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUA +czAwBggrBgEFBQcCARYkaHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2Mu +aHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRt +aW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2MV9kZXIuY3JsMA4GA1Ud +DwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZIhvcNAQEF +BQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdp +D70ER9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gU +JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m +AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD +vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms +tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH +7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h +I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA +h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF +d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H +pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7 +-----END CERTIFICATE----- + +# Issuer: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Subject: CN=TWCA Global Root CA O=TAIWAN-CA OU=Root CA +# Label: "TWCA Global Root CA" +# Serial: 3262 +# MD5 Fingerprint: f9:03:7e:cf:e6:9e:3c:73:7a:2a:90:07:69:ff:2b:96 +# SHA1 Fingerprint: 9c:bb:48:53:f6:a4:f6:d3:52:a4:e8:32:52:55:60:13:f5:ad:af:65 +# SHA256 Fingerprint: 59:76:90:07:f7:68:5d:0f:cd:50:87:2f:9f:95:d5:75:5a:5b:2b:45:7d:81:f3:69:2b:61:0a:98:67:2f:0e:1b +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcx +EjAQBgNVBAoTCVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMT +VFdDQSBHbG9iYWwgUm9vdCBDQTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5 +NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQKEwlUQUlXQU4tQ0ExEDAOBgNVBAsT +B1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3QgQ0EwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2CnJfF +10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz +0ALfUPZVr2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfCh +MBwqoJimFb3u/Rk28OKRQ4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbH +zIh1HrtsBv+baz4X7GGqcXzGHaL3SekVtTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc +46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1WKKD+u4ZqyPpcC1jcxkt2 +yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99sy2sbZCi +laLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYP +oA/pyJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQA +BDzfuBSO6N+pjWxnkjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcE +qYSjMq+u7msXi7Kx/mzhkIyIqJdIzshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm +4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6gcFGn90xHNcgL +1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn +LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WF +H6vPNOw/KP4M8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNo +RI2T9GRwoD2dKAXDOXC4Ynsg/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+ +nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlglPx4mI88k1HtQJAH32RjJMtOcQWh +15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryPA9gK8kxkRr05YuWW +6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3mi4TW +nsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5j +wa19hAM8EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWz +aGHQRiapIVJpLesux+t3zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmy +KwbQBM0= +-----END CERTIFICATE----- + +# Issuer: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Subject: CN=TeliaSonera Root CA v1 O=TeliaSonera +# Label: "TeliaSonera Root CA v1" +# Serial: 199041966741090107964904287217786801558 +# MD5 Fingerprint: 37:41:49:1b:18:56:9a:26:f5:ad:c2:66:fb:40:a5:4c +# SHA1 Fingerprint: 43:13:bb:96:f1:d5:86:9b:c1:4e:6a:92:f6:cf:f6:34:69:87:82:37 +# SHA256 Fingerprint: dd:69:36:fe:21:f8:f0:77:c1:23:a1:a5:21:c1:22:24:f7:22:55:b7:3e:03:a7:26:06:93:e8:a2:4b:0f:a3:89 +-----BEGIN CERTIFICATE----- +MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAw +NzEUMBIGA1UECgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJv +b3QgQ0EgdjEwHhcNMDcxMDE4MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYD +VQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwWVGVsaWFTb25lcmEgUm9vdCBDQSB2 +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+6yfwIaPzaSZVfp3F +VRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA3GV1 +7CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+X +Z75Ljo1kB1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+ +/jXh7VB7qTCNGdMJjmhnXb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs +81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxHoLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkm +dtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3F0fUTPHSiXk+TT2YqGHe +Oh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJoWjiUIMu +sDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4 +pgd7gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fs +slESl1MpWtTwEhDcTwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQ +arMCpgKIv7NHfirZ1fpoeDVNAgMBAAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYD +VR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qWDNXr+nuqF+gTEjANBgkqhkiG +9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNmzqjMDfz1mgbl +dxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx +0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1Tj +TQpgcmLNkQfWpb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBed +Y2gea+zDTYa4EzAvXUYNR0PVG6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7 +Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpcc41teyWRyu5FrgZLAMzTsVlQ2jqI +OylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOTJsjrDNYmiLbAJM+7 +vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2qReW +t88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcn +HL/EVlP6Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVx +SK236thZiNSQvxaz2emsWWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= +-----END CERTIFICATE----- + +# Issuer: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Subject: CN=E-Tugra Certification Authority O=E-Tu\u011fra EBG Bili\u015fim Teknolojileri ve Hizmetleri A.\u015e. OU=E-Tugra Sertifikasyon Merkezi +# Label: "E-Tugra Certification Authority" +# Serial: 7667447206703254355 +# MD5 Fingerprint: b8:a1:03:63:b0:bd:21:71:70:8a:6f:13:3a:bb:79:49 +# SHA1 Fingerprint: 51:c6:e7:08:49:06:6e:f3:92:d4:5c:a0:0d:6d:a3:62:8f:c3:52:39 +# SHA256 Fingerprint: b0:bf:d5:2b:b0:d7:d9:bd:92:bf:5d:4d:c1:3d:a2:55:c0:2c:54:2f:37:83:65:ea:89:39:11:f5:5e:55:f2:3c +-----BEGIN CERTIFICATE----- +MIIGSzCCBDOgAwIBAgIIamg+nFGby1MwDQYJKoZIhvcNAQELBQAwgbIxCzAJBgNV +BAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+BgNVBAoMN0UtVHXEn3JhIEVCRyBC +aWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhpem1ldGxlcmkgQS7Fni4xJjAkBgNV +BAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBNZXJrZXppMSgwJgYDVQQDDB9FLVR1 +Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDMwNTEyMDk0OFoXDTIz +MDMwMzEyMDk0OFowgbIxCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmthcmExQDA+ +BgNVBAoMN0UtVHXEn3JhIEVCRyBCaWxpxZ9pbSBUZWtub2xvamlsZXJpIHZlIEhp +em1ldGxlcmkgQS7Fni4xJjAkBgNVBAsMHUUtVHVncmEgU2VydGlmaWthc3lvbiBN +ZXJrZXppMSgwJgYDVQQDDB9FLVR1Z3JhIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4vU/kwVRHoViVF56C/UY +B4Oufq9899SKa6VjQzm5S/fDxmSJPZQuVIBSOTkHS0vdhQd2h8y/L5VMzH2nPbxH +D5hw+IyFHnSOkm0bQNGZDbt1bsipa5rAhDGvykPL6ys06I+XawGb1Q5KCKpbknSF +Q9OArqGIW66z6l7LFpp3RMih9lRozt6Plyu6W0ACDGQXwLWTzeHxE2bODHnv0ZEo +q1+gElIwcxmOj+GMB6LDu0rw6h8VqO4lzKRG+Bsi77MOQ7osJLjFLFzUHPhdZL3D +k14opz8n8Y4e0ypQBaNV2cvnOVPAmJ6MVGKLJrD3fY185MaeZkJVgkfnsliNZvcH +fC425lAcP9tDJMW/hkd5s3kc91r0E+xs+D/iWR+V7kI+ua2oMoVJl0b+SzGPWsut +dEcf6ZG33ygEIqDUD13ieU/qbIWGvaimzuT6w+Gzrt48Ue7LE3wBf4QOXVGUnhMM +ti6lTPk5cDZvlsouDERVxcr6XQKj39ZkjFqzAQqptQpHF//vkUAqjqFGOjGY5RH8 +zLtJVor8udBhmm9lbObDyz51Sf6Pp+KJxWfXnUYTTjF2OySznhFlhqt/7x3U+Lzn +rFpct1pHXFXOVbQicVtbC/DP3KBhZOqp12gKY6fgDT+gr9Oq0n7vUaDmUStVkhUX +U8u3Zg5mTPj5dUyQ5xJwx0UCAwEAAaNjMGEwHQYDVR0OBBYEFC7j27JJ0JxUeVz6 +Jyr+zE7S6E5UMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAULuPbsknQnFR5 +XPonKv7MTtLoTlQwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAF +Nzr0TbdF4kV1JI+2d1LoHNgQk2Xz8lkGpD4eKexd0dCrfOAKkEh47U6YA5n+KGCR +HTAduGN8qOY1tfrTYXbm1gdLymmasoR6d5NFFxWfJNCYExL/u6Au/U5Mh/jOXKqY +GwXgAEZKgoClM4so3O0409/lPun++1ndYYRP0lSWE2ETPo+Aab6TR7U1Q9Jauz1c +77NCR807VRMGsAnb/WP2OogKmW9+4c4bU2pEZiNRCHu8W1Ki/QY3OEBhj0qWuJA3 ++GbHeJAAFS6LrVE1Uweoa2iu+U48BybNCAVwzDk/dr2l02cmAYamU9JgO3xDf1WK +vJUawSg5TB9D0pH0clmKuVb8P7Sd2nCcdlqMQ1DujjByTd//SffGqWfZbawCEeI6 +FiWnWAjLb1NBnEg4R2gz0dfHj9R0IdTDBZB6/86WiLEVKV0jq9BgoRJP3vQXzTLl +yb/IQ639Lo7xr+L0mPoSHyDYwKcMhcWQ9DstliaxLL5Mq+ux0orJ23gTDx4JnW2P +AJ8C2sH6H3p6CcRK5ogql5+Ji/03X186zjhZhkuvcQu02PJwT58yE+Owp1fl2tpD +y4Q08ijE6m30Ku/Ba3ba+367hTzSU8JNvnHhRdH9I2cNE3X7z2VnIp2usAnRCf8d +NL/+I5c30jn6PQ0GC7TbO6Orb1wdtn7os4I07QZcJA== +-----END CERTIFICATE----- + +# Issuer: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Subject: CN=T-TeleSec GlobalRoot Class 2 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center +# Label: "T-TeleSec GlobalRoot Class 2" +# Serial: 1 +# MD5 Fingerprint: 2b:9b:9e:e4:7b:6c:1f:00:72:1a:cc:c1:77:79:df:6a +# SHA1 Fingerprint: 59:0d:2d:7d:88:4f:40:2e:61:7e:a5:62:32:17:65:cf:17:d8:94:e9 +# SHA256 Fingerprint: 91:e2:f5:78:8d:58:10:eb:a7:ba:58:73:7d:e1:54:8a:8e:ca:cd:01:45:98:bc:0b:14:3e:04:1b:17:05:25:52 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx +KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd +BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl +YyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgxMDAxMTA0MDE0WhcNMzMxMDAxMjM1 +OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy +aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50 +ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUd +AqSzm1nzHoqvNK38DcLZSBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiC +FoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/FvudocP05l03Sx5iRUKrERLMjfTlH6VJi +1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx9702cu+fjOlbpSD8DT6Iavq +jnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGVWOHAD3bZ +wI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGj +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/ +WSA2AHmgoCJrjNXyYdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhy +NsZt+U2e+iKo4YFWz827n+qrkRk4r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPAC +uvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNfvNoBYimipidx5joifsFvHZVw +IEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR3p1m0IvVVGb6 +g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN +9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlP +BSeOE6Fuwg== +-----END CERTIFICATE----- + +# Issuer: CN=Atos TrustedRoot 2011 O=Atos +# Subject: CN=Atos TrustedRoot 2011 O=Atos +# Label: "Atos TrustedRoot 2011" +# Serial: 6643877497813316402 +# MD5 Fingerprint: ae:b9:c4:32:4b:ac:7f:5d:66:cc:77:94:bb:2a:77:56 +# SHA1 Fingerprint: 2b:b1:f5:3e:55:0c:1d:c5:f1:d4:e6:b7:6a:46:4b:55:06:02:ac:21 +# SHA256 Fingerprint: f3:56:be:a2:44:b7:a9:1e:b3:5d:53:ca:9a:d7:86:4a:ce:01:8e:2d:35:d5:f8:f9:6d:df:68:a6:f4:1a:a4:74 +-----BEGIN CERTIFICATE----- +MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UE +AwwVQXRvcyBUcnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQG +EwJERTAeFw0xMTA3MDcxNDU4MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMM +FUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsGA1UECgwEQXRvczELMAkGA1UEBhMC +REUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCVhTuXbyo7LjvPpvMp +Nb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr54rM +VD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+ +SZFhyBH+DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ +4J7sVaE3IqKHBAUsR320HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0L +cp2AMBYHlT8oDv3FdU9T1nSatCQujgKRz3bFmx5VdJx4IbHwLfELn8LVlhgf8FQi +eowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7Rl+lwrrw7GWzbITAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZbNshMBgG +A1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3 +DQEBCwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8j +vZfza1zv7v1Apt+hk6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kP +DpFrdRbhIfzYJsdHt6bPWHJxfrrhTZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pc +maHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a961qn8FYiqTxlVMYVqL2Gns2D +lmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G3mB/ufNPRJLv +KrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 1 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 1 G3" +# Serial: 687049649626669250736271037606554624078720034195 +# MD5 Fingerprint: a4:bc:5b:3f:fe:37:9a:fa:64:f0:e2:fa:05:3d:0b:ab +# SHA1 Fingerprint: 1b:8e:ea:57:96:29:1a:c9:39:ea:b8:0a:81:1a:73:73:c0:93:79:67 +# SHA256 Fingerprint: 8a:86:6f:d1:b2:76:b5:7e:57:8e:92:1c:65:82:8a:2b:ed:58:e9:f2:f2:88:05:41:34:b7:f1:f4:bf:c9:cc:74 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00 +MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakEPBtV +wedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWe +rNrwU8lmPNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF341 +68Xfuw6cwI2H44g4hWf6Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh +4Pw5qlPafX7PGglTvF0FBM+hSo+LdoINofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXp +UhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/lg6AnhF4EwfWQvTA9xO+o +abw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV7qJZjqlc +3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/G +KubX9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSt +hfbZxbGL0eUQMk1fiyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KO +Tk0k+17kBL5yG6YnLUlamXrXXAkgt3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOt +zCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZIhvcNAQELBQAD +ggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC +MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2 +cDMT/uFPpiN3GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUN +qXsCHKnQO18LwIE6PWThv6ctTr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5 +YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP+V04ikkwj+3x6xn0dxoxGE1nVGwv +b2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh3jRJjehZrJ3ydlo2 +8hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fawx/k +NSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNj +ZgKAvQU6O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhp +q1467HxpvMc7hU6eFbm0FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFt +nh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOVhMJKzRwuJIczYOXD +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 2 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 2 G3" +# Serial: 390156079458959257446133169266079962026824725800 +# MD5 Fingerprint: af:0c:86:6e:bf:40:2d:7f:0b:3e:12:50:ba:12:3d:06 +# SHA1 Fingerprint: 09:3c:61:f3:8b:8b:dc:7d:55:df:75:38:02:05:00:e1:25:f5:c8:36 +# SHA256 Fingerprint: 8f:e4:fb:0a:f9:3a:4d:0d:67:db:0b:eb:b2:3e:37:c7:1b:f3:25:dc:bc:dd:24:0e:a0:4d:af:58:b4:7e:18:40 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00 +MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFhZiFf +qq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMW +n4rjyduYNM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ym +c5GQYaYDFCDy54ejiK2toIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+ +O7q414AB+6XrW7PFXmAqMaCvN+ggOp+oMiwMzAkd056OXbxMmO7FGmh77FOm6RQ1 +o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+lV0POKa2Mq1W/xPtbAd0j +IaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZoL1NesNKq +IcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz +8eQQsSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43eh +vNURG3YBZwjgQQvD6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l +7ZizlWNof/k19N+IxWA1ksB8aRxhlRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALG +cC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZIhvcNAQELBQAD +ggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 +AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RC +roijQ1h5fq7KpVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0Ga +W/ZZGYjeVYg3UQt4XAoeo0L9x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4n +lv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgzdWqTHBLmYF5vHX/JHyPLhGGfHoJE ++V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6XU/IyAgkwo1jwDQHV +csaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+NwmNtd +dbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNg +KCLjsZWDzYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeM +HVOyToV7BjjHLPj4sHKNJeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4 +WSr2Rz0ZiC3oheGe7IUIarFsNMkd7EgrO3jtZsSOeWmD3n+M +-----END CERTIFICATE----- + +# Issuer: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Subject: CN=QuoVadis Root CA 3 G3 O=QuoVadis Limited +# Label: "QuoVadis Root CA 3 G3" +# Serial: 268090761170461462463995952157327242137089239581 +# MD5 Fingerprint: df:7d:b9:ad:54:6f:68:a1:df:89:57:03:97:43:b0:d7 +# SHA1 Fingerprint: 48:12:bd:92:3c:a8:c4:39:06:e7:30:6d:27:96:e6:a4:cf:22:2e:7d +# SHA256 Fingerprint: 88:ef:81:de:20:2e:b0:18:45:2e:43:f8:64:72:5c:ea:5f:bd:1f:c2:d9:d2:05:73:07:09:c5:d8:b8:69:0f:46 +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQEL +BQAwSDELMAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAc +BgNVBAMTFVF1b1ZhZGlzIFJvb3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00 +MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBM +aW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMgRzMwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286IxSR +/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNu +FoM7pmRLMon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXR +U7Ox7sWTaYI+FrUoRqHe6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+c +ra1AdHkrAj80//ogaX3T7mH1urPnMNA3I4ZyYUUpSFlob3emLoG+B01vr87ERROR +FHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3UVDmrJqMz6nWB2i3ND0/k +A9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f75li59wzw +eyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634Ryl +sSqiMd5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBp +VzgeAVuNVejH38DMdyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0Q +A4XN8f+MFrXBsj6IbGB/kE+V9/YtrQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ +ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +BjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZIhvcNAQELBQAD +ggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px +KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnI +FUBhynLWcKzSt/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5Wvv +oxXqA/4Ti2Tk08HS6IT7SdEQTXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFg +u/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9DuDcpmvJRPpq3t/O5jrFc/ZSXPsoaP +0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGibIh6BJpsQBJFxwAYf +3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmDhPbl +8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+ +DhcI00iX0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HN +PlopNLk9hM6xZdRZkZFWdSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ +ywaZWWDYWGWVjUTR939+J399roD1B0y2PpxxVJkES/1Y+Zj0 +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G2" +# Serial: 15385348160840213938643033620894905419 +# MD5 Fingerprint: 92:38:b9:f8:63:24:82:65:2c:57:33:e6:fe:81:8f:9d +# SHA1 Fingerprint: a1:4b:48:d9:43:ee:0a:0e:40:90:4f:3c:e0:a4:c0:91:93:51:5d:3f +# SHA256 Fingerprint: 7d:05:eb:b6:82:33:9f:8c:94:51:ee:09:4e:eb:fe:fa:79:53:a1:14:ed:b2:f4:49:49:45:2f:ab:7d:2f:c1:85 +-----BEGIN CERTIFICATE----- +MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBl +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv +b3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQG +EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl +cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSA +n61UQbVH35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4Htecc +biJVMWWXvdMX0h5i89vqbFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9Hp +EgjAALAcKxHad3A2m67OeYfcgnDmCXRwVWmvo2ifv922ebPynXApVfSr/5Vh88lA +bx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OPYLfykqGxvYmJHzDNw6Yu +YjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+RnlTGNAgMB +AAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQW +BBTOw0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPI +QW5pJ6d1Ee88hjZv0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I +0jJmwYrA8y8678Dj1JGG0VDjA9tzd29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4Gni +lmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAWhsI6yLETcDbYz+70CjTVW0z9 +B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0MjomZmWzwPDCv +ON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo +IhNzbM8m9Yop5w== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Assured ID Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Assured ID Root G3" +# Serial: 15459312981008553731928384953135426796 +# MD5 Fingerprint: 7c:7f:65:31:0c:81:df:8d:ba:3e:99:e2:5c:ad:6e:fb +# SHA1 Fingerprint: f5:17:a2:4f:9a:48:c6:c9:f8:a2:00:26:9f:dc:0f:48:2c:ab:30:89 +# SHA256 Fingerprint: 7e:37:cb:8b:4c:47:09:0c:ab:36:55:1b:a6:f4:5d:b8:40:68:0f:ba:16:6a:95:2d:b1:00:71:7f:43:05:3f:c2 +-----BEGIN CERTIFICATE----- +MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg +RzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBlMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQBgcq +hkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJf +Zn4f5dwbRXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17Q +RSAPWXYQ1qAk8C3eNvJsKTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ +BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgFUaFNN6KDec6NHSrkhDAKBggqhkjOPQQD +AwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5FyYZ5eEJJZVrmDxxDnOOlY +JjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy1vUhZscv +6pZjamVFkpUBtA== +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G2 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G2" +# Serial: 4293743540046975378534879503202253541 +# MD5 Fingerprint: e4:a6:8a:c8:54:ac:52:42:46:0a:fd:72:48:1b:2a:44 +# SHA1 Fingerprint: df:3c:24:f9:bf:d6:66:76:1b:26:80:73:fe:06:d1:cc:8d:4f:82:a4 +# SHA256 Fingerprint: cb:3c:cb:b7:60:31:e5:e0:13:8f:8d:d3:9a:23:f9:de:47:ff:c3:5e:43:c1:14:4c:ea:27:d4:6a:5a:b1:cb:5f +-----BEGIN CERTIFICATE----- +MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBH +MjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI +2/Ou8jqJkTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx +1x7e/dfgy5SDN67sH0NO3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQ +q2EGnI/yuum06ZIya7XzV+hdG82MHauVBJVJ8zUtluNJbd134/tJS7SsVQepj5Wz +tCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyMUNGPHgm+F6HmIcr9g+UQ +vIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQABo0IwQDAP +BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV +5uNu5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY +1Yl9PMWLSn/pvtsrF9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4 +NeF22d+mQrvHRAiGfzZ0JFrabA0UWTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NG +Fdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBHQRFXGU7Aj64GxJUTFy8bJZ91 +8rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/iyK5S9kJRaTe +pLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl +MrY= +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Global Root G3 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Global Root G3" +# Serial: 7089244469030293291760083333884364146 +# MD5 Fingerprint: f5:5d:a4:50:a5:fb:28:7e:1e:0f:0d:cc:96:57:56:ca +# SHA1 Fingerprint: 7e:04:de:89:6a:3e:66:6d:00:e6:87:d3:3f:fa:d9:3b:e8:3d:34:9e +# SHA256 Fingerprint: 31:ad:66:48:f8:10:41:38:c7:38:f3:9e:a4:32:01:33:39:3e:3a:18:cc:02:29:6e:f9:7c:2a:c9:ef:67:31:d0 +-----BEGIN CERTIFICATE----- +MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQsw +CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu +ZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAe +Fw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGExCzAJBgNVBAYTAlVTMRUw +EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x +IDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0CAQYF +K4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FG +fp4tn+6OYwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPO +Z9wj/wMco+I+o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAd +BgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNpYim8S8YwCgYIKoZIzj0EAwMDaAAwZQIx +AK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y3maTD/HMsQmP3Wyr+mt/ +oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34VOKa5Vt8 +sycX +-----END CERTIFICATE----- + +# Issuer: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Subject: CN=DigiCert Trusted Root G4 O=DigiCert Inc OU=www.digicert.com +# Label: "DigiCert Trusted Root G4" +# Serial: 7451500558977370777930084869016614236 +# MD5 Fingerprint: 78:f2:fc:aa:60:1f:2f:b4:eb:c9:37:ba:53:2e:75:49 +# SHA1 Fingerprint: dd:fb:16:cd:49:31:c9:73:a2:03:7d:3f:c8:3a:4d:7d:77:5d:05:e4 +# SHA256 Fingerprint: 55:2f:7b:dc:f1:a7:af:9e:6c:e6:72:01:7f:4f:12:ab:f7:72:40:c7:8e:76:1a:c2:03:d1:d9:d2:0a:c8:99:88 +-----BEGIN CERTIFICATE----- +MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBi +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg +RzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1MTIwMDAwWjBiMQswCQYDVQQGEwJV +UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQu +Y29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3y +ithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1If +xp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDV +ySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiO +DCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQ +jdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/ +CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCi +EhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADM +fRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QY +uKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXK +chYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t +9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB +hjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD +ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2 +SV1EY+CtnJYYZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd ++SeuMIW59mdNOj6PWTkiU0TryF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWc +fFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy7zBZLq7gcfJW5GqXb5JQbZaNaHqa +sjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iahixTXTBmyUEFxPT9N +cCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN5r5N +0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie +4u1Ki7wb/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mI +r/OSmbaz5mEP0oUA51Aa5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1 +/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tKG48BtieVU+i2iW1bvGjUI+iLUaJW+fCm +gKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP82Z+ +-----END CERTIFICATE----- + +# Issuer: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Subject: CN=COMODO RSA Certification Authority O=COMODO CA Limited +# Label: "COMODO RSA Certification Authority" +# Serial: 101909084537582093308941363524873193117 +# MD5 Fingerprint: 1b:31:b0:71:40:36:cc:14:36:91:ad:c4:3e:fd:ec:18 +# SHA1 Fingerprint: af:e5:d2:44:a8:d1:19:42:30:ff:47:9f:e2:f8:97:bb:cd:7a:8c:b4 +# SHA256 Fingerprint: 52:f0:e1:c4:e5:8e:c6:29:29:1b:60:31:7f:07:46:71:b8:5d:7e:a8:0d:5b:07:27:34:63:53:4b:32:b4:02:34 +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCB +hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G +A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV +BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMTE5 +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT +EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR +Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNh +dGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR +6FSS0gpWsawNJN3Fz0RndJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8X +pz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZFGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC +9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+5eNu/Nio5JIk2kNrYrhV +/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pGx8cgoLEf +Zd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z ++pUX2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7w +qP/0uK3pN/u6uPQLOvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZah +SL0896+1DSJMwBGB7FY79tOi4lu3sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVIC +u9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+CGCe01a60y1Dma/RMhnEw6abf +Fobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5WdYgGq/yapiq +crxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB +/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvl +wFTPoCWOAvn9sKIN9SCYPBMtrFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM +4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+nq6PK7o9mfjYcwlYRm6mnPTXJ9OV +2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSgtZx8jb8uk2Intzna +FxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwWsRqZ +CuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiK +boHGhfKppC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmcke +jkk9u+UJueBPSZI9FoJAzMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yL +S0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHqZJx64SIDqZxubw5lT2yHh17zbqD5daWb +QOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk527RH89elWsn2/x20Kk4yl +0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7ILaZRfyHB +NVOFBkpdn627G190 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust RSA Certification Authority O=The USERTRUST Network +# Label: "USERTrust RSA Certification Authority" +# Serial: 2645093764781058787591871645665788717 +# MD5 Fingerprint: 1b:fe:69:d1:91:b7:19:33:a3:72:a8:0f:e1:55:e5:b5 +# SHA1 Fingerprint: 2b:8f:1b:57:33:0d:bb:a2:d0:7a:6c:51:f7:0e:e9:0d:da:b9:ad:8e +# SHA256 Fingerprint: e7:93:c9:b0:2f:d8:aa:13:e2:1c:31:22:8a:cc:b0:81:19:64:3b:74:9c:89:89:64:b1:74:6d:46:c3:d4:cb:d2 +-----BEGIN CERTIFICATE----- +MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB +iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl +cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV +BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw +MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV +BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU +aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B +3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY +tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/ +Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2 +VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT +79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6 +c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT +Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l +c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee +UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE +Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd +BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G +A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF +Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO +VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3 +ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs +8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR +iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze +Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ +XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/ +qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB +VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB +L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG +jjxDah2nGN59PRbxYvnKkKj9 +-----END CERTIFICATE----- + +# Issuer: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Subject: CN=USERTrust ECC Certification Authority O=The USERTRUST Network +# Label: "USERTrust ECC Certification Authority" +# Serial: 123013823720199481456569720443997572134 +# MD5 Fingerprint: fa:68:bc:d9:b5:7f:ad:fd:c9:1d:06:83:28:cc:24:c1 +# SHA1 Fingerprint: d1:cb:ca:5d:b2:d5:2a:7f:69:3b:67:4d:e5:f0:5a:1d:0c:95:7d:f0 +# SHA256 Fingerprint: 4f:f4:60:d5:4b:9c:86:da:bf:bc:fc:57:12:e0:40:0d:2b:ed:3f:bc:4d:4f:bd:aa:86:e0:6a:dc:d2:a9:ad:7a +-----BEGIN CERTIFICATE----- +MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl +eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT +JVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAwMjAx +MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT +Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg +VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlm +aWNhdGlvbiBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqflo +I+d61SRvU8Za2EurxtW20eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinng +o4N+LZfQYcTxmdwlkWOrfzCjtHDix6EznPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0G +A1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBBHU6+4WMB +zzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbW +RNZu9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R4 +# Label: "GlobalSign ECC Root CA - R4" +# Serial: 14367148294922964480859022125800977897474 +# MD5 Fingerprint: 20:f0:27:68:d1:7e:a0:9d:0e:e6:2a:ca:df:5c:89:8e +# SHA1 Fingerprint: 69:69:56:2e:40:80:f4:24:a1:e7:19:9f:14:ba:f3:ee:58:ab:6a:bb +# SHA256 Fingerprint: be:c9:49:11:c2:95:56:76:db:6c:0a:55:09:86:d7:6e:3b:a0:05:66:7c:44:2c:97:62:b4:fb:b7:73:de:22:8c +-----BEGIN CERTIFICATE----- +MIIB4TCCAYegAwIBAgIRKjikHJYKBN5CsiilC+g0mAIwCgYIKoZIzj0EAwIwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI0MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI0MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEuMZ5049sJQ6fLjkZHAOkrprlOQcJ +FspjsbmG+IpXwVfOQvpzofdlQv8ewQCybnMO/8ch5RikqtlxP6jUuc6MHaNCMEAw +DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFFSwe61F +uOJAf/sKbvu+M8k8o4TVMAoGCCqGSM49BAMCA0gAMEUCIQDckqGgE6bPA7DmxCGX +kPoUVy0D7O48027KqGx2vKLeuwIgJ6iFJzWbVsaj8kfSt24bAgAXqmemFZHe+pTs +ewv4n4Q= +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign ECC Root CA - R5 +# Label: "GlobalSign ECC Root CA - R5" +# Serial: 32785792099990507226680698011560947931244 +# MD5 Fingerprint: 9f:ad:3b:1c:02:1e:8a:ba:17:74:38:81:0c:a2:bc:08 +# SHA1 Fingerprint: 1f:24:c6:30:cd:a4:18:ef:20:69:ff:ad:4f:dd:5f:46:3a:1b:69:aa +# SHA256 Fingerprint: 17:9f:bc:14:8a:3d:d0:0f:d2:4e:a1:34:58:cc:43:bf:a7:f5:9c:81:82:d7:83:a5:13:f6:eb:ec:10:0c:89:24 +-----BEGIN CERTIFICATE----- +MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEk +MCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpH +bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoX +DTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMbR2xvYmFsU2lnbiBFQ0MgUm9vdCBD +QSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu +MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6SFkc +8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8ke +hOvRnkmSh5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD +VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYI +KoZIzj0EAwMDaAAwZQIxAOVpEslu28YxuglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg +515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7yFz9SO8NdCKoCOJuxUnO +xwy8p2Fp8fc74SrL+SvzZpA3 +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden Root CA - G3 O=Staat der Nederlanden +# Label: "Staat der Nederlanden Root CA - G3" +# Serial: 10003001 +# MD5 Fingerprint: 0b:46:67:07:db:10:2f:19:8c:35:50:60:d1:0b:f4:37 +# SHA1 Fingerprint: d8:eb:6b:41:51:92:59:e0:f3:e7:85:00:c0:3d:b6:88:97:c9:ee:fc +# SHA256 Fingerprint: 3c:4f:b0:b9:5a:b8:b3:00:32:f4:32:b8:6f:53:5f:e1:72:c1:85:d0:fd:39:86:58:37:cf:36:18:7f:a6:f4:28 +-----BEGIN CERTIFICATE----- +MIIFdDCCA1ygAwIBAgIEAJiiOTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEczMB4XDTEzMTExNDExMjg0MloX +DTI4MTExMzIzMDAwMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl +ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv +b3QgQ0EgLSBHMzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL4yolQP +cPssXFnrbMSkUeiFKrPMSjTysF/zDsccPVMeiAho2G89rcKezIJnByeHaHE6n3WW +IkYFsO2tx1ueKt6c/DrGlaf1F2cY5y9JCAxcz+bMNO14+1Cx3Gsy8KL+tjzk7FqX +xz8ecAgwoNzFs21v0IJyEavSgWhZghe3eJJg+szeP4TrjTgzkApyI/o1zCZxMdFy +KJLZWyNtZrVtB0LrpjPOktvA9mxjeM3KTj215VKb8b475lRgsGYeCasH/lSJEULR +9yS6YHgamPfJEf0WwTUaVHXvQ9Plrk7O53vDxk5hUUurmkVLoR9BvUhTFXFkC4az +5S6+zqQbwSmEorXLCCN2QyIkHxcE1G6cxvx/K2Ya7Irl1s9N9WMJtxU51nus6+N8 +6U78dULI7ViVDAZCopz35HCz33JvWjdAidiFpNfxC95DGdRKWCyMijmev4SH8RY7 +Ngzp07TKbBlBUgmhHbBqv4LvcFEhMtwFdozL92TkA1CvjJFnq8Xy7ljY3r735zHP +bMk7ccHViLVlvMDoFxcHErVc0qsgk7TmgoNwNsXNo42ti+yjwUOH5kPiNL6VizXt +BznaqB16nzaeErAMZRKQFWDZJkBE41ZgpRDUajz9QdwOWke275dhdU/Z/seyHdTt +XUmzqWrLZoQT1Vyg3N9udwbRcXXIV2+vD3dbAgMBAAGjQjBAMA8GA1UdEwEB/wQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRUrfrHkleuyjWcLhL75Lpd +INyUVzANBgkqhkiG9w0BAQsFAAOCAgEAMJmdBTLIXg47mAE6iqTnB/d6+Oea31BD +U5cqPco8R5gu4RV78ZLzYdqQJRZlwJ9UXQ4DO1t3ApyEtg2YXzTdO2PCwyiBwpwp +LiniyMMB8jPqKqrMCQj3ZWfGzd/TtiunvczRDnBfuCPRy5FOCvTIeuXZYzbB1N/8 +Ipf3YF3qKS9Ysr1YvY2WTxB1v0h7PVGHoTx0IsL8B3+A3MSs/mrBcDCw6Y5p4ixp +gZQJut3+TcCDjJRYwEYgr5wfAvg1VUkvRtTA8KCWAg8zxXHzniN9lLf9OtMJgwYh +/WA9rjLA0u6NpvDntIJ8CsxwyXmA+P5M9zWEGYox+wrZ13+b8KKaa8MFSu1BYBQw +0aoRQm7TIwIEC8Zl3d1Sd9qBa7Ko+gE4uZbqKmxnl4mUnrzhVNXkanjvSr0rmj1A +fsbAddJu+2gw7OyLnflJNZoaLNmzlTnVHpL3prllL+U9bTpITAjc5CgSKL59NVzq +4BZ+Extq1z7XnvwtdbLBFNUjA9tbbws+eC8N3jONFrdI54OagQ97wUNNVQQXOEpR +1VmiiXTTn74eS9fGbbeIJG9gkaSChVtWQbzQRKtqE77RLFi3EjNYsjdj3BP1lB0/ +QFH1T/U67cjF68IeHRaVesd+QnGTbksVtzDfqu1XhUisHWrdOWnk4Xl4vs4Fv6EM +94B7IWcnMFk= +-----END CERTIFICATE----- + +# Issuer: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Subject: CN=Staat der Nederlanden EV Root CA O=Staat der Nederlanden +# Label: "Staat der Nederlanden EV Root CA" +# Serial: 10000013 +# MD5 Fingerprint: fc:06:af:7b:e8:1a:f1:9a:b4:e8:d2:70:1f:c0:f5:ba +# SHA1 Fingerprint: 76:e2:7e:c1:4f:db:82:c1:c0:a6:75:b5:05:be:3d:29:b4:ed:db:bb +# SHA256 Fingerprint: 4d:24:91:41:4c:fe:95:67:46:ec:4c:ef:a6:cf:6f:72:e2:8a:13:29:43:2f:9d:8a:90:7a:c4:cb:5d:ad:c1:5a +-----BEGIN CERTIFICATE----- +MIIFcDCCA1igAwIBAgIEAJiWjTANBgkqhkiG9w0BAQsFADBYMQswCQYDVQQGEwJO +TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSkwJwYDVQQDDCBTdGFh +dCBkZXIgTmVkZXJsYW5kZW4gRVYgUm9vdCBDQTAeFw0xMDEyMDgxMTE5MjlaFw0y +MjEyMDgxMTEwMjhaMFgxCzAJBgNVBAYTAk5MMR4wHAYDVQQKDBVTdGFhdCBkZXIg +TmVkZXJsYW5kZW4xKTAnBgNVBAMMIFN0YWF0IGRlciBOZWRlcmxhbmRlbiBFViBS +b290IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA48d+ifkkSzrS +M4M1LGns3Amk41GoJSt5uAg94JG6hIXGhaTK5skuU6TJJB79VWZxXSzFYGgEt9nC +UiY4iKTWO0Cmws0/zZiTs1QUWJZV1VD+hq2kY39ch/aO5ieSZxeSAgMs3NZmdO3d +Z//BYY1jTw+bbRcwJu+r0h8QoPnFfxZpgQNH7R5ojXKhTbImxrpsX23Wr9GxE46p +rfNeaXUmGD5BKyF/7otdBwadQ8QpCiv8Kj6GyzyDOvnJDdrFmeK8eEEzduG/L13l +pJhQDBXd4Pqcfzho0LKmeqfRMb1+ilgnQ7O6M5HTp5gVXJrm0w912fxBmJc+qiXb +j5IusHsMX/FjqTf5m3VpTCgmJdrV8hJwRVXj33NeN/UhbJCONVrJ0yPr08C+eKxC +KFhmpUZtcALXEPlLVPxdhkqHz3/KRawRWrUgUY0viEeXOcDPusBCAUCZSCELa6fS +/ZbV0b5GnUngC6agIk440ME8MLxwjyx1zNDFjFE7PZQIZCZhfbnDZY8UnCHQqv0X +cgOPvZuM5l5Tnrmd74K74bzickFbIZTTRTeU0d8JOV3nI6qaHcptqAqGhYqCvkIH +1vI4gnPah1vlPNOePqc7nvQDs/nxfRN0Av+7oeX6AHkcpmZBiFxgV6YuCcS6/ZrP +px9Aw7vMWgpVSzs4dlG4Y4uElBbmVvMCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFP6rAJCYniT8qcwaivsnuL8wbqg7 +MA0GCSqGSIb3DQEBCwUAA4ICAQDPdyxuVr5Os7aEAJSrR8kN0nbHhp8dB9O2tLsI +eK9p0gtJ3jPFrK3CiAJ9Brc1AsFgyb/E6JTe1NOpEyVa/m6irn0F3H3zbPB+po3u +2dfOWBfoqSmuc0iH55vKbimhZF8ZE/euBhD/UcabTVUlT5OZEAFTdfETzsemQUHS +v4ilf0X8rLiltTMMgsT7B/Zq5SWEXwbKwYY5EdtYzXc7LMJMD16a4/CrPmEbUCTC +wPTxGfARKbalGAKb12NMcIxHowNDXLldRqANb/9Zjr7dn3LDWyvfjFvO5QxGbJKy +CqNMVEIYFRIYvdr8unRu/8G2oGTYqV9Vrp9canaW2HNnh/tNf1zuacpzEPuKqf2e +vTY4SUmH9A4U8OmHuD+nT3pajnnUk+S7aFKErGzp85hwVXIy+TSrK0m1zSBi5Dp6 +Z2Orltxtrpfs/J92VoguZs9btsmksNcFuuEnL5O7Jiqik7Ab846+HUCjuTaPPoIa +Gl6I6lD4WeKDRikL40Rc4ZW2aZCaFG+XroHPaO+Zmr615+F/+PoTRxZMzG0IQOeL +eG9QgkRQP2YGiqtDhFZKDyAthg710tvSeopLzaXoTvFeJiUBWSOgftL2fiFX1ye8 +FVdMpEbB4IMeDExNH08GGeL5qPQ6gqGyeUN51q1veieQA6TqJIc/2b3Z6fJfUEkc +7uzXLg== +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Commercial Root CA 1 O=IdenTrust +# Label: "IdenTrust Commercial Root CA 1" +# Serial: 13298821034946342390520003877796839426 +# MD5 Fingerprint: b3:3e:77:73:75:ee:a0:d3:e3:7e:49:63:49:59:bb:c7 +# SHA1 Fingerprint: df:71:7e:aa:4a:d9:4e:c9:55:84:99:60:2d:48:de:5f:bc:f0:3a:25 +# SHA256 Fingerprint: 5d:56:49:9b:e4:d2:e0:8b:cf:ca:d0:8a:3e:38:72:3d:50:50:3b:de:70:69:48:e4:2f:55:60:30:19:e5:28:ae +-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBK +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVu +VHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQw +MTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MScw +JQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENBIDEwggIiMA0GCSqG +SIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ldhNlT +3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU ++ehcCuz/mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gp +S0l4PJNgiCL8mdo2yMKi1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1 +bVoE/c40yiTcdCMbXTMTEl3EASX2MN0CXZ/g1Ue9tOsbobtJSdifWwLziuQkkORi +T0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl3ZBWzvurpWCdxJ35UrCL +vYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzyNeVJSQjK +Vsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZK +dHzVWYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHT +c+XvvqDtMwt0viAgxGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hv +l7yTmvmcEpB4eoCHFddydJxVdHixuuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5N +iGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB +/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZIhvcNAQELBQAD +ggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH +6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwt +LRvM7Kqas6pgghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93 +nAbowacYXVKV7cndJZ5t+qntozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3 ++wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmVYjzlVYA211QC//G5Xc7UI2/YRYRK +W2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUXfeu+h1sXIFRRk0pT +AwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/rokTLq +l1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG +4iZZRHUe2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZ +mUlO+KWA2yUPHGNiiskzZ2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A +7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7RcGzM7vRX+Bi6hG6H +-----END CERTIFICATE----- + +# Issuer: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Subject: CN=IdenTrust Public Sector Root CA 1 O=IdenTrust +# Label: "IdenTrust Public Sector Root CA 1" +# Serial: 13298821034946342390521976156843933698 +# MD5 Fingerprint: 37:06:a5:b0:fc:89:9d:ba:f4:6b:8c:1a:64:cd:d5:ba +# SHA1 Fingerprint: ba:29:41:60:77:98:3f:f4:f3:ef:f2:31:05:3b:2e:ea:6d:4d:45:fd +# SHA256 Fingerprint: 30:d0:89:5a:9a:44:8a:26:20:91:63:55:22:d1:f5:20:10:b5:86:7a:ca:e1:2c:78:ef:95:8f:d4:f4:38:9f:2f +-----BEGIN CERTIFICATE----- +MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVu +VHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcN +MzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJVUzESMBAGA1UEChMJSWRlblRydXN0 +MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBSb290IENBIDEwggIi +MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTyP4o7 +ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGy +RBb06tD6Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlS +bdsHyo+1W/CD80/HLaXIrcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF +/YTLNiCBWS2ab21ISGHKTN9T0a9SvESfqy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R +3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoSmJxZZoY+rfGwyj4GD3vw +EUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFnol57plzy +9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9V +GxyhLrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ +2fjXctscvG29ZV/viDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsV +WaFHVCkugyhfHMKiq3IXAAaOReyL4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gD +W/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ +BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMwDQYJKoZIhvcN +AQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj +t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHV +DRDtfULAj+7AmgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9 +TaDKQGXSc3z1i9kKlT/YPyNtGtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8G +lwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFtm6/n6J91eEyrRjuazr8FGF1NFTwW +mhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMxNRF4eKLg6TCMf4Df +WN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4Mhn5 ++bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJ +tshquDDIajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhA +GaQdp/lLQzfcaFpPz+vCZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv +8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ3Wl9af0AVqW3rLatt8o+Ae+c +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - G2 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2009 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - G2" +# Serial: 1246989352 +# MD5 Fingerprint: 4b:e2:c9:91:96:65:0c:f4:0e:5a:93:92:a0:0a:fe:b2 +# SHA1 Fingerprint: 8c:f4:27:fd:79:0c:3a:d1:66:06:8d:e8:1e:57:ef:bb:93:22:72:d4 +# SHA256 Fingerprint: 43:df:57:74:b0:3e:7f:ef:5f:e4:0d:93:1a:7b:ed:f1:bb:2e:6b:42:73:8c:4e:6d:38:41:10:3d:3a:a7:f3:39 +-----BEGIN CERTIFICATE----- +MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMC +VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50 +cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3Qs +IEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVz +dCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwHhcNMDkwNzA3MTcy +NTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUVu +dHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwt +dGVybXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0 +aG9yaXplZCB1c2Ugb25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmlj +YXRpb24gQXV0aG9yaXR5IC0gRzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP/vaCeb9zYQYKpSfYs1/T +RU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXzHHfV1IWN +cCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hW +wcKUs/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1 +U1+cPvQXLOZprE4yTGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0 +jaWvYkxN4FisZDQSA/i2jZRjJKRxAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAP +BgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ60B7vfec7aVHUbI2fkBJmqzAN +BgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5ZiXMRrEPR9RP/ +jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ +Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v +1fN2D807iDginWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4R +nAuknZoh8/CbCzB428Hch0P+vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmH +VHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xOe4pIb4tF9g== +-----END CERTIFICATE----- + +# Issuer: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Subject: CN=Entrust Root Certification Authority - EC1 O=Entrust, Inc. OU=See www.entrust.net/legal-terms/(c) 2012 Entrust, Inc. - for authorized use only +# Label: "Entrust Root Certification Authority - EC1" +# Serial: 51543124481930649114116133369 +# MD5 Fingerprint: b6:7e:1d:f0:58:c5:49:6c:24:3b:3d:ed:98:18:ed:bc +# SHA1 Fingerprint: 20:d8:06:40:df:9b:25:f5:12:25:3a:11:ea:f7:59:8a:eb:14:b5:47 +# SHA256 Fingerprint: 02:ed:0e:b2:8c:14:da:45:16:5c:56:67:91:70:0d:64:51:d7:fb:56:f0:b2:ab:1d:3b:8e:b0:70:e5:6e:df:f5 +-----BEGIN CERTIFICATE----- +MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkG +A1UEBhMCVVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3 +d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVu +dHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25seTEzMDEGA1UEAxMq +RW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRUMxMB4XDTEy +MTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYwFAYD +VQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0 +L2xlZ2FsLXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0g +Zm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBD +ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEVDMTB2MBAGByqGSM49AgEGBSuBBAAi +A2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHyAsWfoPZb1YsGGYZPUxBt +ByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef9eNi1KlH +Bz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O +BBYEFLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVC +R98crlOZF7ZvHH3hvxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nX +hTcGtXsI/esni0qU+eH6p44mCOh8kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G +-----END CERTIFICATE----- + +# Issuer: CN=CFCA EV ROOT O=China Financial Certification Authority +# Subject: CN=CFCA EV ROOT O=China Financial Certification Authority +# Label: "CFCA EV ROOT" +# Serial: 407555286 +# MD5 Fingerprint: 74:e1:b6:ed:26:7a:7a:44:30:33:94:ab:7b:27:81:30 +# SHA1 Fingerprint: e2:b8:29:4b:55:84:ab:6b:58:c2:90:46:6c:ac:3f:b8:39:8f:84:83 +# SHA256 Fingerprint: 5c:c3:d7:8e:4e:1d:5e:45:54:7a:04:e6:87:3e:64:f9:0c:f9:53:6d:1c:cc:2e:f8:00:f3:55:c4:c5:fd:70:fd +-----BEGIN CERTIFICATE----- +MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkx +MjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5j +aWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNBIEVWIFJP +T1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnVBU03 +sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpL +TIpTUnrD7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5 +/ZOkVIBMUtRSqy5J35DNuF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp +7hZZLDRJGqgG16iI0gNyejLi6mhNbiyWZXvKWfry4t3uMCz7zEasxGPrb382KzRz +EpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7xzbh72fROdOXW3NiGUgt +hxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9fpy25IGvP +a931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqot +aK8KgWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNg +TnYGmE69g60dWIolhdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfV +PKPtl8MeNPo4+QgO48BdK4PRVmrJtqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hv +cWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAfBgNVHSMEGDAWgBTj/i39KNAL +tbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAd +BgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB +ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObT +ej/tUxPQ4i9qecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdL +jOztUmCypAbqTuv0axn96/Ua4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBS +ESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sGE5uPhnEFtC+NiWYzKXZUmhH4J/qy +P5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfXBDrDMlI1Dlb4pd19 +xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjnaH9d +Ci77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN +5mydLIhyPDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe +/v5WOaHIz16eGWRGENoXkbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+Z +AAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3CekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ +5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su +-----END CERTIFICATE----- + +# Issuer: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Subject: CN=Certinomis - Root CA O=Certinomis OU=0002 433998903 +# Label: "Certinomis - Root CA" +# Serial: 1 +# MD5 Fingerprint: 14:0a:fd:8d:a8:28:b5:38:69:db:56:7e:61:22:03:3f +# SHA1 Fingerprint: 9d:70:bb:01:a5:a4:a0:18:11:2e:f7:1c:01:b9:32:c5:34:e7:88:a8 +# SHA256 Fingerprint: 2a:99:f5:bc:11:74:b7:3c:bb:1d:62:08:84:e0:1c:34:e5:1c:cb:39:78:da:12:5f:0e:33:26:88:83:bf:41:58 +-----BEGIN CERTIFICATE----- +MIIFkjCCA3qgAwIBAgIBATANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJGUjET +MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxHTAb +BgNVBAMTFENlcnRpbm9taXMgLSBSb290IENBMB4XDTEzMTAyMTA5MTcxOFoXDTMz +MTAyMTA5MTcxOFowWjELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNlcnRpbm9taXMx +FzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMR0wGwYDVQQDExRDZXJ0aW5vbWlzIC0g +Um9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANTMCQosP5L2 +fxSeC5yaah1AMGT9qt8OHgZbn1CF6s2Nq0Nn3rD6foCWnoR4kkjW4znuzuRZWJfl +LieY6pOod5tK8O90gC3rMB+12ceAnGInkYjwSond3IjmFPnVAy//ldu9n+ws+hQV +WZUKxkd8aRi5pwP5ynapz8dvtF4F/u7BUrJ1Mofs7SlmO/NKFoL21prbcpjp3vDF +TKWrteoB4owuZH9kb/2jJZOLyKIOSY008B/sWEUuNKqEUL3nskoTuLAPrjhdsKkb +5nPJWqHZZkCqqU2mNAKthH6yI8H7KsZn9DS2sJVqM09xRLWtwHkziOC/7aOgFLSc +CbAK42C++PhmiM1b8XcF4LVzbsF9Ri6OSyemzTUK/eVNfaoqoynHWmgE6OXWk6Ri +wsXm9E/G+Z8ajYJJGYrKWUM66A0ywfRMEwNvbqY/kXPLynNvEiCL7sCCeN5LLsJJ +wx3tFvYk9CcbXFcx3FXuqB5vbKziRcxXV4p1VxngtViZSTYxPDMBbRZKzbgqg4SG +m/lg0h9tkQPTYKbVPZrdd5A9NaSfD171UkRpucC63M9933zZxKyGIjK8e2uR73r4 +F2iw4lNVYC2vPsKD2NkJK/DAZNuHi5HMkesE/Xa0lZrmFAYb1TQdvtj/dBxThZng +WVJKYe2InmtJiUZ+IFrZ50rlau7SZRFDAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIB +BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTvkUz1pcMw6C8I6tNxIqSSaHh0 +2TAfBgNVHSMEGDAWgBTvkUz1pcMw6C8I6tNxIqSSaHh02TANBgkqhkiG9w0BAQsF +AAOCAgEAfj1U2iJdGlg+O1QnurrMyOMaauo++RLrVl89UM7g6kgmJs95Vn6RHJk/ +0KGRHCwPT5iVWVO90CLYiF2cN/z7ZMF4jIuaYAnq1fohX9B0ZedQxb8uuQsLrbWw +F6YSjNRieOpWauwK0kDDPAUwPk2Ut59KA9N9J0u2/kTO+hkzGm2kQtHdzMjI1xZS +g081lLMSVX3l4kLr5JyTCcBMWwerx20RoFAXlCOotQqSD7J6wWAsOMwaplv/8gzj +qh8c3LigkyfeY+N/IZ865Z764BNqdeuWXGKRlI5nU7aJ+BIJy29SWwNyhlCVCNSN +h4YVH5Uk2KRvms6knZtt0rJ2BobGVgjF6wnaNsIbW0G+YSrjcOa4pvi2WsS9Iff/ +ql+hbHY5ZtbqTFXhADObE5hjyW/QASAJN1LnDE8+zbz1X5YnpyACleAu6AdBBR8V +btaw5BngDwKTACdyxYvRVB9dSsNAl35VpnzBMwQUAR1JIGkLGZOdblgi90AMRgwj +Y/M50n92Uaf0yKHxDHYiI0ZSKS3io0EHVmmY0gUJvGnHWmHNj4FgFU2A3ZDifcRQ +8ow7bkrHxuaAKzyBvBGAFhAn1/DNP3nMcyrDflOR1m749fPH0FFNjkulW+YZFzvW +gQncItzujrnEj1PhZ7szuIgVRs/taTX/dQ1G885x4cVrhkIGuUE= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GB CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GB CA" +# Serial: 157768595616588414422159278966750757568 +# MD5 Fingerprint: a4:eb:b9:61:28:2e:b7:2f:98:b0:35:26:90:99:51:1d +# SHA1 Fingerprint: 0f:f9:40:76:18:d3:d7:6a:4b:98:f0:a8:35:9e:0c:fd:27:ac:cc:ed +# SHA256 Fingerprint: 6b:9c:08:e8:6e:b0:f7:67:cf:ad:65:cd:98:b6:21:49:e5:49:4a:67:f5:84:5e:7b:d1:ed:01:9f:27:b8:6b:d6 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- + +# Issuer: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Subject: CN=SZAFIR ROOT CA2 O=Krajowa Izba Rozliczeniowa S.A. +# Label: "SZAFIR ROOT CA2" +# Serial: 357043034767186914217277344587386743377558296292 +# MD5 Fingerprint: 11:64:c1:89:b0:24:b1:8c:b1:07:7e:89:9e:51:9e:99 +# SHA1 Fingerprint: e2:52:fa:95:3f:ed:db:24:60:bd:6e:28:f3:9c:cc:cf:5e:b3:3f:de +# SHA256 Fingerprint: a1:33:9d:33:28:1a:0b:56:e5:57:d3:d3:2b:1c:e7:f9:36:7e:b0:94:bd:5f:a7:2a:7e:50:04:c8:de:d7:ca:fe +-----BEGIN CERTIFICATE----- +MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQEL +BQAwUTELMAkGA1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6 +ZW5pb3dhIFMuQS4xGDAWBgNVBAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkw +NzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJBgNVBAYTAlBMMSgwJgYDVQQKDB9L +cmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYDVQQDDA9TWkFGSVIg +Uk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5QqEvN +QLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT +3PSQ1hNKDJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw +3gAeqDRHu5rr/gsUvTaE2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr6 +3fE9biCloBK0TXC5ztdyO4mTp4CEHCdJckm1/zuVnsHMyAHs6A6KCpbns6aH5db5 +BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwiieDhZNRnvDF5YTy7ykHN +XGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsF +AAOCAQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw +8PRBEew/R40/cof5O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOG +nXkZ7/e7DDWQw4rtTw/1zBLZpD67oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCP +oky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul4+vJhaAlIDf7js4MNIThPIGy +d05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6+/NNIxuZMzSg +LvWpCz/UXeHPhJ/iGcJfitYgHuNztw== +-----END CERTIFICATE----- + +# Issuer: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Subject: CN=Certum Trusted Network CA 2 O=Unizeto Technologies S.A. OU=Certum Certification Authority +# Label: "Certum Trusted Network CA 2" +# Serial: 44979900017204383099463764357512596969 +# MD5 Fingerprint: 6d:46:9e:d9:25:6d:08:23:5b:5e:74:7d:1e:27:db:f2 +# SHA1 Fingerprint: d3:dd:48:3e:2b:bf:4c:05:e8:af:10:f5:fa:76:26:cf:d3:dc:30:92 +# SHA256 Fingerprint: b6:76:f2:ed:da:e8:77:5c:d3:6c:b0:f6:3c:d1:d4:60:39:61:f4:9e:62:65:ba:01:3a:2f:03:07:b6:d0:b8:04 +-----BEGIN CERTIFICATE----- +MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCB +gDELMAkGA1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMu +QS4xJzAlBgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIG +A1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMCIYDzIwMTExMDA2MDgz +OTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UEChMZ +VW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRp +ZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3 +b3JrIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWA +DGSdhhuWZGc/IjoedQF97/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn +0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+oCgCXhVqqndwpyeI1B+twTUrWwbNWuKFB +OJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40bRr5HMNUuctHFY9rnY3lE +fktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2puTRZCr+E +Sv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1m +o130GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02i +sx7QBlrd9pPPV3WZ9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOW +OZV7bIBaTxNyxtd9KXpEulKkKtVBRgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgez +Tv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pyehizKV/Ma5ciSixqClnrDvFAS +adgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vMBhBgu4M1t15n +3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMC +AQYwDQYJKoZIhvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQ +F/xlhMcQSZDe28cmk4gmb3DWAl45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTf +CVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuAL55MYIR4PSFk1vtBHxgP58l1cb29 +XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMoclm2q8KMZiYcdywm +djWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tMpkT/ +WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jb +AoJnwTnbw3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksq +P/ujmv5zMnHCnsZy4YpoJ/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Ko +b7a6bINDd82Kkhehnlt4Fj1F4jNy3eFmypnTycUm/Q1oBEauttmbjL4ZvrHG8hnj +XALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLXis7VmFxWlgPF7ncGNf/P +5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7zAYspsbi +DrW5viSP +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: ca:ff:e2:db:03:d9:cb:4b:e9:0f:ad:84:fd:7b:18:ce +# SHA1 Fingerprint: 01:0c:06:95:a6:98:19:14:ff:bf:5f:c6:b0:b6:95:ea:29:e9:12:a6 +# SHA256 Fingerprint: a0:40:92:9a:02:ce:53:b4:ac:f4:f2:ff:c6:98:1c:e4:49:6f:75:5e:6d:45:fe:0b:2a:69:2b:cd:52:52:3f:36 +-----BEGIN CERTIFICATE----- +MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1Ix +DzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5k +IFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMT +N0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9v +dENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAxMTIxWjCBpjELMAkG +A1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNh +ZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkx +QDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1 +dGlvbnMgUm9vdENBIDIwMTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC +AQDC+Kk/G4n8PDwEXT2QNrCROnk8ZlrvbTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA +4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+ehiGsxr/CL0BgzuNtFajT0 +AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+6PAQZe10 +4S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06C +ojXdFPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV +9Cz82XBST3i4vTwri5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrD +gfgXy5I2XdGj2HUb4Ysn6npIQf1FGQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6 +Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2fu/Z8VFRfS0myGlZYeCsargq +NhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9muiNX6hME6wGko +LfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc +Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVd +ctA4GGqd83EkVAswDQYJKoZIhvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0I +XtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+D1hYc2Ryx+hFjtyp8iY/xnmMsVMI +M4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrMd/K4kPFox/la/vot +9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+yd+2V +Z5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/ea +j8GsGsVn82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnh +X9izjFk0WaSrT2y7HxjbdavYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQ +l033DlZdwJVqwjbDG2jJ9SrcR5q+ss7FJej6A7na+RZukYT1HCjI/CbM1xyQVqdf +bzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVtJ94Cj8rDtSvK6evIIVM4 +pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGaJI7ZjnHK +e7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0 +vm9qp/UsQu0yrbYhnr68 +-----END CERTIFICATE----- + +# Issuer: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Subject: CN=Hellenic Academic and Research Institutions ECC RootCA 2015 O=Hellenic Academic and Research Institutions Cert. Authority +# Label: "Hellenic Academic and Research Institutions ECC RootCA 2015" +# Serial: 0 +# MD5 Fingerprint: 81:e5:b4:17:eb:c2:f5:e1:4b:0d:41:7b:49:92:fe:ef +# SHA1 Fingerprint: 9f:f1:71:8d:92:d5:9a:f3:7d:74:97:b4:bc:6f:84:68:0b:ba:b6:66 +# SHA256 Fingerprint: 44:b5:45:aa:8a:25:e6:5a:73:ca:15:dc:27:fc:36:d2:4c:1c:b9:95:3a:06:65:39:b1:15:82:dc:48:7b:48:33 +-----BEGIN CERTIFICATE----- +MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzAN +BgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl +c2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hl +bGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgRUNDIFJv +b3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEwMzcxMlowgaoxCzAJ +BgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmljIEFj +YWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5 +MUQwQgYDVQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0 +dXRpb25zIEVDQyBSb290Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKg +QehLgoRc4vgxEZmGZE4JJS+dQS8KrjVPdJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJa +jq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoKVlp8aQuqgAkkbH7BRqNC +MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFLQi +C4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaep +lSTAGiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7Sof +TUwJCA3sS61kFyjndc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR +-----END CERTIFICATE----- + +# Issuer: CN=ISRG Root X1 O=Internet Security Research Group +# Subject: CN=ISRG Root X1 O=Internet Security Research Group +# Label: "ISRG Root X1" +# Serial: 172886928669790476064670243504169061120 +# MD5 Fingerprint: 0c:d2:f9:e0:da:17:73:e9:ed:86:4d:a5:e3:70:e7:4e +# SHA1 Fingerprint: ca:bd:2a:79:a1:07:6a:31:f2:1d:25:36:35:cb:03:9d:43:29:a5:e8 +# SHA256 Fingerprint: 96:bc:ec:06:26:49:76:f3:74:60:77:9a:cf:28:c5:a7:cf:e8:a3:c0:aa:e1:1a:8f:fc:ee:05:c0:bd:df:08:c6 +-----BEGIN CERTIFICATE----- +MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw +TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh +cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 +WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu +ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY +MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc +h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+ +0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U +A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW +T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH +B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC +B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv +KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn +OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn +jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw +qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI +rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV +HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq +hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL +ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ +3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK +NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5 +ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur +TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC +jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc +oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq +4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA +mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d +emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc= +-----END CERTIFICATE----- + +# Issuer: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Subject: O=FNMT-RCM OU=AC RAIZ FNMT-RCM +# Label: "AC RAIZ FNMT-RCM" +# Serial: 485876308206448804701554682760554759 +# MD5 Fingerprint: e2:09:04:b4:d3:bd:d1:a0:14:fd:1a:d2:47:c4:57:1d +# SHA1 Fingerprint: ec:50:35:07:b2:15:c4:95:62:19:e2:a8:9a:5b:42:99:2c:4c:2c:20 +# SHA256 Fingerprint: eb:c5:57:0c:29:01:8c:4d:67:b1:aa:12:7b:af:12:f7:03:b4:61:1e:bc:17:b7:da:b5:57:38:94:17:9b:93:fa +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsx +CzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJ +WiBGTk1ULVJDTTAeFw0wODEwMjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJ +BgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBG +Tk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALpxgHpMhm5/ +yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcfqQgf +BBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAz +WHFctPVrbtQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxF +tBDXaEAUwED653cXeuYLj2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z +374jNUUeAlz+taibmSXaXvMiwzn15Cou08YfxGyqxRxqAQVKL9LFwag0Jl1mpdIC +IfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mwWsXmo8RZZUc1g16p6DUL +mbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnTtOmlcYF7 +wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peS +MKGJ47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2 +ZSysV4999AeU14ECll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMet +UqIJ5G+GR4of6ygnXYMgrwTJbFaai0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUw +AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPd9xf3E6Jobd2Sn9R2gzL+H +YJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3 +LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD +nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1 +RXxlDPiyN8+sD8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYM +LVN0V2Ue1bLdI4E7pWYjJ2cJj+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf +77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrTQfv6MooqtyuGC2mDOL7Nii4LcK2N +JpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW+YJF1DngoABd15jm +fZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7Ixjp +6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp +1txyM/1d8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B +9kiABdcPUXmsEKvU7ANm5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wok +RqEIr9baRRmW1FMdW4R58MD3R++Lj8UGrp1MYp3/RgT408m2ECVAdf4WqslKYIYv +uu8wd+RU4riEmViAqhOLUTpPSPaLtrM= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 1 O=Amazon +# Subject: CN=Amazon Root CA 1 O=Amazon +# Label: "Amazon Root CA 1" +# Serial: 143266978916655856878034712317230054538369994 +# MD5 Fingerprint: 43:c6:bf:ae:ec:fe:ad:2f:18:c6:88:68:30:fc:c8:e6 +# SHA1 Fingerprint: 8d:a7:f9:65:ec:5e:fc:37:91:0f:1c:6e:59:fd:c1:cc:6a:6e:de:16 +# SHA256 Fingerprint: 8e:cd:e6:88:4f:3d:87:b1:12:5b:a3:1a:c3:fc:b1:3d:70:16:de:7f:57:cc:90:4f:e1:cb:97:c6:ae:98:19:6e +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj +ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM +9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw +IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6 +VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L +93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm +jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC +AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA +A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI +U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs +N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv +o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU +5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy +rqXRfboQnoZsG4q5WTP468SQvvG5 +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 2 O=Amazon +# Subject: CN=Amazon Root CA 2 O=Amazon +# Label: "Amazon Root CA 2" +# Serial: 143266982885963551818349160658925006970653239 +# MD5 Fingerprint: c8:e5:8d:ce:a8:42:e2:7a:c0:2a:5c:7c:9e:26:bf:66 +# SHA1 Fingerprint: 5a:8c:ef:45:d7:a6:98:59:76:7a:8c:8b:44:96:b5:78:cf:47:4b:1a +# SHA256 Fingerprint: 1b:a5:b2:aa:8c:65:40:1a:82:96:01:18:f8:0b:ec:4f:62:30:4d:83:ce:c4:71:3a:19:c3:9c:01:1e:a4:6d:b4 +-----BEGIN CERTIFICATE----- +MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwF +ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6 +b24gUm9vdCBDQSAyMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTEL +MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv +b3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK2Wny2cSkxK +gXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4kHbZ +W0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg +1dKmSYXpN+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K +8nu+NQWpEjTj82R0Yiw9AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r +2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvdfLC6HM783k81ds8P+HgfajZRRidhW+me +z/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAExkv8LV/SasrlX6avvDXbR +8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSSbtqDT6Zj +mUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz +7Mt0Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6 ++XUyo05f7O0oYtlNc/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI +0u1ufm8/0i2BWSlmy5A5lREedCf+3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSwDPBMMPQFWAJI/TPlUq9LhONm +UjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oAA7CXDpO8Wqj2 +LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY ++gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kS +k5Nrp+gvU5LEYFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl +7uxMMne0nxrpS10gxdr9HIcWxkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygm +btmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQgj9sAq+uEjonljYE1x2igGOpm/Hl +urR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbWaQbLU8uz/mtBzUF+ +fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoVYh63 +n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE +76KlXIx3KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H +9jVlpNMKVv/1F2Rs76giJUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT +4PsJYGw= +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 3 O=Amazon +# Subject: CN=Amazon Root CA 3 O=Amazon +# Label: "Amazon Root CA 3" +# Serial: 143266986699090766294700635381230934788665930 +# MD5 Fingerprint: a0:d4:ef:0b:f7:b5:d8:49:95:2a:ec:f5:c4:fc:81:87 +# SHA1 Fingerprint: 0d:44:dd:8c:3c:8c:1a:1a:58:75:64:81:e9:0f:2e:2a:ff:b3:d2:6e +# SHA256 Fingerprint: 18:ce:6c:fe:7b:f1:4e:60:b2:e3:47:b8:df:e8:68:cb:31:d0:2e:bb:3a:da:27:15:69:f5:03:43:b4:6d:b3:a4 +-----BEGIN CERTIFICATE----- +MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSAzMB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZBf8ANm+gBG1bG8lKl +ui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjrZt6j +QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSr +ttvXBp43rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkr +BqWTrBqYaGFy+uGh0PsceGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteM +YyRIHN8wfdVoOw== +-----END CERTIFICATE----- + +# Issuer: CN=Amazon Root CA 4 O=Amazon +# Subject: CN=Amazon Root CA 4 O=Amazon +# Label: "Amazon Root CA 4" +# Serial: 143266989758080763974105200630763877849284878 +# MD5 Fingerprint: 89:bc:27:d5:eb:17:8d:06:6a:69:d5:fd:89:47:b4:cd +# SHA1 Fingerprint: f6:10:84:07:d6:f8:bb:67:98:0c:c2:e2:44:c2:eb:ae:1c:ef:63:be +# SHA256 Fingerprint: e3:5d:28:41:9e:d0:20:25:cf:a6:90:38:cd:62:39:62:45:8d:a5:c6:95:fb:de:a3:c2:2b:0b:fb:25:89:70:92 +-----BEGIN CERTIFICATE----- +MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5 +MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24g +Um9vdCBDQSA0MB4XDTE1MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkG +A1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJvb3Qg +Q0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN/sGKe0uoe0ZLY7Bi +9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri83Bk +M6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB +/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WB +MAoGCCqGSM49BAMDA2gAMGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlw +CkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1AE47xDqUEpHJWEadIRNyp4iciuRMStuW +1KyLa2tJElMzrdfkviT8tQp21KW8EA== +-----END CERTIFICATE----- + +# Issuer: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Subject: CN=LuxTrust Global Root 2 O=LuxTrust S.A. +# Label: "LuxTrust Global Root 2" +# Serial: 59914338225734147123941058376788110305822489521 +# MD5 Fingerprint: b2:e1:09:00:61:af:f7:f1:91:6f:c4:ad:8d:5e:3b:7c +# SHA1 Fingerprint: 1e:0e:56:19:0a:d1:8b:25:98:b2:04:44:ff:66:8a:04:17:99:5f:3f +# SHA256 Fingerprint: 54:45:5f:71:29:c2:0b:14:47:c4:18:f9:97:16:8f:24:c5:8f:c5:02:3b:f5:da:5b:e2:eb:6e:1d:d8:90:2e:d5 +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- + +# Issuer: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Subject: CN=TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 O=Turkiye Bilimsel ve Teknolojik Arastirma Kurumu - TUBITAK OU=Kamu Sertifikasyon Merkezi - Kamu SM +# Label: "TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1" +# Serial: 1 +# MD5 Fingerprint: dc:00:81:dc:69:2f:3e:2f:b0:3b:f6:3d:5a:91:8e:49 +# SHA1 Fingerprint: 31:43:64:9b:ec:ce:27:ec:ed:3a:3f:0b:8f:0d:e4:e8:91:dd:ee:ca +# SHA256 Fingerprint: 46:ed:c3:68:90:46:d5:3a:45:3f:b3:10:4a:b8:0d:ca:ec:65:8b:26:60:ea:16:29:dd:7e:86:79:90:64:87:16 +-----BEGIN CERTIFICATE----- +MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIx +GDAWBgNVBAcTD0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxp +bXNlbCB2ZSBUZWtub2xvamlrIEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0w +KwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24gTWVya2V6aSAtIEthbXUgU00xNjA0 +BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRpZmlrYXNpIC0gU3Vy +dW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYDVQQG +EwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXll +IEJpbGltc2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklU +QUsxLTArBgNVBAsTJEthbXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBT +TTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11IFNNIFNTTCBLb2sgU2VydGlmaWthc2kg +LSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr3UwM6q7 +a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y86Ij5iySr +LqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INr +N3wcwv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2X +YacQuFWQfw4tJzh03+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/ +iSIzL+aFCr2lqBs23tPcLG07xxO9WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4f +AJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQUZT/HiobGPN08VFw1+DrtUgxH +V8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh +AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPf +IPP54+M638yclNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4 +lzwDGrpDxpa5RXI4s6ehlj2Re37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c +8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0jq5Rm+K37DwhuJi1/FwcJsoz7UMCf +lo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= +-----END CERTIFICATE----- + +# Issuer: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Subject: CN=GDCA TrustAUTH R5 ROOT O=GUANG DONG CERTIFICATE AUTHORITY CO.,LTD. +# Label: "GDCA TrustAUTH R5 ROOT" +# Serial: 9009899650740120186 +# MD5 Fingerprint: 63:cc:d9:3d:34:35:5c:6f:53:a3:e2:08:70:48:1f:b4 +# SHA1 Fingerprint: 0f:36:38:5b:81:1a:25:c3:9b:31:4e:83:ca:e9:34:66:70:cc:74:b4 +# SHA256 Fingerprint: bf:ff:8f:d0:44:33:48:7d:6a:8a:a6:0c:1a:29:76:7a:9f:c2:bb:b0:5e:42:0f:71:3a:13:b9:92:89:1d:38:93 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UE +BhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ +IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0 +MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVowYjELMAkGA1UEBhMCQ04xMjAwBgNV +BAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8w +HQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0BAQEF +AAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJj +Dp6L3TQsAlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBj +TnnEt1u9ol2x8kECK62pOqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+u +KU49tm7srsHwJ5uu4/Ts765/94Y9cnrrpftZTqfrlYwiOXnhLQiPzLyRuEH3FMEj +qcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ9Cy5WmYqsBebnh52nUpm +MUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQxXABZG12 +ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloP +zgsMR6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3Gk +L30SgLdTMEZeS1SZD2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeC +jGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4oR24qoAATILnsn8JuLwwoC8N9VKejveSswoA +HQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx9hoh49pwBiFYFIeFd3mqgnkC +AwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlRMA8GA1UdEwEB +/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg +p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZm +DRd9FBUb1Ov9H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5 +COmSdI31R9KrO9b7eGZONn356ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ry +L3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd+PwyvzeG5LuOmCd+uh8W4XAR8gPf +JWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQHtZa37dG/OaG+svg +IHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBDF8Io +2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV +09tL7ECQ8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQ +XR4EzzffHqhmsYzmIGrv/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrq +T8p+ck0LcIymSLumoRT2+1hEmRSuqguTaaApJUqlyyvdimYHFngVV3Eb7PVHhPOe +MTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-1" +# Serial: 15752444095811006489 +# MD5 Fingerprint: 6e:85:f1:dc:1a:00:d3:22:d5:b2:b2:ac:6b:37:05:45 +# SHA1 Fingerprint: ff:bd:cd:e7:82:c8:43:5e:3c:6f:26:86:5c:ca:a8:3a:45:5b:c3:0a +# SHA256 Fingerprint: d4:0e:9c:86:cd:8f:e4:68:c1:77:69:59:f4:9e:a7:74:fa:54:86:84:b6:c4:06:f3:90:92:61:f4:dc:e2:57:5c +-----BEGIN CERTIFICATE----- +MIIEMDCCAxigAwIBAgIJANqb7HHzA7AZMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRydXN0Q29y +IFJvb3RDZXJ0IENBLTEwHhcNMTYwMjA0MTIzMjE2WhcNMjkxMjMxMTcyMzE2WjCB +pDELMAkGA1UEBhMCUEExDzANBgNVBAgMBlBhbmFtYTEUMBIGA1UEBwwLUGFuYW1h +IENpdHkxJDAiBgNVBAoMG1RydXN0Q29yIFN5c3RlbXMgUy4gZGUgUi5MLjEnMCUG +A1UECwweVHJ1c3RDb3IgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYDVQQDDBZU +cnVzdENvciBSb290Q2VydCBDQS0xMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAv463leLCJhJrMxnHQFgKq1mqjQCj/IDHUHuO1CAmujIS2CNUSSUQIpid +RtLByZ5OGy4sDjjzGiVoHKZaBeYei0i/mJZ0PmnK6bV4pQa81QBeCQryJ3pS/C3V +seq0iWEk8xoT26nPUu0MJLq5nux+AHT6k61sKZKuUbS701e/s/OojZz0JEsq1pme +9J7+wH5COucLlVPat2gOkEz7cD+PSiyU8ybdY2mplNgQTsVHCJCZGxdNuWxu72CV +EY4hgLW9oHPY0LJ3xEXqWib7ZnZ2+AYfYW0PVcWDtxBWcgYHpfOxGgMFZA6dWorW +hnAbJN7+KIor0Gqw/Hqi3LJ5DotlDwIDAQABo2MwYTAdBgNVHQ4EFgQU7mtJPHo/ +DeOxCbeKyKsZn3MzUOcwHwYDVR0jBBgwFoAU7mtJPHo/DeOxCbeKyKsZn3MzUOcw +DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD +ggEBACUY1JGPE+6PHh0RU9otRCkZoB5rMZ5NDp6tPVxBb5UrJKF5mDo4Nvu7Zp5I +/5CQ7z3UuJu0h3U/IJvOcs+hVcFNZKIZBqEHMwwLKeXx6quj7LUKdJDHfXLy11yf +ke+Ri7fc7Waiz45mO7yfOgLgJ90WmMCV1Aqk5IGadZQ1nJBfiDcGrVmVCrDRZ9MZ +yonnMlo2HD6CqFqTvsbQZJG2z9m2GM/bftJlo6bEjhcxwft+dtvTheNYsnd6djts +L1Ac59v2Z3kf9YKVmgenFK+P3CghZwnS1k1aHBkcjndcw5QkPTJrS37UeJSDvjdN +zl/HHk484IkzlQsPpTLWPFp5LBk= +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor RootCert CA-2 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor RootCert CA-2" +# Serial: 2711694510199101698 +# MD5 Fingerprint: a2:e1:f8:18:0b:ba:45:d5:c7:41:2a:bb:37:52:45:64 +# SHA1 Fingerprint: b8:be:6d:cb:56:f1:55:b9:63:d4:12:ca:4e:06:34:c7:94:b2:1c:c0 +# SHA256 Fingerprint: 07:53:e9:40:37:8c:1b:d5:e3:83:6e:39:5d:ae:a5:cb:83:9e:50:46:f1:bd:0e:ae:19:51:cf:10:fe:c7:c9:65 +-----BEGIN CERTIFICATE----- +MIIGLzCCBBegAwIBAgIIJaHfyjPLWQIwDQYJKoZIhvcNAQELBQAwgaQxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEfMB0GA1UEAwwWVHJ1c3RDb3Ig +Um9vdENlcnQgQ0EtMjAeFw0xNjAyMDQxMjMyMjNaFw0zNDEyMzExNzI2MzlaMIGk +MQswCQYDVQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEg +Q2l0eTEkMCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYD +VQQLDB5UcnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgNVBAMMFlRy +dXN0Q29yIFJvb3RDZXJ0IENBLTIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQCnIG7CKqJiJJWQdsg4foDSq8GbZQWU9MEKENUCrO2fk8eHyLAnK0IMPQo+ +QVqedd2NyuCb7GgypGmSaIwLgQ5WoD4a3SwlFIIvl9NkRvRUqdw6VC0xK5mC8tkq +1+9xALgxpL56JAfDQiDyitSSBBtlVkxs1Pu2YVpHI7TYabS3OtB0PAx1oYxOdqHp +2yqlO/rOsP9+aij9JxzIsekp8VduZLTQwRVtDr4uDkbIXvRR/u8OYzo7cbrPb1nK +DOObXUm4TOJXsZiKQlecdu/vvdFoqNL0Cbt3Nb4lggjEFixEIFapRBF37120Hape +az6LMvYHL1cEksr1/p3C6eizjkxLAjHZ5DxIgif3GIJ2SDpxsROhOdUuxTTCHWKF +3wP+TfSvPd9cW436cOGlfifHhi5qjxLGhF5DUVCcGZt45vz27Ud+ez1m7xMTiF88 +oWP7+ayHNZ/zgp6kPwqcMWmLmaSISo5uZk3vFsQPeSghYA2FFn3XVDjxklb9tTNM +g9zXEJ9L/cb4Qr26fHMC4P99zVvh1Kxhe1fVSntb1IVYJ12/+CtgrKAmrhQhJ8Z3 +mjOAPF5GP/fDsaOGM8boXg25NSyqRsGFAnWAoOsk+xWq5Gd/bnc/9ASKL3x74xdh +8N0JqSDIvgmk0H5Ew7IwSjiqqewYmgeCK9u4nBit2uBGF6zPXQIDAQABo2MwYTAd +BgNVHQ4EFgQU2f4hQG6UnrybPZx9mCAZ5YwwYrIwHwYDVR0jBBgwFoAU2f4hQG6U +nrybPZx9mCAZ5YwwYrIwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYw +DQYJKoZIhvcNAQELBQADggIBAJ5Fngw7tu/hOsh80QA9z+LqBrWyOrsGS2h60COX +dKcs8AjYeVrXWoSK2BKaG9l9XE1wxaX5q+WjiYndAfrs3fnpkpfbsEZC89NiqpX+ +MWcUaViQCqoL7jcjx1BRtPV+nuN79+TMQjItSQzL/0kMmx40/W5ulop5A7Zv2wnL +/V9lFDfhOPXzYRZY5LVtDQsEGz9QLX+zx3oaFoBg+Iof6Rsqxvm6ARppv9JYx1RX +CI/hOWB3S6xZhBqI8d3LT3jX5+EzLfzuQfogsL7L9ziUwOHQhQ+77Sxzq+3+knYa +ZH9bDTMJBzN7Bj8RpFxwPIXAz+OQqIN3+tvmxYxoZxBnpVIt8MSZj3+/0WvitUfW +2dCFmU2Umw9Lje4AWkcdEQOsQRivh7dvDDqPys/cA8GiCcjl/YBeyGBCARsaU1q7 +N6a3vLqE6R5sGtRk2tRD/pOLS/IseRYQ1JMLiI+h2IYURpFHmygk71dSTlxCnKr3 +Sewn6EAes6aJInKc9Q0ztFijMDvd1GpUk74aTfOTlPf8hAs/hCBcNANExdqtvArB +As8e5ZTZ845b2EzwnexhF7sUMlQMAimTHpKG9n/v55IFDlndmQguLvqcAFLTxWYp +5KeXRKQOKIETNcX2b2TmQcTVL8w0RSXPQQCWPUouwpaYT05KnJe32x+SMsj/D1Fu +1uwJ +-----END CERTIFICATE----- + +# Issuer: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Subject: CN=TrustCor ECA-1 O=TrustCor Systems S. de R.L. OU=TrustCor Certificate Authority +# Label: "TrustCor ECA-1" +# Serial: 9548242946988625984 +# MD5 Fingerprint: 27:92:23:1d:0a:f5:40:7c:e9:e6:6b:9d:d8:f5:e7:6c +# SHA1 Fingerprint: 58:d1:df:95:95:67:6b:63:c0:f0:5b:1c:17:4d:8b:84:0b:c8:78:bd +# SHA256 Fingerprint: 5a:88:5d:b1:9c:01:d9:12:c5:75:93:88:93:8c:af:bb:df:03:1a:b2:d4:8e:91:ee:15:58:9b:42:97:1d:03:9c +-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIJAISCLF8cYtBAMA0GCSqGSIb3DQEBCwUAMIGcMQswCQYD +VQQGEwJQQTEPMA0GA1UECAwGUGFuYW1hMRQwEgYDVQQHDAtQYW5hbWEgQ2l0eTEk +MCIGA1UECgwbVHJ1c3RDb3IgU3lzdGVtcyBTLiBkZSBSLkwuMScwJQYDVQQLDB5U +cnVzdENvciBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxFzAVBgNVBAMMDlRydXN0Q29y +IEVDQS0xMB4XDTE2MDIwNDEyMzIzM1oXDTI5MTIzMTE3MjgwN1owgZwxCzAJBgNV +BAYTAlBBMQ8wDQYDVQQIDAZQYW5hbWExFDASBgNVBAcMC1BhbmFtYSBDaXR5MSQw +IgYDVQQKDBtUcnVzdENvciBTeXN0ZW1zIFMuIGRlIFIuTC4xJzAlBgNVBAsMHlRy +dXN0Q29yIENlcnRpZmljYXRlIEF1dGhvcml0eTEXMBUGA1UEAwwOVHJ1c3RDb3Ig +RUNBLTEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPj+ARtZ+odnbb +3w9U73NjKYKtR8aja+3+XzP4Q1HpGjORMRegdMTUpwHmspI+ap3tDvl0mEDTPwOA +BoJA6LHip1GnHYMma6ve+heRK9jGrB6xnhkB1Zem6g23xFUfJ3zSCNV2HykVh0A5 +3ThFEXXQmqc04L/NyFIduUd+Dbi7xgz2c1cWWn5DkR9VOsZtRASqnKmcp0yJF4Ou +owReUoCLHhIlERnXDH19MURB6tuvsBzvgdAsxZohmz3tQjtQJvLsznFhBmIhVE5/ +wZ0+fyCMgMsq2JdiyIMzkX2woloPV+g7zPIlstR8L+xNxqE6FXrntl019fZISjZF +ZtS6mFjBAgMBAAGjYzBhMB0GA1UdDgQWBBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAf +BgNVHSMEGDAWgBREnkj1zG1I1KBLf/5ZJC+Dl5mahjAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAQEABT41XBVwm8nHc2Fv +civUwo/yQ10CzsSUuZQRg2dd4mdsdXa/uwyqNsatR5Nj3B5+1t4u/ukZMjgDfxT2 +AHMsWbEhBuH7rBiVDKP/mZb3Kyeb1STMHd3BOuCYRLDE5D53sXOpZCz2HAF8P11F +hcCF5yWPldwX8zyfGm6wyuMdKulMY/okYWLW2n62HGz1Ah3UKt1VkOsqEUc8Ll50 +soIipX1TH0XsJ5F95yIW6MBoNtjG8U+ARDL54dHRHareqKucBK+tIA5kmE2la8BI +WJZpTdwHjFGTot+fDz2LYLSCjaoITmJF4PkL0uDgPFveXHEnJcLmA4GLEFPjx1Wi +tJ/X5g== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority RSA O=SSL Corporation +# Label: "SSL.com Root Certification Authority RSA" +# Serial: 8875640296558310041 +# MD5 Fingerprint: 86:69:12:c0:70:f1:ec:ac:ac:c2:d5:bc:a5:5b:a1:29 +# SHA1 Fingerprint: b7:ab:33:08:d1:ea:44:77:ba:14:80:12:5a:6f:bd:a9:36:49:0c:bb +# SHA256 Fingerprint: 85:66:6a:56:2e:e0:be:5c:e9:25:c1:d8:89:0a:6f:76:a8:7e:c1:6d:4d:7d:5f:29:ea:74:19:cf:20:12:3b:69 +-----BEGIN CERTIFICATE----- +MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE +BhMCVVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQK +DA9TU0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYwMjEyMTczOTM5WhcNNDEwMjEyMTcz +OTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv +bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2R +xFdHaxh3a3by/ZPkPQ/CFp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aX +qhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcC +C52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/geoeOy3ZExqysdBP+lSgQ3 +6YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkpk8zruFvh +/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrF +YD3ZfBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93E +JNyAKoFBbZQ+yODJgUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVc +US4cK38acijnALXRdMbX5J+tB5O2UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8 +ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi81xtZPCvM8hnIk2snYxnP/Okm ++Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4sbE6x/c+cCbqi +M+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV +HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4G +A1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGV +cpNxJK1ok1iOMq8bs3AD/CUrdIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBc +Hadm47GUBwwyOabqG7B52B2ccETjit3E+ZUfijhDPwGFpUenPUayvOUiaPd7nNgs +PgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAslu1OJD7OAUN5F7kR/ +q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjqerQ0 +cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jr +a6x+3uxjMxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90I +H37hVZkLId6Tngr75qNJvTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/Y +K9f1JmzJBjSWFupwWRoyeXkLtoh/D1JIPb9s2KJELtFOt3JY04kTlf5Eq/jXixtu +nLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406ywKBjYZC6VWg3dGq2ktuf +oYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NIWuuA8ShY +Ic2wBlX7Jz9TkHCpBB5XJ7k= +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com Root Certification Authority ECC" +# Serial: 8495723813297216424 +# MD5 Fingerprint: 2e:da:e4:39:7f:9c:8f:37:d1:70:9f:26:17:51:3a:8e +# SHA1 Fingerprint: c3:19:7c:39:24:e6:54:af:1b:c4:ab:20:95:7a:e2:c3:0e:13:02:6a +# SHA256 Fingerprint: 34:17:bb:06:cc:60:07:da:1b:96:1c:92:0b:8a:b4:ce:3f:ad:82:0e:4a:a3:0b:9a:cb:c4:a7:4e:bd:ce:bc:65 +-----BEGIN CERTIFICATE----- +MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xMTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNDAzWhcNNDEwMjEyMTgxNDAz +WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hvdXN0 +b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNvbSBS +b290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB +BAAiA2IABEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI +7Z4INcgn64mMU1jrYor+8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPg +CemB+vNH06NjMGEwHQYDVR0OBBYEFILRhXMw5zUE044CkvvlpNHEIejNMA8GA1Ud +EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTTjgKS++Wk0cQh6M0wDgYD +VR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCWe+0F+S8T +kdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+ +gA0z5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority RSA R2 O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority RSA R2" +# Serial: 6248227494352943350 +# MD5 Fingerprint: e1:1e:31:58:1a:ae:54:53:02:f6:17:6a:11:7b:4d:95 +# SHA1 Fingerprint: 74:3a:f0:52:9b:d0:32:a0:f4:4a:83:cd:d4:ba:a9:7b:7c:2e:c4:9a +# SHA256 Fingerprint: 2e:7b:f1:6c:c2:24:85:a7:bb:e2:aa:86:96:75:07:61:b0:ae:39:be:3b:2f:e9:d0:cc:6d:4e:f7:34:91:42:5c +-----BEGIN CERTIFICATE----- +MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNV +BAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UE +CgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2Vy +dGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMB4XDTE3MDUzMTE4MTQzN1oXDTQy +MDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQIDAVUZXhhczEQMA4G +A1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYDVQQD +DC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvq +M0fNTPl9fb69LT3w23jhhqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssuf +OePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7wcXHswxzpY6IXFJ3vG2fThVUCAtZJycxa +4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTOZw+oz12WGQvE43LrrdF9 +HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+B6KjBSYR +aZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcA +b9ZhCBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQ +Gp8hLH94t2S42Oim9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQV +PWKchjgGAGYS5Fl2WlPAApiiECtoRHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMO +pgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+SlmJuwgUHfbSguPvuUCYHBBXtSu +UDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48+qvWBkofZ6aY +MBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV +HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa4 +9QaAJadz20ZpqJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBW +s47LCp1Jjr+kxJG7ZhcFUZh1++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5 +Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nxY/hoLVUE0fKNsKTPvDxeH3jnpaAg +cLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2GguDKBAdRUNf/ktUM +79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDzOFSz +/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXt +ll9ldDz7CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEm +Kf7GUmG6sXP/wwyc5WxqlD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKK +QbNmC1r7fSOl8hqw/96bg5Qu0T/fkreRrwU7ZcegbLHNYhLDkBvjJc40vG93drEQ +w/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1hlMYegouCRw2n5H9gooi +S9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX9hwJ1C07 +mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== +-----END CERTIFICATE----- + +# Issuer: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Subject: CN=SSL.com EV Root Certification Authority ECC O=SSL Corporation +# Label: "SSL.com EV Root Certification Authority ECC" +# Serial: 3182246526754555285 +# MD5 Fingerprint: 59:53:22:65:83:42:01:54:c0:ce:42:b9:5a:7c:f2:90 +# SHA1 Fingerprint: 4c:dd:51:a3:d1:f5:20:32:14:b0:c6:c5:32:23:03:91:c7:46:42:6d +# SHA256 Fingerprint: 22:a2:c1:f7:bd:ed:70:4c:c1:e7:01:b5:f4:08:c3:10:88:0f:e9:56:b5:de:2a:4a:44:f9:9c:87:3a:25:a7:c8 +-----BEGIN CERTIFICATE----- +MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMC +VVMxDjAMBgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9T +U0wgQ29ycG9yYXRpb24xNDAyBgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZp +Y2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEyMTgxNTIzWhcNNDEwMjEyMTgx +NTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAOBgNVBAcMB0hv +dXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NMLmNv +bSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMA +VIbc/R/fALhBYlzccBYy3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1Kthku +WnBaBu2+8KGwytAJKaNjMGEwHQYDVR0OBBYEFFvKXuXe0oGqzagtZFG22XKbl+ZP +MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe5d7SgarNqC1kUbbZcpuX +5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJN+vp1RPZ +ytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZg +h5Mmm7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== +-----END CERTIFICATE----- + +# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R6 +# Label: "GlobalSign Root CA - R6" +# Serial: 1417766617973444989252670301619537 +# MD5 Fingerprint: 4f:dd:07:e4:d4:22:64:39:1e:0c:37:42:ea:d1:c6:ae +# SHA1 Fingerprint: 80:94:64:0e:b5:a7:a1:ca:11:9c:1f:dd:d5:9f:81:02:63:a7:fb:d1 +# SHA256 Fingerprint: 2c:ab:ea:fe:37:d0:6c:a2:2a:ba:73:91:c0:03:3d:25:98:29:52:c4:53:64:73:49:76:3a:3a:b5:ad:6c:cf:69 +-----BEGIN CERTIFICATE----- +MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg +MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh +bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx +MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET +MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ +KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI +xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k +ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD +aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw +LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw +1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX +k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2 +SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h +bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n +WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY +rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce +MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD +AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu +bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN +nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt +Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61 +55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj +vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf +cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz +oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp +nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs +pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v +JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R +8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4 +5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= +-----END CERTIFICATE----- + +# Issuer: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Subject: CN=OISTE WISeKey Global Root GC CA O=WISeKey OU=OISTE Foundation Endorsed +# Label: "OISTE WISeKey Global Root GC CA" +# Serial: 44084345621038548146064804565436152554 +# MD5 Fingerprint: a9:d6:b9:2d:2f:93:64:f8:a5:69:ca:91:e9:68:07:23 +# SHA1 Fingerprint: e0:11:84:5e:34:de:be:88:81:b9:9c:f6:16:26:d1:96:1f:c3:b9:31 +# SHA256 Fingerprint: 85:60:f9:1c:36:24:da:ba:95:70:b5:fe:a0:db:e3:6f:f1:1a:83:23:be:94:86:85:4f:b3:f3:4a:55:71:19:8d +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- diff --git a/env/lib/python3.7/site-packages/pip/_vendor/certifi/core.py b/env/lib/python3.7/site-packages/pip/_vendor/certifi/core.py new file mode 100644 index 0000000..eab9d1d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/certifi/core.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +certifi.py +~~~~~~~~~~ + +This module returns the installation location of cacert.pem. +""" +import os +import warnings + + +class DeprecatedBundleWarning(DeprecationWarning): + """ + The weak security bundle is being deprecated. Please bother your service + provider to get them to stop using cross-signed roots. + """ + + +def where(): + f = os.path.dirname(__file__) + + return os.path.join(f, 'cacert.pem') + + +def old_where(): + warnings.warn( + "The weak security bundle has been removed. certifi.old_where() is now an alias " + "of certifi.where(). Please update your code to use certifi.where() instead. " + "certifi.old_where() will be removed in 2018.", + DeprecatedBundleWarning + ) + return where() + +if __name__ == '__main__': + print(where()) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py new file mode 100644 index 0000000..0f9f820 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__init__.py @@ -0,0 +1,39 @@ +######################## BEGIN LICENSE BLOCK ######################## +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +from .compat import PY2, PY3 +from .universaldetector import UniversalDetector +from .version import __version__, VERSION + + +def detect(byte_str): + """ + Detect the encoding of the given byte string. + + :param byte_str: The byte sequence to examine. + :type byte_str: ``bytes`` or ``bytearray`` + """ + if not isinstance(byte_str, bytearray): + if not isinstance(byte_str, bytes): + raise TypeError('Expected object of type bytes or bytearray, got: ' + '{0}'.format(type(byte_str))) + else: + byte_str = bytearray(byte_str) + detector = UniversalDetector() + detector.feed(byte_str) + return detector.close() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d388777c8de7078cf8b08b04617f8a4f6ada50c1 GIT binary patch literal 800 zcmYjPO^?$s5ViB&z@iooaP$dLiEUS~2UGz<Kqa^=h+U9~kdkcdcC$+2tmDFVX)l!j z!B(93OTKdAFK}Y)w7^I+nz83Szhvg=&Q6HHqHni9-1HFosf(>ykURlz9zdXo;sTX8 z!le~iSl3ozmrmrE+%DYGi@eg0e5f7jennA0y+hRZe_??4EoHxce@}<|eXM$KtNbGq zO<Fu>l4X($Xt)x``Yh*F94r6b_|4(VR|lC!Ytw36@Mqx73kVV|ki;vi*)y31*&S(9 zeCbGcfmV2pSNIFA0*Q6CMABQKC0^i5e}UE*Bgld^0)^Ja_mF_KQiwcZgjE@*c{L?` zV(KZVt;q3QGSWx^7lY71Ms+IE(p<!FG14^T2ngC%b~XbhMkFWfJT3Ez4O*C-*KN-~ z6iE^dYLbL-u_;m^(s_~?%*ForyoO)JDB;JakQi-So<@T--azh>DVHPid2iY8s4#Ex zs*x!OQJudn$~CX4&Jj?Ih2TPY6E4bBDo3jm4*X)}Oc<le%?jQym{6cGTCxi0W^O-_ z=t1Z2M?+cG!#b~b&0|Hen|+#Ar}AuH9~y`0R+Nijc9IH!592tmav8^idak^d@0K2J z7XtD_9AXb&vjT`A7B}GR0KUe{cv+`X=yeb_1l5~ucWJAs)$VVWN$9N+u-wRy7`gw2 Y>zX5YSaLcm*kk=nqkFsfD(>2U0BRoH?f?J) literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5freq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0d79d4d2ff71417f089bbf862af19612a3fbe35 GIT binary patch literal 27135 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/big5prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4717a20e70da3c503bea3a55af9291110cbfad7f GIT binary patch literal 1076 zcmah|OK%e~5VrS~O_a3IipPNyNJx=rb7^mgM-o&ak%E-l3d!26-E=GOCbb<<qTUjz zKZA1QFInQmiNC;!8E-<v1svJ_b|yRX&3v=nR;xi^C10L?{2meV10Oak0PqU7?!&<e zr;-#jp%k$vy~0m?hkY3oVG=qV$f&3#HA+qh4|%jAJQ8&2Co!)LNjv^YAyk{%`-7P@ zd3SC^?>tpQVLqtINGR~^^(H(o$3v4EF-WuXycA%4*v-es{ahQBk7g#Hl&{NF&ULQA z*Xq7KIcCEF8@%tod6z+gKg(YueFQ*|gmRL2*W`?H%Dq*b_#)sw4_0JJlMt|D3^=+b z0ZEW?%{DM~MK444xbVi<xb-tQ3^DYIEWI1=D>#jBf+ak&&_qiDckPPY#OUD!V$#!g z-G+KL6-q(RiH#Y{%iJ)gFrW(2R?l1?m@X9RVDIs*>RF2AFNCt85?UDOLZF2_gS*aH zCR42$`$m4f?3iNOndZ}jywoO@@*w*>E-%dG5gOfQpG3(gs*`~ZT$s)Xs+~G94ySV! zL+U56H3C9+XoJRdv47i=!wvPndV~Gx;cG~pQ>fWHwE@1RcEHl6stK3F)v*hYwuu~| z8dj!-XoE$2a1d|tU@PDDfBv7d*24kP;$LZFnU>>OIu-|8DYr}9_}eimh2$8s4aSNI zpGm|`#x7^6tURt~HijO8zGklOLR7U6hi$E;$%K@kHFjddtA!Yw;0EF`0F9Fo(`M8R zoDFAYw-~L<uM|?)AG=pg3g~M@QGGFPj_e($>DJg(lN3P|4P%94=0e{xsgM&ReqNRL N;t`TT`J2@J{NI3R0(t-d literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/chardistribution.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..33276bded664985f63e76bd5d90e572507ccd8eb GIT binary patch literal 6262 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 ZK4O1BF5tg!V@B&|W#%)Z>NlR5`Y+{q{zm`+ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetgroupprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1b7f8c2386ee11919eadcf213aae5f93c7744f7a GIT binary patch literal 2183 zcmb_d&2Jk;6rb6dU9TNGEg@|KL?T7y!xe3X6bX=^EwnV^fQy=xN><Ux@k|!G8-L8K zOKLU}QX=)ljRQB5BbWXo{0DnOoO<HUiQk)bk^<qz+VAa~kA3q#e(%kvjYf^(Y5)Az z!(Zna`<(_ykA!d&<lY6-O!Jg&^ET%s2WhY^+Jdt+riGUKOiLs7L|f``oi(H99G^6K zQUB5oH+zF*J?mr!<HoITI(FS;G;M4bn~onkjUIOo%&<1stR3k2r)-PsK#ToqTX-2K z?8j|sLLKSKKHKB%2y(2eUashxp4(^bSl4v}@9I+~S-S?C&J+u?!`JL^GAb=-bpwAW zWAqj?a_>OMSjKa<7xaUiYyJbd9pp@jgn>&<Jk$(|MGKD2rJX^dwt8u1>~m7tjEc}r zM#frltcaEB4SJbU#hmJNv)*H)29xcgGV+0N#e&*2E>p?GIH$_VW>83H(k&a3I$l(j z>ZTnmt6$ikYuB>v(X~-;bfq_NStm`ebiYjo{cOBSlb+OLGtfhOt&5OrlliwZSwh~I zCtMvpu`!fi1UV8IU*Hjb)7SnTs;fsHbSby=P{_zR3Y%+z9fj;5IAjPH!l%T})tvR^ zZT9u0U7mBhob%Z#!m7d?3i?8e_n}OQ@$v&;3tvS(u(D+%Xx*?LOch(fpp0f{4Lq?` znjriZQ5jP^he0#2bw4)?BexCO2Xr%ghS*uKw?U2s#^>R1ol73$y}+kSr?~EqJNBE* zA>VI-+zJ>xWNs;E2b}yaN8|xX{QwZ*t)}p{74wP7RChSo>S;6RnxanGfiG&%*+zkQ z%S%&F>|MkW@6lPlRD;M{D*5#FQ!IT^-Tz^*eHjNAF`;|XN&d^ibJ+CZDHfgvqa#(v zl}8XF^5Og*!p;r_4v-n_26^BX#&I6>xqFq~2Y}5X-xaxVmoXNZ=*vfey_r*O0#5x1 zVW-&&W@A7wP=Fyo7VF>x0$Gebu@;ZGjcFIYs+M1k;|G*5eBYF<J05c$e$ASPn0*PB z6>`fMZ7KOheCO`{)@}9qMw!?URhXF~YTeyXUwr1FSwzZDHf0IOc=JhSFlFrm6xbzV zKFcSmK99LiK<*M4^RNs6%YfGaP~udb#OJ|d(DcG7ARr@;lTY1)D#wTSCkSwoQ7vY? zA0SAJnj>U15*WRqfmbbd17C-7=OK27NX0!L^6TT(T=XON6=o|3v6dKB4+G9<{-Acq zcI9j(q!rLyE)OMYBFN<<W><5GlnMl0j#quSrTb9}oKIB}wUTFRzfBjP{c$7tZjr?O z8wm{d&$RKTTNw<qm9o;O=P<<oq?A@Z#<*E8!%7*l7l^$=jM~BrS&Y(Qk{DZr+H6h| zOZDY(ZVAWDuq;AKPf_(<nGW$eE2J0yku)li`yh82jQIpfq(<Ubb{0zES)?!K=Rvd< zfln`<lDfaQ2WlL1bazm9z}-<(YI~?BDam!E#*<E3uJ|_Y8(R^h?cv(Vo|Jx(OO{|& zR&rx@iF8exDs=)sv>x9jeS@TGTmd=iqcNY4>a}`YkK;w(eOt}22n}v8R~ABJ)^o~s cYw0%d`%aXX5~(iYk4guwFOz;csLt!+FS!@l_5c6? literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/charsetprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fc1a8d72428eb577a6c5bced19ca1024d860cac1 GIT binary patch literal 3393 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/codingstatemachine.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a7976551176a8ad5348e9a789e65d4b616e0076a GIT binary patch literal 2840 zcma)8%Wm676djU!S(eo_Y0(7fW4Z|<G?4?eK!BiV^K3SaTi8JsLIHy2j3l}gsmzS* zIB-_UH+0)%*<a$etNcP&J@-<SEL#ma!VEdDbMKsU?@;%*w%P(^@aMJP8eJj&rcPCA zc)5#eucJ{yd8rr(<*Oj|CjP+p#ABgqs{Tf(x(;3kgPQX8M6dB4tHsWH4{gsYI!~f_ zoMd{>MNY>wRh0lQcTw#_G+GQiB?i9o1_7CPBLK(XgSu*{Ci)H4QX6<SRa<T1+0q-T zqqg3N*WRG5x-k7waq&T}l5E7r=7ys`aE`V_xhE|-At$9r(&h3{n`C$_Be{Q!39Fya zbQWtl%nin-k#R{pOCuvO%D{d3Q*Ibc1Ek#L##$<k!#V6SI@Zadwl`$r<WZ8Qa;UYE zZXCJ!>Rf7Ah0WMuA!Dt&6&*%N8tte0hRicv?!xX!x@4mJ@+r)%ZivTGHqsUr?J2nZ z$ii@*(XgBveVF7kJKq^)<kB1)j#geXy3sO1{dS23=nVE(t@4p*VLrsP(?(lIltx%O zbNS7Rk~?h%+IxC$_h|`n2WLotY1xMo6&vwlh%-0F!HNG=kD_!{8HOS)7v*}=2Pu&} zjM79&sHEjIhd(_Q5!4tEt&JQ<R_<#JI+V^_GEB7Um!3U&RJk?xD^p2~I3f4IJMpx7 z@+AW7t_03m_ZR@@v{N0!WK8@J9=T<;qZq-g(l!}o5R1c(rHR~mC@@T`vs~uDFgT{Q z3BqI%obqU#ASh!f5a*eTAetkh$;Gp9Rj8BVSi+GC=TaRZGFZf9GSMobe1V~aVinTb zBN&F8XW{5jmEdz)AMNh`vRg4*3Vw>%4{-{O(xvuiP07_XWr~;SxjfCfqnyXe5MyV~ zR+6@ad|2f+lcZn7=?p<e%$|p<cFCd1C!~T!uozfC9`X=`L&ju%-WvP3`KZt{Kz)E} zZ=pHyPDF?s7p=#wuLRx$S9@D`jdwKOJP~hO?}Ue&8CRdbWB9_|C>r4eNst!ZFrFC` zlK3GMtojssVXCuYvz+J9E}CgR8sXwBHb&b0jCXB{Rv2c{M2BI~pjnL6k>lF+{Gw)c zIxKuU`Ae7!aQC0b+io)5o+i_qNe09;y%`^kvIF=0I~wE~9_mcxW}6&9sBD)PDx05Q z$o=Ut8BMaph2d?YqJu_wjrp(Ry}Ww<e(zU1Vj_SFJ&93flOUWpAjZHUnDTadfg!Ss zI^RjAh4-Fk@bxPX!zVHyQ+Er^kEoV~@?KtEW1cx#C`sSUg_2`*PQ(FpyaGk9h*v&( zp7Rfa-+gmSp%>P8KES+>D#ALg;IY~j@d-vh6R!g9*D+7)5D_P$CJt(<aT~{E1p4ka zcZ$t8jjRnFeLOfEif$!$IaqYc6+_&KxhXc8{rP%2Vy|K9crYc*k-0?O1~pBZuQ5%9 z7Z+^~EQTxE9BB+zl1DMY3>NK7zi=T>-N&H4h(-imuLDgl_+4tfuJ`hbHN-A=t|&|D zva;kAF;i;ll@6}evABe&=5WW=9}*=<fM2n_()HRJ^J})O__2sE`UAxZL1E6sqDFax zkRmSEM^<r};rTyB$xb*=g1u92ee+*#t=ac~eQTxovoMQBANJ3D1vj28T=CZ?UWK&N z+ccY4TeL&EduA!!8J#eEK8w=%4blulmB(RdNPkW%bCupcr{+uA+nSnus*O8l)2G5{ z5le=0>uXd?soMIq=CxX_pw&eUc&=AB8w6F?*=%CV9B<_N2l!{k^Xov1*7v2$KaeYy JOtkz?@GrVI`<4Iz literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7a4927eaa6a6bc814725c7eff880920deccd2ba7 GIT binary patch literal 311 zcmXwxzfQw25XSv4O<J`JLOcQ@Lx}`zAcPng5fUs|NKqPJAtkYc?H2Mh%)F9UroI9b z=OXTOzq|WB>ARlICIm}<9zJP7$aj4Hi{WvF<02GMv?Y=NSy9Dai9J$WG9@Gj0m+id z5hOCz`=~H<IAkDps*tIo_aslYm_lxIw&l1jMLgW(<G|hE!gK@HHAa_>UYfw~9#0}p z(eyT?Yu(gFLC6-BgEC5E4<EktLk}TY3?AGUvC|kE@pE4It}ptgpEuh1s%_`>`?Fs8 wx3ehjrrdy5#uoKUWfl0MHeFx&<9-O)MQ7Byh06nsa(jr3PpH7o=!pI8UlmSJWdHyG literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/cp949prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b55bc7be13484326f9bfc33765eb8ae14ad7c443 GIT binary patch literal 1083 zcmah|%We}f6t(9Srz9<uhd^Ql5>iClY_h3@pfs&ml$45y%?Qbwj@@*SXEL=NP@?Wq zsh>ev@=LR2#V@epUQYw*1{~Qwz8>GlxhK2r_6mU!e|`4xRfCWpcvy@8zz$5a2a6zr zDw5NfQpBF}azFMR_EnIFap-WMqP!6|D0xFfD547@A{oy8n2E-abl6V{t~#`OwEv-h z@P02dR%gc(n~jUtMWUuAGjO@yAB(IQ4Q*oOAW2WNLW1?dV4`fcJGHWZn&_dlM|ylL zHQcQBkG6Z;d^q5PcYFJ9QwZ^A_}9qv07w#3L1OQcoKQi9cfn#`2ErG?1)0-01nhDK z99@!t#F%rVy5;=W;ZiIB2kz(`r`dqT5=+m?+`IC=!KL+WFo!b_Z8RsaH_piw!y7@s zDLw2otI$kJsdWU8E5><NWR`P{4t0pOX6kt0Cf6RG?~5hAc!Gq@q^?3OjkLf+V5B;M zy~%m15@R_3PJZolZC-ZEtlZ2BV-uw|(=VgqlRfL9(M|qY7GkWsDex+!?WQHrSvq#N z%Bf}$`zcI=fY4RC;xjtCw?xX;BKaHaAVYn8hdL4zs`d`6&^^<uVCqoag3aN2S%YKM z!Ze^DUL?7E4i<yO6L0o#IpXq1|Bo6SjI~UPe}!c#DMpiIB)dx?Zxp%spu@0Rm>uWU z3g`J)Ocdf4=Vy~d)i;i|iUEz#V>{J%z^%RuOVz$^Pb!syej^o&#M+3F1t*Fp01T>w z(H3h3&W5_V?HaYDg<2l#wOpXdR_68J#)+v~%a5<=s++2@Ayouc1JXjNIoE$Psgdgj Sdr_D7@-ZfZ3TRRH^M3=6!vVkm literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/enums.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..525eaea71766088005984b7a30837fed55fd77df GIT binary patch literal 2574 zcmbVO+iu%N5T$Mu#n`#Hk1fyz+6EQS$UxC2Hz=$N?J$-pL!^s_2td)?wZw!Xm0dD{ z1@tNTk3RPg`Yrp~C;dY2Gb_oCW5-Ck!i;uyhr7cwvuD}a+%z?4{xA2R{;X@-?`W)B z6*{{hVgib4zP7K?5-q>cXqlB>SNt;A6<P(ms_Y8bHL8QHE4vDIof=>p%C3RkpeER+ zvURX;(G9RSlwGHruGYLg=Vm)eNOnr{2_sfoOa=79oP?Z_LNE#z&x-LRD{|!$O+rpt zPG({BJRGx@Y3_tYKFRnF>4hojBw?yt$k#MXTPJICcRUT_q!ne;rWwH-p0^V8c0t5v zpqS>D;N8o#<X33fuhNQNqg7w0HHcN0rk&1;+|9$B&0Ui~^Cqz%45B8S%{UV*%`tvP zXncCgIG9AByC5Mc()cCgB1{Ox&!RlzB!Y-f7>U!CT5SO#XbX&JQ3mBS>(U5<G@P;^ zkY*4}Gg>6r-w1*iMVPE+>OnxW2wjejhgQ&byS6PGmfKx-AKCklg3c4q`c>l_u&`2p z>}==L+4d}+J&02XGD#jpug2-K{Ka=Ts3dsFQkwDY73kaerlK`F;~1j>B2XEXY6*X8 z^b)xE7Q5*75Y+p@_3Kpk4O;gbtjcN~%{Q6J^p3{r(7#0u0KXw`_rr8tK+5;xBxij7 z>_Za(C7_-or|LmLUNHrHIGZJBB+p2wRvL|t*9q#a@-rGO^TI0-KF1TXPzqmqaTnF+ zpq%CgufacuBc<^=Ds+%r-AA@#xmMuXhev&T&$fE<ll7Q4Z1-%>9ysm3G#<B)+UP0u zgTc^hJF@N!oS^&oKvvrQzO1hvk`)-bNZ_)!iTm9Kbq_>rfikMgbgZ>eQuCJ*^D$Mw zam2HeI2|wRe*Z&ZKd<{4JkGAvI>*|$02XTfS`ZsO%d@(k?d(fqZ*c7N0^5_iGw^~# z>sly2g=GoI<;uj-{|~@n7)|1oEdg*o8UTd^nJyQ3_soAF4mH<n4?S74hQq;7>bB>; z4*)F5<`n>N^b!DA(!1#P4XB%rCNro`>u<EzCBLycid!ywQLr>({rEXc;z^d#`A;{) zlAL=Y*M|fdC5+%4lhZ6ovR6=FiZ_8oU&dJ>NR|S(BgMW0&;kRGuzs=OKS~!w;Mt@l zAdB*RXNR-A;HlUFie?083ri4oek+a$czK-h7|1zJ)#gZVEq(`<QKi)^$x4)nx5^9; zo7@_+JOIz&Vu9~*dn{<JGXLr-IIXKsI8F1~dN&+vzwOySTGBXn`u2g<e<JnOzi~8h zfiqz4R+NN7Oc~sJl;4MK--=NYykdnfVB%X4fkSJO239C@oQXir8)CQ%BEAH5Q#CA! z8Zb8Gz3w`P-6fJ|^WSbRf{RP>0y=U|&v3i3L_j@owaRGZLQy2FbCxsQNw6G=i1E>g zz%6`HL72WggAW0$mUeoU!&x1ZgbDQ}k&^Df@rHvwftxzYQV~<QmnjLsBZvB1-Ms(8 zdoTV$^*5@&Q2hzYX*RCSQv;~T+5>*?NwW`sK?jKYK<e(3!_J^DYdw1(h^oHY``Yy2 z!E1vo)1$BH8tze?ahk^R8qu?pXYjS4E>}h59LbF1fmV4`-q&p)jfcw*h9B^DQoB?u LcN=%_fPnrFdkAqw literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d12de97bfc4a9b6135a94eaba39fdd1010e2843 GIT binary patch literal 2561 zcma)7L2nyH6rR~#uh;h4NlhA3pz0DNBqQ3OiUUHZv?NaJwsE33P_zOK&d%7eyIwo9 z>o&2RQzCi+P8^X)j$HZ+_$6~goO<HUiT7r0w;>f`R`cfVyf^b^-uvF0FN(!Hf#(1E z{x{JaA%Eh}v{}I1h8}+ngcD9f(xX15$Qz;2GksI@W@z;?ex_&pb}#E^^_&$ty_}!x z<^6oG;1_zX?^1G?@C>(42)6}2HvJ;cHb}*JL1Fs}RmIi4rfi60OZIn#go*NMpLe2m zBWWgLqZ#aVB2h6_>0vW!51VbV-U$;Sm5cgQHRVne^`eTU3io{0*kBu*Yt@IUTx)FJ z{OIP*)%wM``&$?19&FF%0yyKWp<}ScUjY%sr=0i(r@qPOo{<*iCbv#<zNLA*u;XWh z&9mG&A;;9u0-xh~%{#on-4o*Hc#)T2%s(R*@eAOVc{N{+gL5t!{hs%r?d)}8@0`FJ z#v=Bb-g40A!i$4F(G$yFb1;y7aGTfaOOK001PQpw6A@?u6Mv|8d%7p2*gf<_Gwy_k zo)kg99d$;{-B5TU4w?hu!SZ;o(@MNp><?i%+L8iP!;auyKk|~k-m1ezlyq8$Ua}`* zSUoj#Lrd#{p`Atuj_5)YdVC5bAqgFmW20+~DW^XI!rEj^m^mh0E6H^2+eEGbZ=Plo zC&?YtGtij*=V$+@TL9hfW-|AjtO&C4Ojb%|94*ahI<M&^P0M3)`o<YSEJHAiI>50I z0`OQ%qpq@`GVyRAq%6SsmBUyk>LiS*T<TmF_oNFFiT4B`->cQDjVf!@Hntwt)@#)@ zWkYyG#3edGW|26k>fFDxbq9524u9<jo7>epb%{x;=9&<}Cj$0nL4Oz}>Jm%CDmV)u zcVdyK^2;eaF6N1{S&S*9G7`d)R19UsB5djN!L@RX1z|Ie8T*a=eQPD@4ORx7!SzlA zi^A}F@U$Iull_lzQg`+Qj@_3lXc5e>07w95kg+!ghq46c`~Z6V4iG}i)TS<-hYu-s zd-9F0{2Sdjrala?9$-V9pnEh<>cC8Ka%x~?4wf;NYvkLdBRZzBx4+0?WY(Cb^8Lj} zB*~!8F`$dtI<8qwok>)8Dmht%jdc{|5^_)k!R@K1l^KdiF5vWKB#S^QhP;A2>Q$(G z3;DN^;EnYbp8^w?fe>1PJ6qJyUT}eq7BAdd$7FV8ygK$(=&=n1j*kGO06={P7_@n9 za%NY#llZf!*%MV<tdq?cUA<uNRn7lrS6}<}cAY86YOmP57}}}U>+PYh@SZZyX#<`X z=y+$d-hO`fkI};Ozdmn+hHn4ug;HB2kQz}7D^VaeV2O4j0oPl`=-LHeoY$Wfs0=K` zuA}e^Fb6-6DFE$<BjezEJSp(wBXexZ^4RRsczGYjQ)6tL(IabYC1%%pY)B4pG#Nn8 zBHau(J^?&4gky%AkE#4AvAbD-r2{j$27w)LT^`nzK~m5X^VB`V@>B#XB^c+Xx{t`d z{Rn*qD=SugT_R>)K!<ljBU4@lUgaZkkfg~k5lkvm-QM2ZP7#e4RCaxHhiz2ln_8Nd z3A?t_fH~!?Z+=-{W3?T%l==x@jdVBGOP}L3Ej(D9=0-+?Q#reb36!ZsDjK8-<xa~Y z7NRs?UV_(Z3Ben%NxTe%&^%;K9<nA6pA9*brw)8bv6qa|<qLtt9WY5;EX9}uP>S=6 z_4<4mBJVP`KWv5*NtQ9*4;a(sO6RO{poT#?PY&fZyp4zCT_o3msN$qX1|ke$*(~{{ z1wiLMz69?<kFf|k8Otcmy9L*BEyvdNrCuqi;w1ahiYYNkReACrqid#q#geBoA{zE$ w{e(!2)+B}^4&Zf}JsJ9;&<{jf#b$?lS(cRZS?Y;fc+eOh8W()LK$on407h(O)&Kwi literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/escsm.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..418861b686a86b6305e092bd0e9c7a528fa2f71d GIT binary patch literal 7022 zcmeHLOK;jh5VpaXHwom?9HJ;{t17NUNoh}2RVAUQBmoiuC#w>2*(DEwp*HCwzok;o z{YTYad-7lCsXL2pjAMcvp&+GT?Rw|wnept$$_L40jH5sK=d+I~iR1nNVf{*Uu}6pg zJIHZ}Lwtwp@-okJC?E$ge;K4hKrlOp09=m|qCBr*=`tUPQ3&(|B(gb#LMC@86A-<a zWHf`mGX{Iz-jziZmcuwey@@!CA}EStKSVi#;&K$MSp4A0wsEc5Qz-AYyH{Rro^3yj z-sO>H?Bvm`S^iGmg!K*EDSE;7o*Y97IgX<!iDNj9Qf5^WXh}{|>*-a2YS|f0S-UGS ziMIU>-@oP6vtGmQurjyqwg=1ByjxFn%BR_YuBF3zqg|3yXjxvuNtDJZyo54nh4s=h zT9wmO+q-JcXFAtbOzyj_<DEBTG+rMwN6QZUjrDSSN6yeau!7UHqcV5}t)X=m_bPf+ z=cEmTr+ZxDNur{(&M#D4A1DL7!%?mV5`zv-qX;m+3Bs6f1anRQp+DRZtoLh#=*kFK zB<sJ$WNySoA?~{n2HSb8J6U6jv@s>|b|kuvmE`P)gKYlQ%RC7e08n)-i6q|YD7xMp zD4#l*B!)y=X$^WBiR*y4rYO}qSF~mat0pa|N*9wzM^VqNlrs~TA&}d{xEJYca5+5p zWNiGom#RGgIA{I0m^f`wgL%|Iiu&59MwBAVb^Ne?lFjet^Vvdmc)FbpijG>~jvLz# ziW**E>BYNaEWXSlHgMYjYK(X;SIeLb|DwKL-Gf#hb<Scn4;cB+(OZi7-(3cLEp$NX z(J6@>DSZVFxw8aS7kKz5{eY@A5kPHR^IxeMSu7CK=O4xbN*7QHr;IuEfdd<lYeYQm zX;@LK(i#b2^{T6D@NJ8TCAnEB*GZ_}*snE6s939=Q02o$y;&)e5S7*&Bn?WX{aUkJ ztTr3_2jwD(gQU`|oV+iVNs^vt;W%5UGGB=iNsTu~l*>nEB)Q@0=yc2#B^|CnI3AAW z3iRAj9oNQOQPSZGgx;<|&vf;R)1JeNgz4{_+@Raf^)LF_3zdE?>2$KKuV?Dz;PY!> zveEp4Rn*gR@cjhgK@RIJz5Am7okZStd+4fz-)&M)`Zqcyg2Iz6ew*Lo*Xi{*C<Fq$ abwx}WNVoY-I-X9DgA{ZoX>3vHxa~iI4SRV2 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/eucjpprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cfb6ac49804559108e05558db265e71b8414055c GIT binary patch literal 2369 zcmai0OK%%D5GMDfl`P4M^Rk1YaDgU(iYCq>D0&ErB(j<ZV%e}16kW7n*CH)T*<Hz8 zs<j2>Bp12%A5=Q@&|7~G554r1OMgHw?F?5E<f4z2NzM!(GyFIYKPi<81is+MJ74`& zCge9{7M}yeBWUS2&~d_PL}D7y*a|F)ycOB86F7#pBRBQ}&(Kbki~Ybiv>WB)LQpWY z7p=v`ph(G6!gJieAlw(u#12Y4-z3$-I|^#5mM$L1{!usSG*zgCF7AcxlWrmmSEc&K z-Y`<#C+AAkPD0rf3RepWGaI!&Uu>Ii0_j%$Rqe&WZZ}o3do)zte)2d8qw}<z!sInG zS?ecCoT(Lg*~nRQkL~U6)?c>4u;pjZsq_E{K?2H2V7(>Blv8e9_<?O`n>#=|!sRaa zF35xi9?<62K<9X#7cNNP^EF<CG5?l0Bq#t1CB0^JXSZr2B>3Toim{~+pi@NAF_~CX zYX+0bR?Y-?<|=POV9Y7sjQKH{7H|b8a5!yL*R-1s2SUm`9HM>3x=B|tCS72qkFtE* zz{t{AddOerE7-9R!5hK;9L`nR8FWjrcBM##0%)C7M8`1Z8EZ#jnlkn?`Qy=!iU&J` z?%-}WNmUp{ciZ1}lAbz!fI`#Qw<6(vxzmQ%<wEU<VY@dNm^Z#RIG1an_BOQCxGgQy z0`=iH%3d-<?cU;6{|w)Iu>CT8W74xTAQvz>63;gv$#tY4HUK|a$%ZQ^+Q9BAcDUkW zXemYv0i#A&Rvz)5f#i}c_?)%H22SB=tj5TLJ$GLmm~-c<G961rx`?O%zAOo2aUTz` zpd;33b5-B!qW@K^{TJaNOyJf2OR*n?NoN>#1p3}W=_Sk;3);paScM*iPGau)3EcSX zcY`{ez;Bm){p%YGaJQ!Rn2xP2GNW(oF}QKheQn7G%y`or2bb>o(DGwz26;vmdTZd^ z#RGC$Hfu|;mV>l>NxBYFkiglM8F}N3EpCD2modcW76eD{3b!BPxG}wo+}N2xJ_G97 zDi0d66<{5=HwpGP$@h4|>iU0~JuQDhK%X<$XBmCh!O|PAtskhoZ_d6sBN;v2oT2`$ z*ADWF`+(#+c!t{;eQ-P7hQBNdwokfh8v?K|w?nmk1c?yl-T}}=qFcTD6Ta##2t;@> zq3uW{vIufrNFc{Ch&m-CrV;Jd4-fYbwHNg}9U-;L#nG@Mui-&Au)~McUSq$-_UhWp zc53f=tBJh-`TncME_>e6ZnO3Hu%)kdz%AQDDMbP!xG5;s1qPv?u_l7Fb1VdxC8OS$ zqVv1;R=w7G-gv6lJAK7O(jRtC7!Osb%jV2}a@^%2X$!s4e71kss=aEl*0aMpFfVtj zu8B$QBM@Mt)U*p>GEZTqg7|0+LmW&XEu%@^0W&^@W)do)8&<_+lQQHJ$57Z~eks!m z%x+STZqkBPw#u{!65kqCR>KajwhT8!7@P6__kn=dBvT6hh(2u@%2LMnCsvl49Rrd4 z2o`4u*>QMQwX^%dl}wRhFdpmTJSQ9O@7KZuzJ!)y`X=TIqg$(nUPcv40+azvD2%~_ zvAEBN5z<A*PKRNX&6vb%5}o$J521pn^A%q~D2?U1G|%^K5k*i}mXJe6Gg;FlOe{Vh zLQByzeOk;F9sKzpn2g(~mbELAVVoKt%)E6yKAPvXEDR*(TD_6Iv~i_4`$xf)GN?>g yKUOMNR?NKKpq;3*ta^EHWC~>t%U+i1m)2%>qpjM1m?82R)(vBD1)hKYv;P8xe>`6R literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrfreq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3904c881debced12d2f85c8f4930de0610acd658 GIT binary patch literal 12019 zcmXxq1-KT}wuRwMw{%E%NGpm;Hwe-g7>Jac?zXWhl}05@Y^A$PLQ=X>T!4a765?I& zzW4e(erL=%#~gG0|Hi{PYTZnk(kH|}+RrHY<k>0-38xhQ|3|VYYR5kZWQpjU&_1Da zvi8Y3CvTs;bBZ<zWm0yF-S|hI+KH9YB_x!FkSR98D=;)7abT*56EP=oVd{uQ&{)|q zd9>_dS**7<mWksH%EFS^3y+!(60lVHoH7sJQz;|n!ZN#;sBa7|Q?~>xH&_8HVHFG( zH3U{G*TC9{Fh+7O0S)aIk<yo1$C82iJtE}bTd#M8Wdrp?iin{?H;Ssr@}}NZmQ5_1 zAyw>!e@uT;P8Iq9WMlq@+9F^e%OSn;Fii4S@oAx{!Mqq6-leum*#_I;XS;q%i7l*6 z_hEX&I@rOo6L!G{mh4c;$9mb?ZUNP)Dsd1-P@mY{V`DG;0{bA*U_aHLIzSzSLvR?z z7#yLF!ZA1wC*UMJ<^_-W<foLU;aB)AB0TN|@0!krlFV;GOE|;#I|TSqZ@zDQy}M`i zo>rcVD*Pqtyxt%1CtNeVKs{jNB6UW}U)0}l2`)n`FSx*0)DIxPyn(R{x2Y@95`LiG z7H|jiQ!qkV)uF2_*;%g18)5nnRgJn%4HEx14EHmyNZl|P>ChIt3q;-2+hAH1ZYe)^ zr~>?}ybTMPZ?j~9|MU{lL@Y8$MkR+7kP=eC2**=XX&|TFVm3w^JP)IkFHm1NIS}sG zOKYQpPn3>I4;dgMWP&2hcTkxj3v{rXm3oc($;pFKUUVay!ClH%?GA$Mde1NyRlZK; z&>N}DN#%l<1iUXVw=xfOWWJNi3;7^F6o7(I%e6vOYr93Du(G1~Ij~qt5xt^NgXLw{ zZkra<Tf$PDDgh;-6qJTCP|n&eC}r*0qz$;sbg@BMYLsbt<rXNX_lj%zm9J74sW<GF z^!j$nrOF*i4}#<{in+Xi3K5}{UsrhzUNh)wx1#9)>O+G{%Js^LLUZV4r*=bO_)qTv z*SbU%o)B8u+MCwCg<LG{nO}G4Q|dt*n@!))dlT-qb`KmfXaos-Z<*#3KTLcTmLpQ$ zXL;N7UcLLEDwK<ZFoby{-!dr!sQXR-iDmfN^a16Akl!Ph^SvOnnqC?k)v0O*&$HA} z)`VKnhq;Ww8ES@&+6I%UI#gX)#<Gv)Zg^Z-&!9fMDZV;1P&R}{&={IP3DbwDrqB!? zhUU-$^2X%wjE_~*@s@g5U8`ZYm2w5untI0z+E8twnsO(+<Lev^V<4k|b}VC+k5G@o zV^AgO!$cM0#rW5jyX_60fR(O2Nj=5#B1>*Jp4Pi=I!<T@)1sy=<xPNBMLok;jT#Ft z*li3QZN!E6JG=5mj0(e*wfIsB7;W$+JS*j<Ytsy>Lnpn?QaW4fqU;KtL{-vz%SLBN z2Hi}DiGNM#ExqUT5+lL@8<h;Y>(y|h2erUPPil<mQRR3ax;pi&-n+`Vu?+2`WHk8O zpb+)8s3yu@QhGxlNbUuFseaHO2EafV6cGx_TPxrlQHQ16ryR^O1m1J}E`wDuFFa*q zsKGG!*NxRMT-l!QnwOT3zVIN-xACm_Op-_Njf@Dd8kDqK%5<se?*i_H_uXAiy$Ch= zp11n~3}Jqe>PEdpeJAB*>OLE<P$f)XrA9@B(oRnDzQNQyssQzsjUn)ol#_8Sd~5KU zwFcDNUa;SEf~SpTeqHiygEjCUyy9fnI1LA^J;L{nK~?Gv8*jo}@HW&<vP2b{+Ze6) zgx(mcl-;q^I2aG_!UBgz$7$GMt&OL>XYf8ufQhhHKo^*#%wuh+_=!HpBv@xUnVQTp z1*XC@m<|bX8YVe(Tfh|N4-7tpk6;GOgjp~fE;&?7{Kv|v*0L)<QT8+al<MmBE0m>8 z%fNd0%=87*VEQC%gqL8Nyd%_kuPVcrOmB?c&+R5xo@GfvZ7}%4U=Dl<UqyuCKHG~i zC7h=Iic#SjwL$XNd_ARn=EgV5Zy{w24KMKR;5!TTqA$FuH<LLld~LV3<I_Fk0N-~4 zzK7kh40qdjojOG|wU(Q2I6R`vBW08Li_sD$!%XH@2K}L{8>!rQ(MFC~hS&H;^A#5L z9F%3ghb4uL%29=}EE)8E@TwnSZbXQGCWLOLrR^?+$#4UP+c+w3o{jmi02ab)ri-Y> zumqOEGFToF&P!gQ{J_IkQmdej*RL|IF21{{)G*eYA9lPOwVL^EmW|3a%C)c#*24za z2%BItJR;yZ8>!trEBPTQKbdZUO0gG?c|n?J3C~6q(!z4Rw{7gQkygM~8y`~Jq6%4A z9*;M|4eE2(aw^X%6C|IEDs)s9F}O?lxpKRJ&D76AcR*8z>cjnz!|~QaGb`)H&k+{b zsBJLM;3IFD0h#qK>+KXZ*Tyi|rQ8jBU@xTRd(6gz)JpippqSo1YCd%m5`BOBV=pvv ze5PxDyHD%^-@^eLHC#JL9b$f;`7l+4nrC{%^r+rLu@{aT98=a%u2fFq8|OjKOFnKR zr5ALEWCpLZoG>^Er{FaF3ctY__#OPxPCN?@tevCI!yoWxM40PtcheT}WQcz!Bz{-a zRq6uYMfeN;hH>7q*~TShI$z0P&wUEU8PsDL50_c4z*U&VJf7v6vX6~_sOu5oUnk$S zmY(m1!R)BQdj>t3J3$@z!MAafWs{Ac_1>daieF?pA9BS(Xe(fp@;LN}zAz*9!eQ88 z`niBx@-7Rw2kw&hu^04X*=%hMRa442mQ*bNTDuMZK|=g%D6y<TGAcQwfRvCbB2<&| zZVU*0sniBTy&w&>F~*1S2B-8g_%_lSWOa9r-X$uX-YP0Rl>z=S%}8Z}pFHv<d2?c3 zxFWQtr`=(i89oy5i5ppzStCLj=5x&1lpiW@DSOGg-;K#sPN=WUZg(%0gUSgRh32Ai z!>7tT)MwP4RNjbCRdTbq8|qS@n`ZW^`d*rk?<XohwaUpWFp#ByUO^}Xg`o&!l2Vi^ z2F0NSw6<H4Dg~vX4BQnFmUux~Wx04V%u|+AmWK)~z4W$tP<o&DX{c!0N%9x&HZVP= ze4qM=>gc(>l$DqpSgTCk4fntucIUvCP(`mT-vnz{rEI0{HTa4pGfdRm2KO0Mg)9cW z^}eR&+wG&g-}C`!sQkwCTlfwhG-zZ{jj9ecpeEFU+E54TLOrMt4WPI~4XH-3UDVG| z!r*&1Ci)`!>NRF*0uMn`Xa+lc=;e^r#&NqpP&26W@GxI<XaOyu6|{~Bx%`Y~In+k4 zBGs09nQBLEk&@PpWblaIr1+}P#BO8i43*8s8s;CpU>5VE%yX5GMHQy-_4A1yH)sz} zz?1NY-TtQYYz&~DGI$y~z%vmcgOtIpHM7xCZ<^i?Z>d1d7x1i&hAcH<rw8q1>CV#0 zT6^kiQQM&|%Y87}@n`fpOX&i64R#3_X)T)@T@4mc*G=z*ZhGHR&rxqtiBW~daV>mf zx4Xes@iU-@a-o!-)NaQs8}w54hCa|2`ayrFCwTxh5C*|u7y{=^hf>2}IE;Wr4t;1k zQu#c*058Hzu$blLs6y_fkIG!YgI+OhK^@S0RXIjEih2!Rhtxj88`PVyg!wJ%ZD?TQ z9cnc6Q;wku`9U?YdyRV1V5~uTy)UGUQ?@Z(;*sN(??#05UizN03*Q%Z-&gLA=Fro0 zwcf*V8uG<5d=0G((!}`Cl1eT4PQIrht-G1zl~*>Trsz$OJX@JlIZ-(YmU`7egBvhe zZwgF>X|RlCI(5Re52z0zy&Dzetu+`(ePl2LX2KMq4;gG_nWZ-yK8C3V%f+vNZY-Y| zd<vhz=kNurWSK*K317k2@C|$m-@*6r1N;bcVU^uIuFX@<hXt?@7Qtdz0!tygjb+sG zh_K0*y+V1!haLngm8;;8Px*k?r-RjcYhW#;GyTm*acZ63de{J~9m)|A?scO?w1l^) z9x*C3iz<Ai+{m1hc@6B9HyZwNG8eT;{3gCS$|Z0O{xkR;zG2?$i<ky$MQx57p|wLl zIyA^&I&5S9NnS3#EmRqKTd8gEpwR8q&#)sRWRtQc`oeZ<r$JF`#bL1IU3&kq%yzdE zUwh>z)G?vES=PC`J|e`e_*=Qbqf!cbT2oPb_?l6BqY7o^eZ`#H+B?d9%3t{Q!8R#r z1ngI)vs>5k{d@=XYMCC4DooTnq?gBA4pT>9g_K|7Zg_*`VH;0)+P!d;<urAS>TNnM zZiGLX|5R>}cRWr*J-rirrEHv}PQf<iY3eBTt+fxRU-i;^_;1u1_#M)j2C9Jfou$sf zdH4hVj0g>#Y%8y#lnVwI;V<}`C1<pR`}zKjp<xj9z4%Kkm!YY0kCf7`J?z_<z?a`f zBJ~!_2X5?xOMF+vFEza?C6~cQ-^Mj%TO0qd)MCjk^f&6d=?%D(`KGA6QH3t1g_E8E ze+szCcMJZ7Hw<n^6-qEy5_(5eA@0Xti3TmGkA)_ri@0A(GAcQwfRvC5Hn|)BAyoX| zu~8+a)=L9vBSKt_zcwO6v8X~G_*E|*%ffgg?9zKgFMWJk$V_GN$d+D^L9Z~&!v>EU ztb_CdQg~Vh>IyXyGAc7ggf=$z3Ybd$ATPg1Zib&=3*2ENGi+tqs+UEX6|zBg$N@QF z8%r)KcSLw8#)k)>zC)=zBabh3x89d}`;~>LJT~s3=JNgK<ej4OLOvLg^inD<%O)tG zEC_{Qj$UDEdwfe6C-0_S8u-pPRK&E0a*Fb2z69kCuW#-_m#jVR+D^TqHi|)UC;=s* z6qJUiM3tfLg0fH!%0mTs$Bl~AE}^^Kt?5wicqn`pRXCya?-e9gh7Y{pV`~Sz>TS~} z^=7(uH_L}{ka!QZN9bOtqP!RGgCQ(csYQ10r(P9$4-~NRrNLq41Evo`vsi|VUUd{c zaJ*U^gx{&^EH7KjVQoB>3VxBd4>Gtr)AYE(e!Uvju6zAMdNq}`pf(&}sS{QB+l{(< z^`Jf+G;Khw7qD4CLuDgq3{Bv4(lb~N+4!D1OkGI2%hD7I>K%b*%7>vjWaVq(;VqOc z;V54#sx`EMPx#tW$4uK%kHDkw7##E+JWjQTC*VnV3Qh`G08cABz%$ShjteaW&ni1X zXXpZVO8&z~?W*hs?L=+Y8){nE?sEnoDNiU9mE9x4f4<_B%*TAxDpbjc@QcAo=2K7v zK8%)d!C)D48yF@uBb;XW6^cS8z2B%}(8I|yR8OiG^!9@9<*ju0FL`~bRxs7)sG!$} zxm{G@Q|1<ue;3u)z<)O<_M`g402pd*Ahk@?AZjoSf#jwM;)~lIsy9REFzS@SGuDPH zN5DvUJ|Z0Pf)|u8!b|WnyaKPnD0nR*tYxm}+AlFLEK|NLejk)@e3<Dd*YbKnAA{Eg ztTT9ndK2D)x8WTa4ev3Jp~k{E7!U6o`0XX}UFBJaW{Q6=X$mPksI~`v#diTF7&P*h ziPR~*U*QhBciY%&<D9(neA8eO^JJI;Q=z%FX;emUISm(KwT(markj2MAHqj4BO>&7 zW2W*CDZ`n2M-@IcIPdssQ7sK-@fG8nO_ellW$<xQfU=kAC(2ILLc51qKGiG5@)<S6 z(>|xZhzJK=D{b1-T5Y(@@~7SfC<7PaE|_EYOZW=DhF@L#hWZx1gYRLgs9B!zgK`4j zUs8Tl&V_l<nD1+tuUr5Hm={v{1k8p-%Ehn*{uZ^AS_b{SemRwy`QwOC#|K=Y_hX!f zZOWhdK4DoI2jO|Wa<08$@E$y<T<Spum185qbiPamDWHkzD#^{M>wJ}kuGV`r_QK`3 z5e`|KXyXPfg4b<a^7=K*WvR8)x`<HO#(utMh5pLC-n1XJfhuQXBXu+S!U`K*n6I#$ z^V|-4cSz|Bo0vDlPp}2H!nTO;I`d_rcl!vRB}FM;vAdmR7R%2zcEC>91<6=;Q&(;5 zq4vUbDdqKkQSMh>Q|?PD;Q$<jLvT2$C+`S#6pq1hH~}Z&mQQ(#I^wyfsb3?)o$--j ztCv=F?Kgvq)EO#2^Y2uEvv3a1!yoWxMA#@`l^g%q-2+#Z?<V!)M+oa2D#zEzbB{{S z!uKc31yTP}Pn%v;{sk3${J-58Ww#s4r!1FD4=XQISKumqD*3v#Ys!3X9MdZR9c;`J z@Q>+rxB;_cFD!K9In(F(ve*~_H(5qfw@equ&~Tmko}`}Xzi=CNIeA9Ff69dTcWV-p zMT949Bschy<rBC=nVcmBq=ZzE8qz@8h_KjhI%Rsu02v{z2i@>_-xKBEVNL9wluRX3 z(^#r_>77(&gDj90vO#vp0XO}$Zn~CJnG1459=K(CpK0fKE&M@Mbo@@!ypY|=DewkM zAC`Ou|MIo=jGb}npKr&%wy5|mC4`d7{LvSBD0?f1M^D(P%&R=%1O6?!fV|uC3R2%m z`HAl_zW)q5^A&<NPEN4<JXOfX^9Bj=|AZwT^p(6|uw3sr^&)IHD9l_0nk$P^EBF?B z+M=XaF`tBeZWLpgZo1lZfVJX!C7@(P=xR`3N<JHvSxT9Hs+Uz%X=QDLGB%!$8{s=x zZ+8;kT`XIuvQ#-J4;7#yJd`wbqmr^R+zo5=+B)<a%RPEk;9j^dA_Rx3D(iSg1sfkz zOW>5<`%NE!WWLFwEDtKH!C!pUsTxodlJotT^dLW@T6#<QYEvmp>rizer9nNaJ~V)a z&<H*-eN$8i>Itf`K@<2)FQvR^sE+WE!7F^(y#6EVGpeaUGk6%9M}#kY{1(d5e2D@I zQUz_KlHAg?6||0MUM9uC!VTKhYudU)+s9irsaL02hx$$0v~As_Zo9TkS~Ty_x=#F$ zgIWI1QKxRR1|8ZoY2V;rp8xICYg{KTw&>8Xb%RzNTC}d;p!J-D{;A>*CkZ!dRvg%? zZ^gceeak2I9x$+D&z|Kw4e8dq`@nuxG?V`9Ft|(a&VBk<?DSm6{++uFtk`8xryl*g j_V3cKLf>Hr(^l`*r}LnmU22wzpUXdPNJyDHWy=2nT8Kp! literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euckrprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..862a887c7180b964489e8425eaed46e4d96a6d14 GIT binary patch literal 1084 zcmah|O>Yx15ViL!o07Cu1PCNfAR$E}&80_#O4Eu%NkNUctdOkj+D#X{o7DD#67`l! z{TY-a|A&*WocIfznDHi%Uciy<w==u*@!n*=-QFOuk}pr+e~$?Hfe)({0N8`A58&X0 zQ%MS%P>R@-Ug0Oc!@dlPFbN$FWK=Yg1|_cu4|#M&cqHh;Ph#E}k#78xLZ~ja_lK1< z`Top^!Fj4i!n{?JQ=!1q8BBOyjz=anVwh&<c`3m9@bKN>=;R>RM&+lK$tUH@GL<u( zYjAElCmRjf@Xf*D>kLx-S^g5~T>ye4l#|4}CTEmW?p?)+F9PoK;EF705(0KL1CFjq zKoYFEVeh#3b%hx=fD3O7j$1#2!w^F+$-=wwzJk;ECRo5T3r(~ja5pZ=O^hB+ASgZV zHf^Y@sZa`NCpKm*FLT3~!hkA7TQhT1FkL8=!rtR+{j(Gam<we?CA2WWL!gB`gS*LC zCR42$`$m54^-VGDPxEOnFSSXf>}8+F<p*=Ii$=HECsFc=>SrJY7p5<&?4z1GL3XAy z6+`YPur&fgH|YkA>HO{*DLbp;Z?S_64e&cGo>S=BJDx}IS?}mXZGx>!RSPbM>thQZ zZ42vwj#!x%q6-%7!9l$FgY}f_Fa0;IjgBTtq~*WT#xgC(RXP^EwUoEIT)ohZQ7){G zF}uN7G2xX&++ysaN@eYFyxACd1d+{5Z9`bqfy1_!`eZ^%5FDvk71l<KEV!w73_#;} z#IzN)0%ya)*(y$#?bj+PB*=E^aRHHyDC&QX8z#H$gk77RdYmGNqG7gh)?DbnmDI?o T5kIfnd+`X1!4YUt_w#=Pzu5#m literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwfreq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d114d71238ed610eda1be5c28dea791b0b471fa0 GIT binary patch literal 27139 zcmXxs1=Lq%vjuQckS;0d5|B{3ySqE3eCb9?K)SoT1eESl8U!g(5ReYxD2jza=smyx zz1OvzZ(`4$J@cGb6kT71gbCwC3;$@bJV&dsL!(8zFZlmIqK8ho@XvlpLenu?i)bCA zw}{>`MvE97V>XPID^`~<8~*XQY*e&2qD9Ne1X`lv#tF^6*kSmea6a#3=moDc4Vc#y zrlkwLZNf9cjEO??I96!>4mAZm<>rUEATw`6g3!bc`GZ<I^2n8s8+yb=^@|^x31Jwu z0Kx1Sp-GoGtfp11l`u37L(-_ts_DZ*)UWt%@D_!nQLFXl<JHj{#rrheBM9@+g0oBs zR9}SSqNaz!qb94Cm75`)$&`)|gv$jrb=+c>gWNQzd$@np7vVLcW&v-c>SZWAxC8PJ zeVObVQ(G8Ci^`zwko%<<UIFQ4g>3en?aomlI`~NS6B~6<Ek?#{GftBm({3-qT<|i2 zv*4Vt8cY)ovB$8`3(gDs6O@IwiM~!DX;4nsO50qdpW9=v;rsM1Ry`>k3o?qS65b$c z9&l|e^$o8EH;=UWhSw7g48g(Ayw21=beuRKpN4BiRkBPYOaFm%g=!VKI!KQot*m#U zYt%)xLzv&b->UW#{zh6sN=t=dP(W^xEywY47*q@7mKneE>W1{ePSyLWRXykuVH%Ly zrfuaduwYqo(~uS)xSioKRI4~sZq+khp$qR&m<w8<nr*ET+UAGgAmoe|H3>mY3;qh1 zLT(IiH!lU!oesOu+#AAn2yXdGGV-P{T|8MD9dRkh6!HaqgwrYbkXh;)zsc2e$<=U4 z@qOwQz5`i@Ds%WbMlA}b1p`8G5dMURUpriGN|S>8W#2RiHltb${2|<Js*VDG5%LA| z<T?qz46hMX6}GYJA1;0;1P3$aUU`|uyozRgPfG<eZUN6Sa--b0sA5MHz-0<e&{bP6 zh5R7VRhPI`T?7S)Y^ksyTr0Q<yoKf*mR<_CnwC)p-6g0YNKPGF<o+e?uw3tOM$nqK zOj{8OqVzuZs&C<YQ!a_Qw|U9D+iOfQU(=gmZ}2vP>>+7XOX?>Jx6<57$5|iEF2ldD zQAUE+fHbp5PBZq9@wMD(EboNVf@8u=Avmg<X<IG0jmhFIGh_Jy<ZUw+YkQZ-EIM}a zR#LECM_mL}O<O`iI@Qi{?}n;^2Utc5&r$j{rOPA6NnYa>&`~^u1W!Y7&|OC!y<hNN zchhK?Z}ZXvuh6@a87_R^mRSk!<FNICYZIPB$HuT4G(&ZOjAtGot38&5Uhs`VJku70 zUNBeq4OLy??!le+CDv9wpt{Q3GvP^s>~i59!p&W1wL&%>Yj|rz6TGE**>NsdzYbg! zxfw#?K~V&Am>O^wK{8W+pMs-K9NP+`9OoKHZK_@<<ib)<wXvn|hjW9}s5Zjw@G@iE zAUi=jg}a!qERzXjB$gL?Gx4e$`G_e<?kR_zqnZRu-_Q%fVd2lE6@D{(wzij~9SjRW z57plhd>lE1_t@p)ub2<893l5Cf=gCi2e+H5^}OGa{(>~S-W)bMjx?UOI0!bteZs61 zrt*USfb0q9203`2s=lRTBQGu7TW+uz^WV;%FT@4gfj1eM)T*0+tJ!>W=ml3IRl>if zG+W3LWR*MSc`Dg52a)ALehb@zDXL#8JTPqwzO77SbE}e(MD-HyD<c!QZhh<56E=i< z3+Z&;zHm^`5$S*7!Gd=}FQ_8CV7I5Ja#KH3?>2)HY1_`rD0d#D2D!;}YzA&@k7x=v zc>C~Gw{!zCR#|4dYAGE%P&HI2Ay<^#Z<%kLB(1hLnc`+VHgY&GwNLbl!ZYC{R88dS zp>KpQBfeb1irS(%$z`PD<#PBy_P~9MC6~1py316!9&$TLd+5$<<rb;#l8c3}5Xeb$ zuONLzMo+oisFLaUR$;e}5v1)_m}+=k!&me6s9uGep*j}9+m4viv<wdMhwx|MIanIg zoRg~WnZmYguD2^KFLiX6+fC#EZOK)00q@nDoA)-;1UMn#rS+bpY8>Gg4LYXnxbPZ% zYmpXG7_X37hrc6@+6dA}E)S(2z+Knz9n&c+1YuXWrQN;-uEDDZx0$|vWE93+Uakp| z`Kjt=#(AoCgCqgzE|=M~*MU#-$}8-3$#!x(KwjzC5()~|8D3s)jq1M&amh%{9Hd~M zk&m2Y9BEtau@B#4x&6G)!`|Q_s@hogU>S>Gv4`4<{tZ+&EZtOfBvq4v_X_(nOMrvO z1BBIJIKDYpx*Ayw<R*dxMjm9A>i8_8fH}n60?Df*mue5ge<%DV1x+pUedI!Nqj>w} z4(o02$#zqf(X@K5TNCaXzC5TtC+LF0Ik=+CTfzZ4exQD+-MZ=cF>)c{2)LiU+djDB z%oEjQ3U4Zm;{9vJDyohU^pS8Qf|084hPdETc$eTk$4LzL2Ym;ua8$<@TlSJWquNX% zk3sc`^b1HZO7Ah?WiIrQ;qjTPR9$15F~>tlFco-@yA%%jf=Y&OmD@*9ch{KA{A5N; zESdD4487n}xaJhh0nRR$OfH|}G$-;SB6CM%5PpKHgF0?|#s)Os;hj`iD(sEw6lt?i z^$f$H1Fs7iZ=;HX>Ip4x$rTW;w0TOnOO_dmWjSznTE0NvgZGcZTo*54k5jzPM8+fc zG~6(d!eJO($M?BGY2fa7trpZ@r1Uf1pGdbcXY?*p$Ybs*(zYwC5PoT+lK9TTRY%&K z`PpHAHL@kXW@cm|=&rlGZtgi9rxXq=d}zV*az7!+1G1ghjknUYCr*+V^Kl)U&?iUm zufkpgm6*9iK7~63QU;_o$OZIykY40{#XLYiP_>q}3L!X%vQZAWlXACI|8v-1gntS* zt5(H)3Cj=Wril=!el7R8%`<DeXX#%E8sL)u0N<BeWvy?t9rjR}khZ5eG4BD$6xD%P z8tVN9^Kg)oa`ULK<QkV1O7k92^$vn)9_orhD_U|Q_*NL3f^!jOCQ}#&(=Gkb$g3dN zLK7^N%SZSxM*bRlL2<ci+R~ZvCk5YYd&IOhs51Jsw48zaTKJ8-Yy!?K{0(V-`Yw_C zRCR|i8j*S3CAQw(s`Yi`=KX~rALjfB&S?9L`CXWb$ag}PpdgWP6|y+fI)&WA2B?yS zCfEe>nC7NPuUq;%CO=$U9q(B%A1!_#C~CYnN*xx0MS5=l-(+qvUq<M)#h@>`Wp*LR zWuwt@1+1_d-vm^*wf%tk4(~2=6=bi?TY%h?YlI*M`azc2g!D^%e^`1A+!EnFZO`Oh zv*nMNmjky9AwgZ5|5Tl*V<&y>REshnU~c2_{sQ@%S#0D)8~sGpf5KLJ?^E>z{R7@Z z=6mK5(}k7^z-z49)1bX_@eFE<YA)}?&<n0owOaTSzIV)B0DOp+_6k2M45qKO;g8J- zm>-ybbbJ+FC<vLtrRCPbmGn@L<R%I8+T$-;p5m(|_ap=d`l6m=$xm)tAHy#ozcN38 zv;+CYMp;SA;<`T@6dmbPUQ%uEAec*OKU=;j_X6`nUPrlpdar~0imy5E7X&d#>xOTT zLNDR33d_CzZ@k}`KbUusW`rxiJ0G4Y=t5*~ZS{Qzt0`@a?{B$*SkB5lL$EdM4Mv0= zK}Bs1;a;L@<1Xu*eGG76RDbIDi>V;Ir`lG>3Z(DZs7_c2enfRmTQmEv0{Mcs)?Ma> zs|Nc)YB@v)ZTqc%*h{}|nVNbBA<fOS7gjZ`AZf1{zo8tpQuS|wl7YO7z6jE1)E9_^ zp%>IK?PK9OCO$#0>nLdWSEQ9N_g~DdRQoW`QOyDw!Q_Se&Bu_A7v1oJ_zuwWBgiF% z-$6c5J!sV#hX3RCeO>Jj)j|e+rmd}|pUE}W@sDNxQ~jKvauFGFh2<`Rq`<O@_d+2C z?<e5=HhNoF1UM$|B}iI@Kh5}>zBRz>2|r?ZQMYPAOLENLgFH94n6MCBO1G~l_ZOBF z?(*D5kAS-~+kxBRdu8NrX527$8t-4Z=5T+91i{+yB*E{IyWlHq#x)N$RPIyLqA9%O zJ=c*<p{TW@VX3Xq#Dedb+gCW+ps(fjd5SK=<V+K0gBisT{6|Z1ULN2UM4q+L6wE{M zWkt|5LT~Blv_wlEnry<=3iBQ8sC{=BUPwm_xR$71&^(ald8*O%cHoUsZDK}kXU}GM z-jFW{i{al-qK^sJ%#0Y?VlulNyQ8-K2A$W|RM?V?q`Wl>-)M`aBZ)zMv>hWdw%ohI z!)ClDe1;_sufN`x)W;Qm;#RNoV#>urdK^mu1b-nYU}OnLEGU=BiStEdP`?Iq0l3Qw z@lbt=bb`Wbp|s$Hedh?XYm05hP2npe<LgMkBxFu|nMAyQRTJ})FtbD9L8vVJ726?- zn6U;`A*#-~!7#l^fj6o)v}!V8EL8t7Z9T;a3no`s3-XATL)5p!l0xAPW}F2#p_;6% zpe<7>q+&|y=xcatVHzeaQ&dNDRJAadbh>@K>sY>H-h_*TK3(VqBdyiQf~|N@s5)So z^l+sRJVwxjg2G150m-0x!!<q@9@OzdHKRfn;17t*uJ;YMFUb_6AQQ-DN~0wWO#xae zGo?+-tU41xbk#3NYeQNL;UIiB&CLS0NBG$An5z9Km@mw#TFS`!t`XY<{LJgCBb(}L za;?pcr8m3WUo_|Qv^gRWUO_B{ZCL?$E^n~HTOhaa?Id@%;c<}eiFhDoY}B0B-owAg z<kYsn3h`YdmoPVzPMF-jsq7m&R23ZIm7rjYgB3CS02ys4jcZy=)5b*(X7il3JZaF| zNZ*Ew1rnS2fZRL^uj|dH<9(3)MCMg^%{Af}KGE=aa7~PS4Z&s|2|_`^`>N+j8=^O# z-jrmFR(+*9OIS+p-@Kogk`&|zF6%fi$c<}cA}9IN4c<{LX5Y)0<CuHe=7mueL9h_G ztwFgAdRIpQ=5<sBd4sK$KI99MgIqBD^T^q4)CN@{xV2{NHKQyo*$jHyj8?!Os}_c9 zi?1njg-L*A2uKmtci>XF#v-}aOa{Xr8{XSmMd8-LT}NL`*aof?^E*LJ6pGt?A3;SJ zzxfqaJscSfLN#32!TYu`Ee6dAX(^7coSSY%5YHjX3*+;?vDR|EAJb9-xRc&@u_Qu} zn5m${zb=US-j;vsxFAfTdWHJ^RK?|OGpMMrB)(G2ec;l(q1L(?t`+1YydAy<k&$|v zdyk|@t5a~pt-gm#K<;{wB8DG8-_gEhkUm9lT}LOmvU0bbu2+}~{zcFSq&Y}Wg%kuW zk?YP&OGZUoR$_)4bPD(oxow%saP{;ycC{rsUXrl^_zYFa2%oM{8A}hjiNNI|H_%(c zaTeoCf-fFZUNyPidBF3TQF`A*l@<6e&r?V4u<#QjD`?x{U=?{yd5vt;C>#`o_X__( z8$m*+JAkya<CLVJl8!_QIkcTp7>0DIj+=5{TR#o&A9KF|8Eu8<!ctgD({hWsj6ROx z87XZde9oNKme`<PsP2ON4N{qcGpbd1NkC${#w$1dCY%xcVugDI{VSIgBpFkQw7jT_ zDO|@~6-!4WZ=z2i_a*vj3jN`JMIVc)E;j^oJSK(P*N{7_;~Y~{_=duNdWYF^E^tb@ zBNR*&mI({N=agP{mjx7Tcbw#ureJEJD&cfTNGq*+iHzEj86aiRA2etUmXvbUbo>A} z#WHW$cY$ghZK*)E2&W*eD_4(6tx(1H*9}2^x#E~V3r+AXrB}4wHu4|6160#!8^}w` zd!aX#Rd<m4rd$J54VkqF9$A05k0zRfm4TZ_<Z*IO5S~t3bk!1=8|i&r$3wU}hEH;^ zio&0Gsf~PspfT`=WXx2}WMos2tL9d<-~`oWp5hgg$H??X##P9`d#F&CdCCl9GAisO z_X@tcn9B;A7}<`hzs<-5w?g$pn&Vnw5OY{H4W%zs%jwMw{H<`UYDu`np%-L`{2&^X zR!37aet^rO<GkZElY3_A=DauI8d#x=>HxjzbzBg>&s=0aFr&1M;?b8*TMGm;C@7_R z+Ue3Ov{d+9E~~j2<Vp)O*|(KyHie7|t%cQ`xH{8DSd@agz}b8`F(_!OkX_qA>T3W` zAv_b7%*-H#{$ymJw4ILj%zI36d^r$YwPhB)LtSlB<Z9NM3i1|62OVeNI>HqrXd2RV z%r38R*5)mJ2gT)f%k5!0>TQAVIlfN9omdXicU7UBwK8kVX<8QQJHve)@&$hol-?fK zfU~M*V;Ujo0$0=eNkKjZ$*wRX41=b6Yg6?;TudSl85AWvXrr%a+0A4}x;NAue5dWC zwlNA5c`=>69i?N1gPEdC52h9cU6FQUHj+`ozGb|0W(T{D>c<cq>_s0xgaj3Mxh&mX z+c5e@DEz4q%g7;?*{1EDT$J1eE7Ue}q(Q&f{40f3X6$8pgnYqj9X&A*0O>=}Kuezn zxuhdDlbeD%_<8~NW>&dhm<rp3MG@p<`U-!u^kBPvjUWY)X;qiF(4Xi#3#al%5qSu> zpWe)547S2Idh43|y6Psl@e23!zD-p<)vj=tnKI_ibf(?RzvvI^%@8UGnv?qxmhwKm z{-$k%8^Fs>+G|)ggA9}#&0FUrL$DMO4pPWt_)$u4g(ldAd9*DHl2)Ip?+l-;HxAMd zv>m}x1g<#KP2mMd3~S{Gzp$VPs_WsP;4@xcgW_r1M{@(rgHfH245Gfc&!+>vEBM~> zo#xXPHw=SbSaQl$Kv2bn%Hrz|{GE+*sdggcsKU1jL(I72Bn^#h#B2e+WUZ@44h6{{ z$_V~4V-G=DoMavIo<aG^xCY$Lf=lH-hkHk10L}ZU8Ys7(g2m|HRo$<8gn}3N4!|`g zV=KPgG#?{3zp!#hAACYaLsTD|R?M^(s>3K9&QvkuZM_LB^T@Q!j`*Q!0dw=HR#B*D z?j$TdoMZ$@JbWX0o#^YQdIUj5`i>LSS6e!{&rBNy9ADueNPC5X2DP9xJ4jw5U!wX5 z_#WnISPH?7mK(!-15(~@`*~yKmb%bY`l2u=wAMI<KSBOBqmsG#%$Nrf!wM_RcxgsY z;YubxGhXj!I__froHrgz0^kX%1<fc-S`B>fFgN7-fgII#0R0I|Pu5$GH&O2-rio{q z%*#*JF>N;y6hYclwY-j^j?)YMH49#+uO9P`wkZhS<!v#oC&<(=7d#KYgP=WA-xpB; zWEya9R3#9k48355YCY$iuKFJDfrnoPH$!eA1&K%-N>D*mMTxBJF7x4bYg=!HPsq5; z3<ItLQk7|DqnY?-F>9P;J=~YHv_^29`a<Xr=~!g$@bHqsdLqBp@f}EEkl9#rfJ~yG z7(uVAo($&(H*~xr=vT~hfDa>GX1A@Dsb%<Hr03-3g3M!XV41GBInD8e^A)1QE#U3b zRtQUc)e2TEPC+q+g&>QV#mo}sHoj^U+|-eus)B^KFry{26z-O4FXjmF_xMU+e#fVL z%gCO*RyxihXw5qc+=jO-WC@;F|Crnib5GH?9Q_KWy25ehAM_`9CCyl=TF6~i@k)ic z;2EmYswF+t27GT)kk~iAIr4(;(#%uLR9&q%QCJ90=`BoiThi7j+_u{?z1OJ!NAGps zW!`Y!I|h|8vNv!I`qt|Gn5h}!f-n{SW1pA4&&z?Y3N3e-YqV@};$sSTuw+%3WJXK$ z>mq!noe6IcbjA`t41+SfJ~}2KC`(3P;S{$j;?rBNcLVc<Tmme|4H|F8Z_H&E`UIpa zZ!+_#Fb-)8wUxu1*Nomwak-N2SA@vH!tx+L>+oNtN5z->7vwF|K3AAz+H2@HqTj@% zP}m%LK@-bdQ9VjzJFoDgjzU7exgIqN^B8Yblb67%?cq+CQAFXi&*!m@??E=8e}kEd zDvNV|O4>GFO|P|0TS8RnK(<hIQsFrD&GlAgdg<7z`ks-U<vQ?+x^n`g{jl^7aY0|p z{D+`eSPi}s{$;mq2(~k0%}vadr@lV$a$ZF%<e@&Aa0l=ixt+XJcDw5utq7_`>3+ip zgdP4>YWQoTw!5^PQr)GkIFV0~{*Iu6*V?Vn!qT6i`ou;fA_`Q$(0d*@y|%8rj`p1j z{Em_D+o+4SkszH^zofLb-r>BW7Q9Ex9@C<u{}@3fGiF)(AIy7I_c8mK&ZtVz{1fJM z2Gv1YQf>v7$_T13f2-yUbHPgMFCwiJ+~)>;hoCB4ZH3YbgWRu+8Dr%>q_jURWl>#| z`&-)~yTvfAzccla%L;dbnE>}Ts%ZvISA8Gp0V`b6F)M@w8>o5{xTR~1#8=lcpJ3T8 zw@mdrEHPE@3oGyrqPl}Q8*qP@jOAb}Rky*VB(lBgSp=W*KGRms(n;w1NMQ=xZ41^H zX2DVlI1$pbZt%IbygJ^+d`OrTcmT*-2(B}gfNv9?fcKw{guHuHRX6u%n#(wL4PkbJ zen&bIK|Sk_&=C(V%GE{+S0N}(T6^AM3Th%a!W&4&QQk4;ICD<hDBy*5J0FI@=<wn} zTW7x`*A@NOM3yC}vW|DHbsyhJy;G^`2KS>vF=2foPnfa8s@+wOTH&NzV!fkK^-w5> zIY~$r{B7=gRyd7dh6PXQNP?w-+#TK--n39vP*}$oAUhRK^A;eeW%Jh&3^FaQ;XO^8 zX{|FME;yvO5J)welOp(1SX=LE-bYR{9&UjfB$oTq@N-s;C2XZ_y091ev#NCvv{o2x z%e21d)owKsODhUKpsEX1i?CD%Nh0^970xoJfL~%hCp^#eHse!r@8g@H+D9&_-i-=h zGUv#6$-AJfE<xwzelYR^ReiOM;kAGpM{Ym4{>(*fn-pS@HWsd4$P#pNjW4l$1#(g0 zI~Tts>}9vF<h~ZRK^hm!a9e&OcbU1u3;{0h^>g^fzm>bnj6?9iM%RSbnVtyp>iEO7 z2iC7|t(f#hDI}G9>}t#D`_9}3Am1SvV6Bq|-4Jesiw0MLf}3(zQ9U$wFf--kJu z4q_^RypOpLL8pYv2^tApii|m!b2CwJ4JpW?+K5-tv@&{g$t5%B1I&$8M|;p)w5&t= zq42hFjgA{3UogZ2+>vXdV~4_8)9%V$@W>S%A{S|W5R74N($Z8%LO1x@TK9C^XDU(k zfLA&6f<|Uk;q~U-G~=OaR)ew<KA7gugx_1?1<3axRZ%_S4N=&vFaqv0L9fV|O~GA- z@jj6G3Jrxn^O_NvT<>zZ$EYqF8Sn<^O`%#EX*JW<^A-ZP#rGd@152mJmr`N9mpLSN z0eBD@Kj8b3X>Q~Y8x3Xpxcw7_*t~)|ei9bO{4?(j3htUVl=q)OyM)6K3}+g8iVt~z zXp7}hQUZ^6`xZvFWS-(nWkzbam&{tG9lj?tSJAP|3ay!B3KN)~a5q4H!BX8duE-@b zEs?e#g}<sEG~+kkM7>p28xdJU+wTfBc|&wGMB0~WMPx2~BP^59IR}QX5RCC{6b>&G zd>MMdY++J|cnJKShx!Qkxg&OU@sS8dMNVScMZ>=bekS~rX>D2?<}cv{BLC)f!19%j z6G;D&OF-X82%fmhBiC(DeF^4Wxo;4BWaI|nrH~*fPwD$0$sM9Sa|%llGrl(CIr<l& z3BvwxnXnq<<y|y9IdC=1Z7GfIuy^eHOf@0qiK;KLe1k8A8Lxzwh5zz~MZO$fZhW1w zoVQUTR9D~<V_BnGiHR2eR(@0pUM&yRRL3*ZqAMiR+gMu+;b^!d2>yc01{Zjqgm9@0 zzpPrvU1I8p#WXOyo7^ECm9d<S{J7|i4e}aOn}XX8)=<Y=OdN%FPVy}o{R|rI_EoSX z5>7I*J;-nht_Z(S&559^`^ClbI`bh&6I2z#-k@dVDO|Ft+&$h^-h24s>8OrxjFBCX z#+Ms`WxHjDTI-sQNqX-Z`IFo!UI#2Afxi$Y(A!ZiA#V)6)>imd$1$6aHK;UjC%8m# zKY=9XC1J*ajMaNMR1o}Rg*SwC+%K`-@gUc!>WrleGY;f2Eu)yv-2Q!qq)3x7$(a<) z=@1;0#ykO4GgKMKm?(S$WQ$MWmE1ZfUdqfx+R>mxs?}VmBFI{~DAOh(Xe8Iv(&H6U z6EqJ&ai7IAhuCP3I{3cz05#<*<Lip05c(PlAL(sQUmD&vELD-dj;b4QN^-{<`Mzph zXG$eETE_(7q^Me(R!_ABzR8q!NAR7nzCuf0H_TI1d#Ltg8mRW-bs+p-(-N6B6>dhz z9K3MOhH%X+lbV7w%p2ym!u&SxS6klTt&4aH)s1YVw{gUTh2R{%v<OmK;jwAm;rtg| zQI#loQ#Bovp6N|r23{Xt?6589hGi4YJ@if^cMO7>PLdJ$m4{02;%|gruuR9V!X~s7 z^WFcTBNOlnyY;2M9Q92>`kMA5NJVW`RriJ_ScU4axe4WF(%i<hvA|#0=zd5a6oc!p zkc_GlI<E54!eushoZg-a{Y=|URThOOAX$0YnAXnOA7rzov&%hlzZ|^2)DKX7OZc`z zPF^l%y5n?`dlTt!3#Q}EP`HVCCNDQ|A#e09;cpA~SY|TK*O=?fQA@u;=>pX}aLMiQ z*o-ptHFLlIa(zuJD|gGFapvaLF$L8?ng_rQh5Om91_2LJxUC}}@CU+13VF<kML|q$ zQ?cX+d55{9<2$+Ip6p$@pNw4ZLIs3B3#%H`KrX#-k7e56+iIic)Mrp=!F!;ZQP@&g z5K9|_J|<%+vmMn9bN>*=^PsuNZKY!iuaLHK<_<Jyzd?oN#^^1=E6U9B6diT6*89}l zyQZ}f76bVgeGXKo;gW}QgR!101qH>)9UM7qc!MCLLQ1)bPInL05Y+}0>|%xrXPY}2 z?l?g?&1h@nRf9^=T-@+EaNS*ZnrW92T=#fwF=ryTA%b?oZoHdtE%D7EcRQ**3gdx4 zP$+?UI$TL!DJHXOHsI32S7r>OG`-&c6v`-c6#fGI27<D3ov2D>ndy|?r{w{Y5@fCw z_NqRV%V5D@5e!FP4ncXQ0&@a=J}e)qw%1YDBPUdNh~);aom;)9x{$O9__FijqhC+` z6>T4Tg_4%`f4dPilhO>T^Qfw5WK3Zt-uLL|D~vGw3UFs_S<u(A%tYP{-b`kZkw1V` zMo^OQk$S5LbEsD3{iZDy-0$>#;AN^Q<Ra~=L8G*Fu+chg)m1wR8>ud4enc<{RVRhh za!>I+;zdK11oH+Ls(~OCkzFF^40FMJUuR?C0$X+hPRgWlgX9kO5gDD)w~zb;0Cy4o zZthm#_Y~fjt7*nyxm$)WL@>+9S_&D+DB-4)_5MI)bS8C}3y#u~TU%`%QTR3sZwWh? z(ckd97Oai04s##rD7bx?7uw@>xQSLs?Lsd=7K3yqZM2OR!8KRth`AH9B$ONECL^_x z7pbpnMl~#Bv}Gmyj<&2!Nh7Do-NSs$$R!4SPknW5t%T)N$08WV+(zFIK{maAF!c<o z&pZ=u(=nCTK&~skhP+11ZKQ8AXNhbqHy(2n-hQf%I&3Y6_!CQJxY_2`h^Pvc28FEJ zRL3J7v3zFDgw2^2%mK%4$ty$dAPaV*rL%(_)^SqdZG{OGMAMPo$ghl?D3=Z7Utud$ z<Fy^3J_WD4>R&oqt4`9<-HbNEwoDhAvqxCax07ohDUgxcmWff_1(}BG5rR7Qt*Q4t z;0{bjX0jR6;X2rSklrV7omB5=d(TFLX`UnOtnj|DOT>#9!~Y@ZEefLK;#;eS;Q=i} zJY!ddjs`{PxQj0hlT5Xgj-M%*Le;R4FPPwE4q`sVtUy1Tpt;)q(~+2#y25Vg&rsi; z7hUyZ9qZ)U`wkYPpNhT*$W7s5KLJyy>M6G#c#GZvMm~-d>@h8JE9R7qIw|CEy1$uT zdLP5RA}EdO+{juy|LQENH%K3*9=Y|I8Th)o#(m(K!f3o{w)~CeoL1Ptv?aGMf_}_Y z%+r`9R)|AxDbgy#H9+5)mJ`gKkRaINoVSFn(N9D_omZXdkF>Pj=con<KfyPU_mPv# zu<BD@FB{Di{=;;$LLP<gyg@qNQrLibyN!A%Y{xteZYfj6w06u?g?kark%KX#L1tlT zX#E<(4=^va?_k~#rYGi4DXkSgUU1u%z3Hoq^r_yoA#<=tVK%;@+J5rV2Mk*6B;|=5 z41AdR0YT$17yPPin2zDhhfEcxJE*r0+#S-s#5WJik8-oD6+>Yex#?+n(}G9kmb%Lb zRK0o2<eq4&fZ$``Ue<~(oaM6^2|Oy&p^#BqULzk+-&gNPs>@C5V}(9&cQNO*^mj=6 z%B=ty4ZM=qPi`J*_kiy+b99UW8OxkCD5s_K@%ovT3uG07{s__`ctCC<!*i?t1UEqS zfZlPa8bv-Sx!S0P>KLyum%jcw#)7=%e)qJkU?zY(NBYF(6NQtQ$;=YqUkHC_co#3z z0?QzSHW)PDpbil}1YKS2ZG64Woq}a5v)V=<X!`-d7tDOSy^nOZr<lV`Fme*+9SFuD zord5CxICCk^Ae~|1U^GSTDbwXJR-MRTPnhD3G?F{Z1{9kuL-}@HW*}}wjILz1kC^$ zBsZ6!nZjAjA~*Qas-KzmFYg6GLom+<nWy6oBhO(jqvK~(6(hHIoc{<vqVQB<sNOdf zTHssBn}cdDvw)!aNEa|antR-C?afHZdtlH4>eo1NAM|BS+h#@_tByfB%%FKlcLHZI zZNBhlkY8v?fND5`^AS?jh35XMT3Rlhk>x=alJ>4a3*mC%Tf|$;EMdx0@Co|4&U6qY ziH^?@e1IxBElYt@@KQ(kcrSG<GGnc^-bb~Zf`)Qqc)v2s^yYMp<-B>3Hkwxm---;P zelT;u$X6i$(Xtp-LXf9KuGF!LS<U>Wqpi6y2>M<4Tv)~{EY~*NP3!U2=s3rFqPkYN zn2bb5ehBx8YC@Xpm^MPLgWM9hG;$wnTgQx4t)@DTd4qx|%yaOq2id^<LDe(n6JczJ z_*BQI!i~%(W;4?j!N<<Ij@gAYH?!CWvR-Zj^REj%aGdna(uh7U^FEOq(SHKhmbV4- z*3bm`{S|$>8Kv-TQ}__1sNQZ0jqq((h;EP8u8~2mG4r0bPtEA>dA6#Ka)>TOzEmAz z)hk}%zlcb<VXDy-t|{z5KLL0;f=!WYkh{ztL*aIU>|z$_jV||&xsxgVg*PAb+p04N z&%^tZ=H*y6hI~PF`|ifFhZ%49UfvSRys7O11&NSWAmekneISK|{mhtekNt87n1jq` z%tI{aX!$%+Fubgeih4hCmld?6j7YOWRj>b(85e2!OKv5|D&}wDAylLF9_AfkR;wQ6 z9b;a@vPN#0j&~_oD~uuRVVR0X9tS?bbT@LTkt^&QrDHhAN!7Bdr+8m5vFx$bZl{G~ zXn7y_jPN3Y>K6P`c$WFt@FqH5Gvl1xCJ%a^Hx|KqnlA|3AQ&fiQTP>eh=ROk<YWG^ zM=Vsiv~4zRGrq}$kJr1-$Ze<!$nAiOB0Q$vOGwWve9fDQej1kYNI&NtmivR3*ZY10 zcbVDh!<=Bo&map_uPCI&w?)TUBDWj9)7<&yehc!_>u-$U$X%#+J*8JwHz{1>UGPTr zQ9U(d5nNr>t=c9UzCqh>W{g0(gqfr;M6M>0$9TVl1i{BX^p;3}#aDx%>jquqm6O{6 zoX?<7Fwb;|*;qD$RI*V9x#8}YAFdp}$wn>~euwW<y%#85=DEx1NX9g<%ngu@AP@0% zh5HcSHf!BftznPna<_!Pf;@G^KNYrzxZtv7rYO8)?n3lEm?^Z});0n`4{LpB(49z* z_dQjyRNvKmS7EBQ?^UPqHqjRwWR?Y|%Pj%!XoY(^zA^2ggEixggS)R#9ONqp+l(cn zX~*Fns5XY%5?Nn3S?`R<aA7UgnZkm0dnA|63Xgf4<zf=~n_M7w7Qte<-@{z6*<BtP zJ{5R}o4#g`Y;ZYA8^~N0?o`cT<PWIcbK*^U|3JS>^+$zg!atdjsNyiAm>;n`0U64h zMfg^`{UrA@^OTvb@C)x(W*f+FyaH~zT{zMT$9!wQD}03hkz8u0n}cABjpp)pllBMP z1L}7mcqW{u+6K#?!teDq!LpnAOKv{M9t0;;7rDk>;bUz(QJvu}fZL}qnwFS8y#l~Z zQN56hOHfnq+Y42cLQ;adDKt}9h~;l{_o$Y4#6qfj;imBxffRIzU55Vy{1|w#!gJwr zR7->xb-a+f?X|WFUkXQiw||HnL)uH`mBJ&vu|mG!v~Q!Dwxy`%S>|7m{kHs%7cKm) z=&0yS3??SC47d`xu_B@4RL9bf_a+6q3E#skwZ|RROy=&D+o<<2Y0FU!;*Hfi)YYP? zj$rmNvCY`2aDb}(4$;%q@~FP18i$F?T$FpA7r^Z^Z9fxF?f@@7FAcr~yo5|#$0<Z< z1<Wg`N~ExoSI<U;Re$5H^kq-yEivPSaGB~s`d&x1N?T$C!@R<ub{hhhL@p__Q{iAl znvS;!|4djI^H{lLaN~HHoo=Tytq8qfuy^}P$1Bw)sFDM(Huo<poFnZB?=z~#!;OIZ zQQN=5i=O*))uWy#1%gr9mRsfxVM->iTczTyLI0oL&rpp(@H@H5?Y52g1A>+0{!VUm z(^BjGN_8!QEUMWNq*0iFZz5BJjEXd;Rk$05!3S3TSlc=#5iRk7S7C{5S~M$kM_+{S zRaicE$v3g2V^%1nGI9poZ@lyh&8%<;IK8<O?NJmsI?^A}Z`V;rM+T4{!VG#dG8atC z#A^zYfV5d~ndSB(h=D4h!XJ9e=qP5!B)KebS()N;U3FAK@YsT@nM82eKwd|XotIed zneY($o%U$v;yF~4sJ_LkjA}NMQ&@!;Q%5f0dN=*R(&x?Xh9H*eO79k%_q&Vd27a44 z>{dsyd~4rIdXLC$K$Qn%7MAr)TD>2`9Y&RyS5q!8Ts|g0Q^Mv)tniMo2JaJmuW5T% zZkV>e%{?MF8@>O!CF)bSjm!_i%7o{3;sV-sxX?5|eo38V6I>hwN11909{^{>d`vDb zQ;>qqz{eCen6^b&5NR@0$Kg&eC8_UC-%*DsB~0Kh-!o~Mf3W<4r4WL`%<FoWI(re} zEV#Pig@U_2`FN^D6^b#(Fc;??=at~CvF~?oT2gpY$1yWb(sClAMPa5JB&WH#j?!{v zm~;xMC@32t&{2+8o~gjBw9Jp%KEqsE_(aDqt~QD3Ww&K=ok8x&r7-Q1r?_Os*UU#C z%bALp<C9y7HyJpq8B=(x%qYW56;=jWY|G~cRS~uTu8eA{N0|oqldz>iHfE=hr_89T zqb$A@1pN&6hYNj0ZdIhe()<PRE`!PeSJU=TM|oi@q_wpD1+q}#j3+zgYO6u2>qw10 z0jf7tx6$_oePi`T$<=^c0rv#y8ojRxYbw-YS}WA%)nO9iJ4R$z1fTkB>sxTG-U>`z zxO&VD`WDewU-&27b~3)8w1M2mIvVmCF^@>gspA^vl;rNvQ4#K}Gc|@wrO<@;!quAc znlYy_pJAE{r^B75`3%z{%moX5)L(*hG@~V42OCvGwbQh=WGqn4YUDdk(h4pSme#yo za6KuFXRQk$XOW&`62rBDOTyb7Ar*Fmt7Ms9+^?Nndu9U#b0~OE_=D<k;YuAH<n~~h zVWa)3=OZg<+pCaT;VJM1g*3vXhIiE4#xqtnx05iVwv_(T@+HVDD<tFXQrL&DGu-}& zaJ@wxB9)G~%r~Ak6MgF<FQc~#?=`sO!Y&B%y3j>}QftesBZcZ$a_@tTrn!%cmqfbO zv;*dzgFDD;<|*bzM)Kn5ILVuhJ_<`$W|tY4FrU|(-df!hx-(xZT%+$priWZrn%f!K zQ#jcAy@{OZe#eEq6w1)IJ5m*1K;MTK-;7U4+dxoXxo-?=kMyR(EL5M_qn~PjCW{#Z zc*DHqWgTVFzk&I0xj4dsAfM}9Nx=gPUID%c*9l~f8$44T1pEOrm^q~FFtbYaHhn`B zhBD>cU>NT!RQud?xNt6M`-QU!zXg}wGX1DZX=DRSAHkf@@T0uiW|U>tyXm(?euyt4 zf@2`>VHqKJRka-OX#^*Xd=8h<jNh2!I)2hI1>~BJ>&zu`M@EFZ#wgwfBR}F5A+0*T zui-|^jbY}=jpdDF#xoO`4rY9Z`35tNs{KYzRQ*_W9aF&OX`N(;>RspT!R%2e$4t^O znfXL`z!7gEog!BU^P33P<J+dUGhE_Gftd=|!uq@HF-<s~nZe9tW-%u%(~690HlHom z5$P?{zOi`?klVtGWXu8ih4&5Sxx#tOeCB7pcYteZTOfB=xR94s?w;^IbHYbGU+%I& zUm;xtx0qSN)U?(KW~p!)vz+N7w}Q8ld4TVIxhts3ILRu7e6I1W+zH>oYPmJcLy)z+ zPkb*aL2@}*&v31vf8_7cRZ}UXbL@2yuru|t`DLcM@TsN$60QeH58TIESM`4Fx_u+p zU^YZpLK9pt<5S^ArZ<9z_PFE_o8(UE7(!nLq^a?3R%mS1IdU~9*djOHs_*KpDc9fJ ztqR+i?aU@re}=f=Vq`enHKh0P)o_xN&Xh*3mf;8S%{Azh!VWAunO)58(A3El^LnPr zjVm^4+O|>idetkIuhq6v^@fcaRIkvuQT4iY+BPU3{?GL!|A#1Fp;qO#4Xd}Pd_DF5 zW-3-I-=J-yx^1g8s9e8o-3FB^H`oxZZ|qP>#5^yPzkiS3`Flt8&KuRUU;p;qyXWmN zs7ueT{reP>jQrVlV5goPd-cuV;r;e~J9g@yzteyY{RegK+o?~!-h;2lE!Cq}#{u0t TmB|w>+%Np#qQ#0CE9U<I_5Q<M literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/euctwprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb391b1fb59db0128272d8347c0f41e6e25dc5d9 GIT binary patch literal 1084 zcmah|O>Yx15ViL!+mf_Z1qdWAa6m+&&80_#O4Eu9DM%@*v_i7nwHp?BH>vHVO4M5_ z^=D9y{2p$;a^f#=V#eD*dI3ka-_GpL$9t2#PG^<C%Dz1P@I4{q2R<xT1Yj4o*@r_A zK@}-!Mk(Sz1!b6p9)~I_<1F?#Qc2m$T9mvdA{NOd5s9SpFiS;iNV@4y3Zc5x-5=D- z7JE}G`yaU;O8ZWaPoxIVW`8V-YBaRm$^p+m7L^3+!-MzzqvQR;SY4ddwis8hDz2uc zFyLJCPBt8{!Q1_VH#wyEv%(u>b^u6{Q9-icikwnGMR1vBp^QW*qDwNTSq#|M3^=(W z5y`OTmb>HQHx=gC04}^SIBxSC4ofV(AoJil_zF%N+Gq~XEVjv<z}>na*C~1gfuQuT zyW(O~Po&mBJ8>yvMO9eFGzQc$+E#K;1v8~aDcn7=)IZ}$z)WfvYiXnf9wH;vDcmcJ z<%%1_*f;WPw`a>qZ&FOQipp57)K-2zsy^AX9W?sQKFdmsbuR}ggtR?b=k|Q!1=*fV zbqcwkz%~d7U8AcsrL((Bq--yWzr_wR)W`3zctN4-;Bc0}XIn?ddJSw{s@rgR+#Kuh z=-OBZbi^uN%4c9P0URWlJy=e;{L+8Zy5xu#=e+t?+EnpsRP&KUF&8Osb-8$<o1$D; z9b;~lv2rYGg}BYwS<O}B@w~Ydcm$E{RBu37y$Ofw+~|`_r9g0`Vo_KJF|y#N;xPb& z<B`&K(vG|h2WP!JxoN*qNh3jSvl$l<*~+r{=lEfA8(!F@*=fcpfhY!M3un!T{#!|d Uyc+3?roESsuoxVHHub;YH^3eQs{jB1 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312freq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..767804e58a62edb1d8872976f509bbc4d2a3b2f3 GIT binary patch literal 19063 zcmXxq1+<pc)&*c1B%}nTySoGoy1PZB`_Ltwl2U>SC=Dth2nY%Wjew+-0fMB+OB*1e z`0wY8|1t*a?zPsObIrBi_xsMdYLyfzlEw*tS}n=j`bMKTaV|^#_a|;RR0@9wrV62R zoK|r<$88n2bG%mZI>&Dsr$B;kM-KaQvtrDKr{l!QFT_kv6vC}|A$*W9gqNNQp;^ih z&g*8BHkPh}o17wq@nL?<Z@@QV8Ms4|hp;F~2;~DKx)8?4Ji$F5EXAzH-4j2AR&Zaa zoh8~oaR_shg)m<Dhx{w#hv~)>7831(+czu~bI@rp$fI;2j76I+?C0fJERCUL+}Cre zqLBckagdK5vi1P(1XqnY_)oYkt&WjS+Lg(<2|`Fj>b|)dKyIc9VJ}yUfjg_^x7IL_ zM5cY|R9N>}ckq|tNj0j&bqS5=OE%`j?yJ!R<EBBI=#4~cV$1&wTI+O?N<62Q!fo6h z_NY!^0=pT>7s6<y7B}cc?-?|YXnf&PtgCQ}Ueq{d!QPaAM(c%kQSAuuTf(f+jphMo zm3Gms1-IVwSjhOdPUARe%R$f7Av`ZV2b_~Y4FccmuIBzI_kRm*t$Imgs&tjRKOMY8 zr!gwJlJ;i2u92I`66C+9@`uJ=-0aVU&|G@MG9}c`8oq$FZn(V|`kC<r_IS$Ng&;M} zI7_*t%Q+<U*S$w7yR;GR7jX47ej;$g-ETJXIo)9zS%bA`3*-Cw`<9LRx(C?kX~uiF zrGY=>B_#)2ZFIq)_oeAv#59mfLVL7Ng)#vWeM9~rZUeX_9F&!oGUGEUebln4y>41f zPV;i#QLQ^%aaZ!b1?w}}fc$f6SB*@H_Nvpj_P9uNdq|@&F;2{muu*i+>Fdyq@;V)X zYfL4JQ(1eoMeA<;AB8m>)G_j1X(J}T26<@ODU1OcpHTTvcR5Bz>2=nA6Pj^VBz7&0 z!f>zSrnSd4-8;6-t&tF9F431Ts=%ev$Zc)~*ZwropWueFRuAMAj5Mz4TG|l$0B3dC zzd1GI>Z%#7h%N-VqkG)&5p1Nzee4VBOSSbuIeN}Dr8ekIH&oG}CGM}dMn_UFhPhES z>1iet1aP!Zx&y7MkxgT1PR(OiAU{&K8^#U8=Q(ZBxN1<{uwZnPN>b@W+!I!q3YUlR zGQvk3Y<C+Og}>l>xsuO~>~2~{0?(Ot3Z!DFMgLOH6y`?RotmR94vc88bR*HZynITf zAeEO)dymtt^!`%I6i(42jKpe}soW9{0KZ|{0gW7_TB@y9n?e3vwe4IrCfbeOTXwrd zV7IUX<aZ7Rplu_y)*T$f=#Tpb#(a(QM2DNPM`Jo}DXV7W?+1)C8ebAf1@{hG8)+xQ zhZ~vJDS?q?UE(+1wRRc_y<8L2sv5ZhB(L|SgGMd2k@R|Tn$)xfXfGSN1$ZidwSgOf zoCE&RM|`wXIk@(Q-^U%o{S4EN={6&<fYUD+-w!eycLCZB$~!ft8ktCKw%WKri!NIK zHEI8#7cG~@1NqL3ZbX*{L(xc$s;rICco*X*4jKrxS=;Mp=s0uBsLf(6KdHND#hhx< ztE-XJ)h!FPD2}BQ5qJbw9&Q(0ZDD+DLv5rj{|s}Z?Yx|Gr$1S1aS({Y#PAV^ODTN7 z!4CVrL%wa0ibluohL(x@C6xDAW|j+k8Kb4z0)tAS-Q%>juY$kSQq!9hYSBNWc3O3n z+7Ci0VL%Ac7~NyRM)ZqQU(=EiH~@0jpb=JmPA!I^s{EY@;3x-1EsRsaTJ){-F4_`X zb_EH4gI${^)+iAKqSw?e+hZj8YDCkUk;g`JT*)BdiImrXJR$H<BfE5i=TVfQ^??zE zpS<Ckf<QFPDHU2X0-p;TVjq;tIYlK2fn4_e6!<g4>$tT))%vLIC7;H$DGX&p`<ZA3 zwJJhRug@)Ekwyo%d(%b{SM`moOYa!H<kDAkHyD1|W4tHipgh2-2B(Fb?sA$$NT&7| z?of}h7O6Vy?hCc(l=Qf1ZwMuWji|2L4U8s~b6YE$v^=S~L<b2!S?iJ09~vjP8Xv&X zA_9NvW+b}VTKlA_&7DQ+ZR_U|M&q8Q(moiE=HgyLJC3&5DIeNkwDhqm!Yvo^rCS>* zr17fc!%fD<9FRUl3+gT+umR&YAFvv+u6$MHvD?CMiVEP4*7yJ<IqoL@=6H;C)baxV z>XgO3<Z!BH+6lNJW@I$?HOga5d)jW3J&#Lp8JzM7yM*7uw5X@K+0gz5e#&Vs`MV)R zyLI=u({LGqW=2-`a+=dsLigY_s-oM@?~Yr|t;kSHdfj3n(sS(QV{Iap=^9_S)0sZ@ zPo!xK{|xP>)0Eh08tY;oS!hIM3~FPUf6<b`{YL%?+H=y!ffn6?o8#^e!<De_GTj37 zI!IG7bdaG71RiL-sF4}tG;TYP3-(<S(x@@fVqCrM@$41W2t5pcP2(@zQAB4FO{9Cz z+}pZ8l7B{HrfKWZ8e_DD8}I6B#;$7kaHr!|y#hQAxP{P=)Ip+YbnnBxiTjPle6`+c zuS*{q`8<KMM15(;6frWl^a<JqQcbuzj5Z1*g;PI}0T^w(5!;!p=1NkbC89Ek@>OA? zGzQ}t+^30dkuG2(1NjngeRNL&M?z}fK7%w~g{x`!6C?jNqnOjkfQtsX`{LH0$i|x( z-w;hrWvjF`<>R`0(C!#MSmOxDBef0EPG}zr>5bgZ>14Fgo?B(KoNyb_ax#>|n_Vt! z9#v(doLYR~eNH_H%yL5|_*;tBi$DePzfexeS{tWn*4hj_It+?-(yPZyeza-cwL=`# z6*?RFY=A_A;i`db7k(svK*%HgiH)nC%t_%lY2h#^3f~>!OBL=U+yoBZH*LJMN4S!x z2uM-J@3^7fvBRmvm2M9!M1O+xwL&V&F9JWM`vCZ~jXKk-<RUs)IvHGjp@dcIS*sEo zC4oOh8zQU(9)#A|dyo{Q82K;hW!F8XJKE`M4kmN|0A#g?GSf!I(2kn%muc<H%|-sW zJ7~!LLn;m7Y6j(KlG=T>o<v`x*ASzxL0^IV2vUT6+7O~oq;U-YoO}*aOWeUd8`YK` z(LL?zR(dx^5FJ4D4Y;C|yZZ`X!enxdX5_OuB@Eyw_z7Q;Hm_%72kAz%2N;#YDVm|S zjQjy}A6Vg*k-I>esTCvoIa(a9_L9HJOERmD73y<(Lx=(Hg?0`kmD)8@Bb>_N<|4IS zZ3@U)Bg?z&<!m%nYa+}K_Yw`^?;U9?xO+~;&8SYQTWm0Gv+jd%FHvZQ2j#}=IUVEg zwwIwF`K@kauLYapW?*A6YY**qO5+NtO&&@m;IH9oOY7;rXm~?5`eR(u-6|9S$>_<v zU}OzpmQ~9Lb)=msS0=C@!#^*KDZoK>QuP8ZdX?wZ7|VrO2HgbdO@1Nyn;KW04hcU~ z-cPxci&%@%#Hwq#&jCCSWP@~@@HotkjvAC7ZYRbW0&PM!s;w~t?hpR{H1{f%E<C@* zX*%h2klA5mG#_KP#$hV$o&Exj&)*q$KaGP#_SonWUvuL-;HsLDAFYu_VPUB~Msd~9 z@O;vG($>HasXS22BCIrMEP-_NTEYF|G{Hw>Ad~q(CXj0GwA}EYtgy>lw@<BsD+!ko zzDxXiG>_gM)3%tghG>1@<G8<)|G-9HN$*G}hgG8=2po~d5ct*bZm|x4KNU_(6Y+8z zBxw+cJ_@v`5pHo8Hc&SP?t#bCPr6>{Lpd|!GhNdk(lHpV)fTY(vC|~nb<!M+cMl<Y zV8%f+dV}Q0&5N6qjjDEg7OjfgDBx7a$Z1Xs!?fs4+)Vb}K;R+9b7uTW>I_H)kbjN5 zWvz`yZcs~(F(v3l2c#poZ(!~(<exJ#o@=j8zEseQvf|bO&gJ#_(6ml)%gBFeZW5xo z!zsEASB8y+AVb}AX1ld9<4-e=YV-^$(eJ>wbWaiZUSpM0Bce;#NbeLMH?i&jt`7R) zP!H`>VK_!-jR~f`51h;CUvFm;UcLo+&Fj;YgJ;ybgFG#*iSZx#FNBolehjjdKy%kw zh|`}vg<$~_eIOlTWKIHK0=K{|iIJDyaN#h<QDKX;j%6B2j|tznze(PRv-Gw}^Jui9 zoZD`Fd2Z%Z*GH&?(>gQ0HnP2k*TQZK;L;LU3eq{G(N{z_OE+nJ&1oUDO~5~@RaTqs zB5uRYAoV+^Z|LUM_zdJtuG-<2vSn)mQ<=OTYSHB|DEiH`*=QZn#)5S9kpI@$LHT>i zlRUi7T|{MRA1c{|WdRZmCAAKt2FAZ|4dGrhd>Jp-f_#)8WR)3l7)qg=OSi0#X-Rg6 zqNQP|YwTqU-?_RR{5>y>2x)YL)H?)TB``AxMBzOTpEtEaY<xm$DU-X@R>Nhdd_|b2 zcFNobW;`XWi_t~*PZzsNm~VJ9+}s*le2yjv&zaHPGKtZik~Z;Co9pzEkdypJR2F$1 zTk)5jUOTn-SgYh>_jz|aP)SVhwk=Z`SqgZA>+C5lU~UgiSMrioEtx@GoMvmJ$EZxD ztt<XUZ47}|Y<a_sf7QBs3183{E))<ZXpF@Dn5*5UWtF~9Dmg|uX^${6`q?t)(Xw*z zPpn<W7a5d7Ivnk;(2w0=x+`t|BbAa)eceGdjF+k03?rkWloz?W@*o}1x(e@r6m)7w zbRzE4xCKpn&u;NBF1v&EtbK*C(6k~#N{}tOqi|PC--A1iwqLCvy=fqW!i;DEFM~9m z54EVj^dJYjjT}$@w$ml2@7>=_QcXd!lbYo8maEHQS^>tN7KTY@6Fp2cgByy&WDm3t z(N;R`fos7*Z8P3+dROSiczn+&p1JjW)BFPR8I_6Beyml~{oHA~##h1&@_B?0$S>o$ zzOWE(J(X!Z=k`ATf^kyVY;JX~a(Y3UJMB{I!b@7|NPC=hYD_sTsgIm?l7GxgGK|dz z%|R<6>{L4^>=RZ5l_<A+$?mS&5G`%hywZO`HmD6(`<(n0wf0>7X{{j!Eu}n0novk9 z98xRb<;vrfSM39$$LOs?D@bY;e~UHBIhAx96}%QraT7ZohTD!&f`eR6Yh2Uc8ga>g zXZ>7UrFJDd)V7lPiD+E%CopQzdzL^J+`_;WTv#EllItdb+h|a$(1=R8oc=*2`q=4v zklX~O5g2Pw3xjTvdQsyY)0Q&Sz^xs^?TuU4x6dn-mtt%W3r25glp*yosjq@c)I_Z` zm9wnX*3Dp#YA*4d(;mt{nD!6aVYr1(ce#ILndxYWg*?)_42?8A6_q)-D=qV8s70R} zc|Aa)cbv-eHyNalwN^-fCw0S&BBV+gR8raxE>+kq3Uk6g03*81s-rPJWcL$cr;YyL z;4ns2-8I5%y6c@jp?4nSHqT#Mt5obWGVKb1UN(<wMtge<)r}ZBLG&}Vhrqc&reOT5 z`!T)ZA&o9E`L7vo3BM4i2fP;T2^)>=`?GEnVTxKsCiBzlt@gIip4~&<(^4SMvGyMu z&r0*^ZW1za@HF{>l&it5AywS)jzU-dDuJw#ekr}<OJNmj88BX^yw#OtBl=QEqwg(q z$FwyzzXg0y`n-`DgkL<0fs}8?-iC0UN>eKwHfSa838Ll9Xyx>+eOCyd0k0+Xh{`ql zJ`|pjZU)|~d%@{4(agGEs5KzJ+eQ<qBm}8PbgEMwjdw9l@w{5v5jT~6yJ0-5dy}iz zFurhlm*_LXBF3L}8V&p@<#|-z7A^zN2kA=Xo^+g3MvOEXpAt=EkM;yg>%NRT4P>%# zTIl5xD{8#SX(zR97@3^jCNM@LhUniKACsDB<hPdjNZ8=+r>M<=8-hEP=eLC^Xn8=! zfP5_NY-C$ESqS8JwBu;obz6m6w8kq?Lt5L@-%emqNTXF6zXpM*nA0Iri73zW5)N}J zh%t~}UZD_f2Hj)!EkN`c&*M|wiv&L5-~lhm3B2L{*1~ns^^b94?xYW)G0$z(lDL<r z+)z8UvTCW_M)A;yI<fXT`N;5pfa@9FGxj3*`^w03(n+i>4d5sjT1r297ptWrFoDx+ zM3?IB*R6<lE(k;`)ROQwk7yr_)K1@Uf89p24SGuBuH7c_a)8}h(hr4K4O%F?t}!0? znmbr1y$@0c?MH*!#V#$)Yx9qR|8hzayOFs&V;dl?)bfNhn#SpS^aj%V-L$4~nWgE7 zrWRW8{5RS)(<1wB1^z`SVOqYR9G$1PhCmIB)~2QAd8FE>2E77&%R~7=ZDhF9Xfj$; z0<Spjhbw4qdZ#A5^a5^#n~Q_bZIn_dVn%<ryV0{e6P`>ISmE<aV4??AT6hO-GrPO( zv5wRerw&xMP<g~vD!Wbg<Gm8mgH&3g#d!L8d{6F`?xI%?q?ATsCLd~yqPNj$pT@7@ z6m@23sF8o!=qPS3r}tdb^BQMe(^+~&xk|_LWCE2*9n?62Ho)l&@Vl%vF|9MkZR=;n zC<O9Y?WpiAYYWsyxWo}uY6<^wkV)g5^eP*>gm*EHkm^JrK3odi6{ekcS08B<2A<(F zSev2m)jBbrfwlh_pW*Zoy_vc%18-NWV`NdM!f+KxB~;7owAze%7+r)mcALe}TLx7{ zyN~u5_*;;I9^Q-mrBGXMWOiW#seT~yaIbs5JD6<Z?hj~`r?<>Si~~un_Mg)cr)@T` z==6da_ua-JjNeUbY(_p_26BJVX$bIZ!aky3X%yjpth9i}Jh<zj5!Lr@+@f+(;{m&0 zI<*NQ8m0R@a3yP{AeBhBImSBR?Yi%)71Q0Swp@3hX=~YiQ+GUEPie(i_w)*bylmAH zAobN2=`JKS7o(U)Q;^PK-)Ij*d)4}?Jx{ME-0K(<aqn?3#YgCs@Z6#i7+FDvy2)2? z4|@Pd++RBPazkS(&qE2c)i@Jy(RAF`%qV1dS?LRKXQ?!Yn``a|o@EYm7aO!n?Fasf z`oPxm+?v^KkMOFn#(Qv4<2mwiFe>5Z<fW?r7-}HB#JavwVv>W@3>Ox4WMe!VWkE*s zQq;8O^x|;UpVTt63r^c?ISzOP$Ue14;SQqDNWDs`7^f3GkDK(CGg+CJDU?rw6hwPL zqnr;!KB9X~d*7`+KszeU!f9ovc233NZt0H0-9u`OMhv~VYIW8AG-wH_w}A&a6{NDp z?S6=H3S<^=1hP-#bGXe`z2b7N+Gw$EHH>GiuwNR-v<kSJrGE&6LE=(LYV#}P^La84 z11)MnYO{OUN99-DLugBR?nx>>?z0@U_DW?AGonpsTTFY?OPB*BneK(ahzja9H*Fi0 zyB^9|@(U;@avJV-7h|;MuPg8>=@e2YteTmZZ$cW~qBqvGgYN1qflUN9(mSJeo4?GY zs^DfcHwnf%-TOor*>VJb;cxgz;=UVZMBhpCf;=(uw%4Zx+7VJ~gJ_f!B!?M?IsIE> zf@yn&-_i1`y)4~f_&vB^V}n8E-DGA0KijgjE9nqknrJ`eAEia$8V8l=ZMB8CYtVio z-<zvnZT=42MCn~=RgjIs#~NjYQPTbfRr4t;ExqL?U#I+>+G%zV6FA|T2HQ6Q?sgYj zL-(4->lz(6SmcIkN&C_}sFoD27x#66D@&iagC9wqmk!r0ZS$|CInZheb7DV@p%z`| zstibCpQ9eQKe)v9MCVGUyNxO!FOY8-dw;@VwOm%+9hQkEkopL%bEx?(D*Tpf%lwqz zqmoznoM>CP-uCULR-LO%w(QI4W%BuPYg#%tfl6xe;cDY%RQnpFvMb5POO|ko+K0JO zOT*)`Ru<#}a4~DWWkzn{vB&s3+DFpvRNk=Q3XREVH+X5zZcf9Sg>ICE@+FWb^iE*( z4&CStjmu~`G~zlP;q(~!xNsj)$u1pFw7!vZ%sA`9CK9-+JHwMHDeaH;o7xgH%B!uE zUKHLAmlG{fn{C1L=HAdKCR`Hkg%I5ZNeA4|sS<EYbN|NZ0TR^1H>O9?R_JK1f2|sG z#0~YaM*?ARU_{|14*&0j$}ezz4eA?C(JqZ_(!s*-?%)twai_Ct<%REDL~aglyMwOM zrk?b0X*zSC#;B$-g2_uRtYrw%e`drp{14VzV3fjr6*vLz8QkxjD*KB30e32Yi*Xn0 zK4QGTQ*$bdfL~xJKIM{3_Hg<{HxUO3okoBxkgjv8VdQGVm%Ft|YMCg<b^0;LN8^k< zgVBj-jCZn$?u&-^^iaBk+yY5Y>Lf1<fM1n1^sWt+{%3{Zz^yF(5`n>_GFWgU2T9>3 zINi~$O>~l<IG;*OQ?BnrcZu;II6Y5lErE`v&C^IPEH^hfyR+dQTYsi!Syj5<pu_aW z`7YT<r6GYyMwT;ezuI>g=a?*t)<z=<sTR^s1WxL%=isi|vud@}R<O~GgX3sBb(d;P zwowJR6uMs-G~4h}a0!EhXr^nr83dxjPRrRnAan(O+oOGqn}+*dJU8Ru6^&X>MS=4H zSMXbXKf_N7J9U@A<+R&$+%LGQ<Fs1sst549FxUzuh4<<G$zM9)p#<VNl~nr%w;OJD z@}-4OKz`GmZPnHEb~5x9+z7Sd1g6@2uhR;(&rRC{@<{DlceROLJmC$4esQV@l9K$X zuvWCgHNAmRM`JCO1Gtwlc2ZuYTQ1yMG(Lc%^%&I+?-8s;t)*Y#mP0Ftk<B}lUC0<h zG!`T!z4pQ)*I9v=j#h2zQDpH@j)pCxt-y=OpYgt=r@YPj#nE=F&EfvBw7MCes$HPm zSz`s|e{}Dwl?WR}vx)v{x9vvu37>_ilG;h~_f0#5+YBT<$kecObPnX8;f;e-bVgd$ z16`&z+1$Fqi>CDycG0^<>X_laUt@M*wBxF^o9se9t=bUbn)Ey11eSS6TA#oUjG`C= zTuukd2{rZ$YrGaW8DE0&k!xQ`U>T_=Al;;2pzUNbAMkRxrIZs|;aRm0tlG?O*?dQ= z<he9~zPRUsXR*=JpkX{OR2vGH1@3p<V+^Gs-#mn<Exi}W&tzy0+6^QBQ;Uz5(}m?S z;|JZJb(3*AM)yOa-#Z-;?ity@skz&jf%^|ezn~WdXF<>KA{sl)_}E$tH723GV9;S+ zo`%Z+_k$Tnbgx@xl`u|iN|+W+#eIcT3f!7#^$1MD9cSN~xI;MT3w+leZ&AsHRv&Ia z*eIH#JKyt2uDipjF}=%9wJqJi$UJZ<+;dB~xE74>w2NL@BhLvPG#(hf4L4oz7d^(E z$$dV`F=*XE)`5)Tr2&7#$XC=DB)l&?Bwr2gABN`QzQ@pgqVHO;m(#zV!dSz{IVCVH zaY&;>x?Kp=@puO6mLye>{4n=-Qf<Ebd&I_MhR%>mZumuw{=yV02RJAr9mVcIklcQ# zuT}elz<dH_tXjnk??B9VynMk+E{x9P2kMR@`aRLnaKBPXEp#L>AFiQOv9M9phQMmI zb-34U*#@_y?~NO}SuE34w=9)ex}P{T)JWkOHIZg@8@VWFrSclj(?W=<Q`sg>Zketi zP0=31b#`Gj2>h+PGlb{~MpfMwz!h*mU^1cFb>J$%U-Ocjz*D@GP<tM@cK}DfQb`N) zl(3tZm1>vaPGIySf8K><mPWCzT<1$5!-cOvMryPqIwf`);K#ZHdFg`DhQBOocU;|O zxMy&8<37h^L*3s@D@5R1%fxqz6Pq%*ocl*E`vvK2kjlD$NwXMqO!qgZdxqyXW2MmB zjJP30r44Ts21V~XJ!Nhmujo?pix}!F?dwZ$o$eCudpo5UhJ|TSCfqSZ%L#FUm*}|K zOVZtj&*$nT{yK45m8+Bd9nj57bcm5DG;V|BHa9!F<>B%Y*eF~BDd3H5&%v8!OqXUQ za2|NQMoo>5RH~bMANK{_#u|O8)NsY?ZF!K5@6Z+-{(-qQ=#9jEQTKt`ERcjmO9`c^ z<T3nckdI!l^i~3$Y&6rfe&#-p+uGc!q}J*d7s?y{q1ql^wwm^Zxfcu?P3k==*@T>M z-HluV_fYtbjhk=<$dB>a`bc`6@@IzsZBRiDW)n?K;91?2YI%HvOe3EJ?HcfWxWvLH zxT5A>0a?LXd2^Eke{1A)jni=3OxppHMt6ZzPT(9yJ_asq<Q8c+kUEy`hE_x4kwIfz z=l6#HK=gN~7i}4X(aN;yLR;@-WspZar%~%=WEmrm3wOw0Ay8V#2mBfEv${PE%1rbh z*8X)Wsc}X4kfF&=Su|RjRyN2-;aA}B)^WNDWQ4{ZxGKU>@-K&O)CDfTTIw(;3Rc2f z!sLE)^Pz2#P6)%JU@v^jYwYDTj^F<dSUQ!BQWK3YEVfZKb7Q1E31o8mS!0va53aL_ zQ(^af2e^w`S*N1`7tJ#57b{!{kSLq<XLDz%^>G>n+>dBkX^+@_8Cvc(*7~)!yxRA! z?qL8&KT(-3oe&yPBrT5H$naC<UQ?R`at${XlRvqkhOtk^$a%4z!;I(;;O4kVZJ7n* zD)38i4=K;k{YF}c)J5qajRwHqxVi#DR-#39uZ9q<rd-fvr`4z&J~Po3wE?8sSh|3b z>p0CKoFKZIXibAA=(gjzpHok?mGq|iFr{!qd8j1QIOijI)ag8_3PQ(N0k1&Ypchp% zJTreU81$+wtHI^bU8{Qn<7*>Nvhj?y{sVp^Jd`Mu0!{5rxM`+c;o!$uFx=PlW-!?+ zbfd}`Z?Sfl-Jdc3ajJ$<h15IJq`X`pnn_v-E<dTkyc~dwr1t_O>PGYu$XmdpNDana z;q<Q4OpN=ucPKxjaYyY9>nHR)#yg!M8c%nuG^G{ZCU8iaT_^%F8h06~VYqp`qGJu; zZOe8H?Q#*HkxD@2kSF*jTw<PkfYc|o8SZ0{n!tr9Zy=Sx++ATt^cV0SYG>f?2<hpS zvh<5=qzKlcns5b}oJK0E?p1p0Jb+A`&Nc0QbCXe-0GtXgsqUB3!a{9M#~ZnojpOv< z<F=Gm25HT~o}l8tSqbkw8;z(8CVvrb34s<GaWP)jSZvxd;d$VfG`?lBr8JqhbC>Qj zxapWIr%^=us>WEgpUH1>+JyTB$ox=?KIEkn_tQ1b8o89y^4_|QREl^HUN`ryFT8AO zJKWG`8cl3@-=L?7rm^|+z+;^*0naDe-DwmX$uufr3?YyTZ8ydhkPh_ntIc!D8X8dv zCciRr2F6i)R1jwId=hsf@V{s))!LY`&y1FE18metC=OTH702hQkhBMZMbh@Ja|M%s zQ~3@qqqHdHrwOFfh(q}+GxGBM3P=^TPe8_Kj3iYy$Vbh&pXE9)1aOo=`U>14;Z<wR zV{)e5j-w4B^}Y~?@<cW=aPYPVm4y5Z+z)kM$Nfp#(H>KQ`{N$xbg@U)5#$yJlbzlP zQqkAJM)Wc-xy@Z}{RUL(fV@lPH-nl>FEW{)z?;&YmVVl_4?>7ysMOUcENl^GvsRku z05(RbU31y#h}M#Rs?pCzWu$2}K0td}`n?$^EnQt&9(bMbqPfXk>`UgR;kk@K*Daj{ zIL4rLlv@*xr#3dM;9ru3k*@eXw6ww>AZvnhG(dMtz(ft4P7xi0+tzJ7ae70T$i^B! zMC$UFjv>D}#1wQxnamxbQHY^!_IQgxLDR}PC2*a8TQ!~;PYH27s4pphBE3SO2Z2n$ zmC$+xspxsuzJn_XSI%iS$O3~-S>_qaH#yCxyVBfiYS+}Nc-)&XGD;IuZtZlz=})3f zEz^Qt2HerQmv#Rk|F+s`%I`6`hu%2yEo^>~=iwS>skFsSNos|3Gl9>Ac5tI`Yijfl z4<%Y=x7xTL3a5>n5e!A;GzLk#<2I%Dg=-(B)<pP3t$g^6Cwe!4qox>r$T#A2jwe%v zXjb5CR`@kEqJeNfS-K_VQS5egy6Y|Z$65&p%w+PQ?k2VKvF{LTCkb39(1(0&@@;)8 zwrMm2-fP-WkfXu?wa46l<HFhn(I_);N4Tw~H4I-8F^z=ALKC5B2n`CvKa-<om6D}O zlx)}R)kd|eR<75sTJ5IIn$)h+yjksr4caxS9RBA_>i<D1SE*OMUDMjFs-Ma5|D~$6 zDmQ7@tYNzvO{zC;*RV;o>P=S18IUkohz*Y_78}&NU$K5M{ffl&891mzuU<tu4e8dW z$DsbD6=VOl8{DN&=e`4qb?V+>K<6%ligoMAPS*il`WNjt>`aoEdiU-8dao`O3WkmR NS4?pd#7hwW{{Ty0byffX literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/gb2312prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..687ed12b626b3b1e1c0b26644c605bfd541a5944 GIT binary patch literal 1092 zcmah|O>Yx15ViL!n`+ZQQISAg;DCrk8&P^hh$cb3kb;!k3d!26-E@(6liCg_Rd1=( zpFuhDmwe^KU*N=yw}IpWUfF)0*_|1`H`{Bqwg`;$>(h@mBIE}iRwDrL2Bsds!U?C6 zlr*Iju_wLKPko1d8I)lfIvmKTY@`iJjtLKWbVYb1=+aMP-WZWi{F6ec4z>4(b7_j+ z!ifG^rbfbiP}8wc;MwU<c~MP9CNpA~<!41D!20mGckuGX!JyDa72~-nrqxlE$%QU7 zc-ys?jfQOae(?5P4oUtD{}$;(0D`2HlhnH=r<7CfUB#&{0`BwRiY#dw0(Mmcj;={S zQmndRlR80NWR7>hfjdUWsh`7Qh@qEc>D_qWz-fFFEaA*T6D<ksjZ1P9qlXiSN>4gX z8|wK?C<V+D8#7i^g<(u#Koz2`nL9R^E)}X_cljCvEJF$|gtDO$S{Ps=&_bTV-efG7 znbwSbC%=xmrkr(W#cZ#rw8^C0%fC#jPv-m(jc&5fqT*B4%|Q(=Om{Lyx@S(5{n<jr zko*ZujeyW?x<zApvAa&o{;K>9evqR+eu(9B3itL-Y*c@zw!zk+DuK=6dTGPaCRhpF ziB(xCo`FSsun_O!!A8#YxBj2E(Z_bu;$MklnN^c{HW4W3D(U7$S8sG;)C>z`%x*DO zPWfCSP8d6%XR`J<?raQPg3@N8?m}F34;I_H6)6`|g6hb|s<IYhB*L}EV*na^B&JD} z1kQ%t(=Nxi1k_3?<jC&SJp)P`QPzKu>nMB2sk_!dbx%bQMMHyO!@1CZE2)taBz{$2 P@AV@r2HPN^?(u#DvIhe) literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/hebrewprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d8f7e938e5ca768207602fab4e423ce802402427 GIT binary patch literal 2926 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 ZfZsU&d?ew=rF|n(;7x3)8^@(?{(ta>n!*48 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jisfreq.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ad840bcfbb46f0a00ffeeb4e4c091f8551d6e8e GIT binary patch literal 22091 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 P9G=JT#-d`!iXH2Jm^#X* literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/jpcntx.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..306087246bdbabf9ff32869f125441ede511f39b GIT binary patch literal 37970 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 WZ`2<s-^?Ey+@Ha#cb&cKq5lC&FF(lu literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langbulgarianmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..30acaf59e8dcbf3b91e4a344a7b54cbc36541cbe GIT binary patch literal 23584 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 Cg{|5E literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langcyrillicmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5a16309af32315236b1eabd3cc77efe1d54acba3 GIT binary patch literal 29040 zcmeI4cXVCVm51eST)@VJl0YB{&44flWK2T97%&*yn3yg|gwT620yU0g8<R#Rg%m>X zy(S@{w@m)Xn%+yM7fqi`)3i)4nfkt;MSig7+?#u4fms>D;$!!-_ttqw&x^HKIe-3~ zw$@*r4<3BUzN^~WzJ>D2U$a`miq=2F*SFAU>uhUG>73G-+Bvl`t#evqdgt`UjLsR2 znVmD6ZOxgDS&i9^T^e&5bMKqkIjcEk+%j+6GP^l-+%kXMvP*N?xMkOI%beznam#Mw zmbuO8<CX>EmU)eZ=d>-}{m`~4ZEa)!)9Nd=gvuEE@7D%TeXUxjRE2ZL{)_U{CJkf% zNvY{|@VyToyP;KY>_%`CxEb66ZUwi2+rb^+PH-1E6Wk5ffP28b;689acmO;I9s&=8 zN5G@tG4OZ`<r^A1owz5#O7Ijo89WWvf@i=A@GN)^tOI9&=fP><6z~E#3#<k&f|tO0 z@G|%s_(AaX77F_t`yoPp82kwMQSf8n$H7m4p9DVzej5A?_*w9C;OD_FfL{dP1iu7+ z8T<<PRq$)z*THXq-vqw}ejAK}-vPf1eh>UU_yh2V;E%wm;E%z#z@LCW1%C$q9Q*|s z1Ahtr3j8(r8}PT_+u-lO--CYu{|NpG{4@9$@UP(Cz`uj<fd6P=+XbG6`ZgfxElB%< z`CuwI1S|q?1=GP^U@n*q=7AYt3fK)S0K0%$U?$iV><xJB#ukFz!5&~A@OH2t*b^)R z?*RvaBfz`CVsI4b07ru3z+vD7a3EL;4hH*!cY=3;!$CVZ02~UA1<S!Zz<a@o;23Z` zSOQK0M}t)@=n<^&4#g0*`zl*d+2pId+pY5RE&K>gz`;G3>_;$hhZ0vMacL5lD{+Ss z_a$-R5_c_eI}^7lan}-eEpeL?w<&R16IUv6pA#1;abpu#FLBKhS2=O-6SqBa;SyKx zdn|%Glnww~ki>0D+@{1`OI*>!T}yms5?3m5PZM`Cap4jdIC1L|H#Tvb61O;UPZL)v zan}+zF>$jKpMb>8PF&35{<xiqk4EC-lK2E9E^y)kCvI$70Zs-h!71QWa2nt$r_;e1 zU^O@stO0AmI&c<P56%Yf0~^3O;9PJXI3HX9E(8~WPH-`JKllLX0+)hra2e<U4bTK1 z1RKHSpch;Lt^|Fc9}Iv&Fa)jwmw*I@!3fv{HUr&aeKhVuy&F6Y9su`(`@mD+Iq(p8 z7(4<V1&@Kp!56`oz!Tsr;H%(Ca6fnu+yh<$&x04i%ivk?40r+D3BC-j23x@m;G^I} z;KSex;AU_w_&E3h@Cooq@G0<Va2@z8_#F5=xE_22d<<LzZU?u3+rS;*CU7IT6>I^Y zX<_Fh*jj{cQ#o|k$}xkT&IGf-Y_JQM1LlHxU_RIt>;@Kqg<yBE2<!pg0`>%ZfxW># z;H}_oU|+BwcsnTXZ+}7#0Pg_r1n&X|f`h=p;1F;qSPTvWhl3+PJ2(<70Y`zQ;An6R zI2Lq(W#Bll92E9<Jl=PM_ka_?d%=m|B(MUU3|4|uz^ULgunL?G&H$^ynP3fA3)X?N zz<O{tcpumR&H?9w^T7Gw0&pR?2y}vr!TZ4nKo__abc4%44`_fU_#oH_E(g8fE^s$^ z8ax2*1v?+DDv#E-Um};Vuq#0y=m!H}5DbB<Kmx;H1Z)DEfj;q5TGGx(@Re<7C50&b z{Mxbe5uETN_-20;{=YraSMWw`_xqw(>NAwO8f*nOfRBO?fe(W(fSbX!;N##8`zE;a z5v=qjP!FTux<YB^BRJtlF!#vlBeVm)4(bm{ck)5J1H26MA=XQ+Px9T^^oOo{ko0lZ z7dd^V@5A;Ha6ix|Uf=a9e9_b&=N=^OTJR9K7=$mMdMF;oaVh8qg<nJUpgclI_(EFv z)_sEDN5Ln-W8hQZaqwyIMQ|O+eewDd4!wW+3if5x&w?kw=fGFM=fPLO_25aMH}NSX zy_ov0d?V^Jz~AO>LVXtK0eueX7Vtc{6}$j$122Nx!AoE>&<A_xBe?Ss<T4xx4gv>* zL%^Y6F*pny4vqlr;7G6p90itwqroxYSkM8Mf#bk(Q26^p?~9%mUHR|(KOW{D{T=Y$ zpUV&BJa9g^09*(z0+aa1f4zTt`t<7Q!PBn^J^K1}q6bQEm>#V==s?e$-akEQTd?V6 zy#h(UC9g#41N~qC41ytW6-ZzhjDSrbK7tEc|B0k!AOCfC_2fzVg(2jM<{bJ(s$fgG z+}GLmweRjgZRDU3A=hcnR-xyR<})hfI>c2Zxk|ZIE4aK=eXqNhq+UEn@D{2e!)+91 z1V<>KE9xrcl5)#KUO%tqaQBwNfVEV&TPw}MYNP5B!~UwKxykL3-1GKGVeM{cf<-Ir z&ua?%^WkrVRCPc#X(&x2xIj?t2x%J2Hc27a%c-yf6{rwbA*9y1s^`XYQkX4-cn5Oi zf@M=z4%WHBX0N3R^D0CcRfEgp>X!;DnQYbDkfib++BW|Hyx8(l?X5qwbHjzJU#fgz zVL;F3c^zUY6qUnXb)PGs@`k4@msGht<n{B0Q47_ugIt_96ui#$sO2G!t1x-3;0pC> zg@idOsA^YnmI~7xB1uqxx@NB8o2?M3Rp+P`Twc`umB-mzIC;6lQ+g39Dm5SkD^4~; z8B$%vO_oc_Ef0D9ycO2u5YKB#-77@4oaE(%4cU>Cst)a<RWl|r&daGUd5K|bF69tQ z>fWj)rD>Bw)hTNQmlstp<srcvCJ)1S5#^Fba4DaWOVb(Uj#_in3U+IgBNYzgZG;e= zE1Q4t4i1u=RB#y81?-h%hYJ)+wSo()Owgfum1`+1OpdS@+a!7XupyU{WQ2ObQEQkT zzdui@#;sbC!)x;X6cW-rz6(fluu6INUZ+B8t;9ur?i(hB5yB$8rb5Z{dI#=aULh0+ zHlHhp3%uE-Fji1=<J*?of#%iq$ssH!7vcg{S6Az@RxMgJE-Wml-c@kqR2?ZtSgcj= zPm(A1CRN3bs&h<EocpU<FSiKWJbAFmVaThYB{|J|k<EK?t|b?6TyBnXZ!V*%O}$hN zR-C){hJvJa9haL@89q0tawyG{yQpn0P)pkG0<}&H!5TFzM-7D~h7hZYQ-&ai&v2ZJ z25-o<>bP<#99bSb*<SB2EX;fH4kUR^UWtQ)H)MEJOPVNbO={IqYXw&=S~X5{<W?t} z$G7SX@4#N2D^-$b3mdZ6ju2dHgsQ=l9j8$}zE#__CT~p+jVfD^ycbJ_dvO7U6vmYg z?X>c^3f}sqyba}gqOdTj!RrvUX0JPSntvWX$X-is$W_Xv`a_r3tL0U@IjAeQX4RwG zrUE`!4llxS4v{2>C95IsO{{7gp4Xd{BQ)+{4=pJK2Q^grzEVAE`02}`bxJZ6XH}AI zp^8)^EZdF>X}Ps4O&#RCvW3dq9Ty7daNjyhA+Ed^r8&eq%~c6DFVPO$JbsYE)|?Rz zx5JV<wM~*8p_iaKSf>fOyC$209ak=ehH`3XGK9#hGlHXBt)HQKg}vC}bAwH)FI;Ya z>MA%~FSkj1!|vr!hR)6Pq7XSMY{Ma;lsm9Pl2spMTaa?9Z7z_TNO56nigV9}l5&j@ zXH^|Y6$)GPHi8r~Trb4=NN3m<f*oRqY<2`yak*W&fFvEMI2W+w9Y}J24#`QXT<CBI z3dyO34p(+-xnSEQRX}J%<-I>kit{!sxiz0wp-Be^DKsRn>e=C5e0c6i<vOHLb%-RZ zp|xCr5E8DGOL<|Eyx8CfYA7$Sidu5d&JAgW8P4@=xyp{S<P6(_R5iqLI^4^VWYuv# zNH#kpsfuk1RuxIkD3n56)s;9cNK%c^nuCMGYGJ1##QXE=Jh{99F5otD^V*inuq{YZ zl`E+NY6VxQS1Uw^ht-9K{9}|u@alA$GaRg<?j>Z{A<14zKEw5LXM{ADDtEZ3GeSc_ z4fTSmQPrO%hp3diMmV?XZ0^e24a4{}J1qI!(4Q;kg6&nO<sm*JNLGEg=8zgHdsjKh z86nM`N(#Bb>nd(2NTIyE6NDQI1>^|l=2Y99;d>BfQ{#>cM+Vh#p-Oq2y-t(O^~yua z(+a&V?+{Dwpn^@oTB6|l;#^6E4i(5P+qO_Dr-q)DYnvpiDv-0~93d{K&d7CDXmc;> z)T^_U%gr6GIPWSa6_&EY4aw$%EV;65Qk@p!tOm(xAvg3A(n4@hy)~8h87`W0sEQp9 zc6r;%rH~=D+%`EO>M9&m-f8fLT&voP7Au?Al#>+VT%Tc^B^7Xn9Zr*!3$ZO1k}Fl! z77ov;xl$TN!Is>bB;QUI@c5FPR#-kbTtE&ZwBhm&sW167j}@xOVFa&K=jP(vsU@f7 za$QA|(i|5$2*HlC<N~r;bsM3mLW0-z?6A#}OW7vLs8B$`ZbOnGudbe?aHJ1%72Cq$ zcGQw`Roq7KTD6orE$7YIa=EgFV5#1kKdZ92isBsXQi^lYoaA8Ft009^R$Z^YO&Phg z3JvAX_3B*NE3r373bxIaLmMG3RQ8cUa$Im!P~AZYc9V8E*pj`HLRv1)i?HN0Nx|VN z_S)uiZL1~ew2%>s2GzlKNV2MsLYoUrP|EdOztjY)gemKvyQ4DHxG$Hb(2yP8kcYOU zw4jDk6;u^)m7w|zhq!3YX0LODZGx&!3(N6_LebEgR2K-rQk`KbIHcx|EYApD7tJ~3 zbx2UlGaQ_glpFRZn;lA1h#i*f&Fvs}q-~)}xkJGUDNM81rGk{pb>$FTL3OS-RK5sj zxO`QcGlG;WP#B`%!i++P>gBvSTR1$Z&af0hyhMd~yKX}c7qH|~wpnt4AUUnvk@Kp2 z?u=mb8HEmqluIh0y@chIr@dib^_QEn(3W%L+AWU@-k^qhzGlI(<5e{tpsqZTB|CB% z9wuazI~;7u89p-D-Xv;n5w?Zy%LlYK6v&NQ7;HyKb5Tnnq+BhmT%NW)-ohgb9XhSt zTcM%X7TDPL(skcBd&Rd;T6N9LHS1R|Z{ILFYs04D;ok0n#WP12_FUebx<&@O22-P% zy863^Mi&mHW>2%x9O!Ab^pVti_2`}>TZejky8F6@28Vk`dN((_Quj#j;OL?&o6VuF z=D^0j-r>u;`kEsn%``fXlEclBu7U3U=IHFc?tzV)x;HkjnYX2PpfR{*xP9r-9ZRp7 zv-+I%?aP;U9N*qCI(J=n&na6|Z(m<;&*;q6E7vVwwrtzKJ37u<Jb!dA`rgp>e_P$B zRg!8M*WP`t4hK3ip8fiLTE@LM=Xc~1<yp2Yle1uap=(>St{ZGL`$p%i8SGu2w#j>3 zu&v8iM%-pyv{nti*0|tRo7fgMclBlct#!Og>FAL1L|ghM|1U%EomERl`iGVb^$xZ7 z4h)ZU_w}{+Y}q()#mH61V$?rfo13lmrzLE$(HvRA&!uO4>HYM4<j~g9*(bEbO?}N1 f_it4l=Kr2KebIOS-e>y9+NMvP^2*<{w?qD4+%udQ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langgreekmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f3e2935e90bf0d056f279d344a6d7903869b7bdb GIT binary patch literal 23542 zcmeI4>z9>f8OAp-AQBivnRK))gKQ)Z1ePg+f*1#t6dkE?oc%fs%!y|<M=dS;1N3`q z`MH0g`b*|(U)rDQTP;_oechlxyn3FOcRPE)UEtzc_u;y)=f3avdEap@U9)e~rVXv$ zpRxDvJ^Ahft=6C9eE8?Kp0T(0ck$sKv|D4X_NuW}?bTzet5&tTy{0|VUfW*RzU{Z` z#@1A;u13~hjf}K!Ki=B0VS8&;tJVE?uRisR#?bxO$H}Wd?)D?q;N0#%CBJ51(EW#` zM*4y4AKrbwr`K%@P6>W4cui0VI)c{)^MXGJ&IwKmUJ{%YydXFxI4_tM92e{tB*6v2 zxL{H+EBIp%>NnJVTD${-X9dp*9u>SQ_?h5k!IOfEf(gM9!Ha^Y1iJ-C1&e|w1p5R( z6dV?u7EB3F2+jx=dQk3f!1txWmFkb8r{C=g#%kv%-IDGz*DdS*P4a&i{8;cU!To}R zf<rxs{dIrvku{^l8-h8(*98v=?i1_~d{gj>V7oxyiSACp_XN8H_X>JnmR9#ig6|0K z5qw|pf#BPMZwN*Odjt;(ekypR2Pxz)$=xFOoZwEuX9aHx^pLw>6?|Us1wkzKZdscI z+XQO`pAl>p==0ZIC-|B`Z*BK>!Fs_R0(}R&`UG`13ce!vqTsuNy99d$KM`ydd`a-- z9>h-LBiP@Kh#RXTuPHNk(3iS&xyr9qeT6nT=#OC1!%KQvNe?CI86`cfq{o=_RFj@j z(&J8gcu5x|=}9NuoTQtR^o){jNzyGzx=2Y6H0fC;-IAmynBocQaVOoYqziJLZRjOQ zcMEi%lirV{+n)5kC0+ES7b593h)bRH9wl9*be}*kPSR_T^l~P>Oi6D_(kqnoRwTWH zNv~Sc3zp)A-7QNmPPxB9-<Lt_#chh0{ju6PinmVRm-6^grk_XGP#%}NSMY>jpCEYq zKeC>b^_1X%;Gp1X!6Csj0=@R>u;7T`sNk63S;2FH=LN?F`lO{71TP9s2woDrEQrtl zE3!@s^g}c02Yu3y<16>&Rap~)*94P-wxANcE|?OW5=;wD3(g2;1haxU!MtEWa8{56 zi-L~eoZ!6Rg5aXylHju74Z)j&UkH9FcuVlM;8%iQ3*HfEr`ubbd*8&K(MrF$1<T(- zJk@v}0pT`)xFE)h=aG|&M3Aw9hl>=kumCEEVby2h4bY-zv*HY5xY1;TL{R7y*Q{`J zljmaSt%%kCk!&L@+!(7K*s1X%VNyl1@j?oLuz(=rnpK}Q@?c!+-dx*D12?(~mE7AM z0(M5uEzTC?Pna#1Ehmv%N$BMg#EfDtyn2f=TVf>GRXhrdg=;{CC7QY%)U={FAQR=J zD2r^kxeG@&DCU}q9hBQfE@ovn)@1~<7!}JX;gXHn0J0Iw)ke&+H+KAGpH>`;*=!|N z!Txgh4;3rRxg50Yv2K_^ZVrZKIo1$mc6~^MMH!+bsD(FV7Q=*Pz%V2tW|J3HOdwpy zTsV`bEUc!V_0Y506?SRdEP9Cq3o~ByXE9vMqJo9|3Xi%X@{GzvSY*wLUf`J(uEh`_ zfr?d-=xgXu>8oNe<e1H*m^UnjHZm?2Qq)Ea3RWbT919h!<z!L$|F!D(cN6v!_rM_9 zu$Z|<!L<=6gJQ8r#7~G=PGljQUcGx0w#zVPSuc@|7*pD)CO`%MV#r=hCETVzX6u)D z6S7Pmhudsqv1l@4;bK{qL|Dk@ct(a2R@7Pyms(;gY{iiVaiqn}rK?C#L4p`V2f4UE zOHgK_MVDTRlod(DxqO0{BN91?HsFPu>z-Pp*m98KB{oWf$@{NpAX-mhXhy}dp-C_= z6tZUJC=oLicwr3%#HcjR<a7_kVkEFw2{Ghzmhm`ac&ywA5i0_-QJZ^v5Xh|#6>71_ zV)1qp!>X@^H$aO4b5<Ob+fc-47uPI0wM5iLECAjxS~h~s#+1g(ZPzYHRD>R2W#L+O zc$UaYY)vtdjhZ7fK0m;bVi8u0G6~4TW5t@7mtibsZVX5*+px)l!krA)%8(*!Dox!G zXi6R+kFA9$1F|(@oEv+gw%9!s+oVZF77E!<vBieWVh+Y<j)<`^TvM@%a3P040H;wg z6jltwSd35iP>6-a{=%Y`y<nkYWw<6k6fQ$!HJB(U#g#<DR3Mu*v{$eG`LctsaEq&B zFDTm*NyOI3=Byy+5)mU2Je~qsC{1H_q$!7Mz!|nC<Cz=nvM^L~oklGb$}C}L428=u zF<`ii$~J7&1_@M(iwFuGz@yggDHIxlOg3V<I|(IcSw)VLi{(yZlaa;6LMmc_C2|8s zr@3~6OhwTm5vSpX1&}2MnJhh9j3$i|ZVZjZaySDD0`w9w+_2(E1cE}$5=D6{<M8@~ z@xrA)YT;Q!R6x09t<eAK9lMV!kh^-Uoo8efO`lej0hF0C2`nfUL(kqa5>$khb4g&? zktEE5$Nq9}l*Nkukw7_)G}qcN*T{&%BW7eMSUE~AMnzwiNwLXLiEIw+3{xRXB6mxI zX9=t2@JN`;m({YIO9d8X@DQMbPiPe<D(YDqIo@(ak!J_RGlF8L<;oDvN%a-u*5%$+ zld@iNZRENS709MyXW&vn45?xkasvuvlr5HX8G-#ZI4zdLo~c03PGg;rjWUcb!(g$= zn21Diz@RkX6$LE8vg<ntUXC0w8nXVZ!rb~Jty8;0c2H4@*3gTX>5<J@xzp@OTLda3 zLZ!hDay_GGR!+|-eYxzVSk_m6MHNf19OT0?mogH>!eZkrC&;)~(bUZy84Ke`C|D++ zOIWP<6oLns@~7C1o_PSw%j%ZhJ)$ASX+>o!!orOTVrC(46;=k1L|C{v0VqYQ!E8}$ z7pbq)AY)lWB<dey@B(N&XTdYFor{YKv78lpk*M!9S4#|)h|w+-tOl*2S1(nc<w*31 z)mv6!F12)kMK&zEYnC;)co4h>6kBnzqUkedwx}?9TEl8U2{Ns51~H=`pR<YreW~Qg z#bM&eVwNWBDfL-Yau%1%ww5Ckt0&iI8>pCoxh7D|+Fr~>WjPjyhZWG^Aj;x!TvUh^ z`zul`QFJ3=SxzH?MHVZU&BdrNi%Uo%1W+*-9u{O`W;LK##n8I-m#{v&azn51x%Pa` z&5ae59OTHv8Yn|9TCt7XN^-HBO0>~{JeYQK9n{BIY?0SjYYj%VgL3k@7-hvXio+Bu z5N&ELTdIDxrfu9To{f)N9E$|jvb!IkRP@3e)><TrStH+aul`Q4WiO(*aZ7Lyu=+nd zYE3z(k~<^Ha*3S4t=J0vNB&!j{U2QH)cb$_{a@c%{LAA9E^jz={MhK8J-Z$m-MzH- zV5+J!JJv02nLIU-#yj)l^Qm2>@!5%mr7a7onylK@++@}BJ8Amj(w&`43)7PmGvf>M zi_@Ly^VN8o=uFQqZ9P*}3**(?)XenasqvYr)2Y(ZMoBJKo$<Me*=lM1%*5Q(xrwRj z^2Q6(bM5&Hi=z)bxa*;#JJv4Ub+{)ow|o4*TiDj4ij_&-5uG3Ii5{76S2IhSuZTqS zN@UB4E5(F<*Gli{Hy{c=*uS$gyRdU%dSP^WZm}~lGc!7QVQTJl=j_7@#^3StRj<>u zQ;oH&&Q6UmrG?Gv$om&AEv<jFXP%p>9=oR}xu{=LI<j?S+sIq3k=3g{{Ac|&_J07T CCk`C| literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhebrewmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d456a4297c0cd6f0e0653fc409a54926e1ef1e7e GIT binary patch literal 22171 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langhungarianmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f83acd46159179479965f1eb946b3f213a63d1a1 GIT binary patch literal 23573 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 JZ`%LG{{zjSAGZJi literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langthaimodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0f85f870e7b50753b0b90954dd48ae40294f2a51 GIT binary patch literal 22150 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 Urhiv*>intqwWhXjd*Hu+1GHPZ>Hq)$ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/langturkishmodel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..faee8f4e1bf6485a5c7df7b41c9f3dbad78adf68 GIT binary patch literal 22173 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/latin1prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0ff4af6e1c7648971d74e31efdfece371115dab2 GIT binary patch literal 2883 zcmc&$Pj4GV6rY*><Mn2pxFt;+QYc)i8Yzt`6;Y&$Cb<8Q+9co<q*Y*WJ!9ADdhN`P zDK*Z8MCuW~0nL#MAA*lDH^c$u190hy_h!@B4sD_0z>enm&3kWV-u&L5<l|B)B=E&Q zo!@*mOUUoIIQl3d%dp74VuT1HXhJ$PrWARWu#OWuz&o)k+}IN&_JtQ0gdYbWD~duK ziXfg6#W)gST$29(J__>n$GF#leEl)L-vb1q2^2zDh0?PVwZ{iqN1%_u;<)a0*F`xR zA)Gf_<=mvqAJd~Ilv86P0*}Vm$WO}rF+FOcA8C`s(_$)~xkW@IN_#|<B;9r5vY4)s z%FF>I8>vuJsy?Wzn$+v6dtWLLM98(%R!!HnJaED4046zroFoSh5)X-wq<|y<Qdw3g z{nrFHs#g<x-m6Wl_C<F1Hf71^fS20gOLAk&y~u8K%7`1;jV>D9JCeQH?&!P*cyaV0 z%=l$@fJhQksCM>*G^wD1?FF$T9O3Sf*p;5}guh32Y3u`E5P{_jq9{Vp2VzP@@LPOB zToQ*6_mYY3)O9<(l*hY)e&UC}cq`8AJP=JZ9g<!4l<k93kRjoYrS6bC^>P`UM^`Jp z@v?qTDiy&t6L8*6+nRGz=1D!%yaD;e8^C6!#G6WP^G3IyYN?E;WF|GFoSVs{3BN_2 z8*=_LdA72oJH4e|ySLa*GhI)T#m1vnx}~=-qtH(NjZ8&XE#VbH>ZQcKtY<U%V(+n< z28ZhSAWTt0r>PHPaB3WYi_hKt8xmFA_zn<_ZwKUCRI^!&gLa>KL$Yr>Gho10ZQcVA z&f3OpH3NH0bn~+tpYrO;24B5*SCv7euz=JFAQh@kA`kulkeqt1Y5|jB8WQj{qJxtY zzFNE{9L2C%N3l)?wayH}Pikw6SFXJO;o>EG$BXYX5yA!m;Ay=h6WE`jhlCC0CoUbg z`p3IX{-BrK7$o(y)vvc?Z|t_oa6GqYSYN;l%Lk`@<$Yiv{m78+(;fQl`jB2HU*6tf zkg9B+>^PbY$(EyC2$OS~fW#fTf<9zwS$kVPgt4#=`?rFj>w#9V4<O&Kf-NTZcKHj` z6#+vh52$SlmC!6S+X>_=f7I3wxJ+9~JA1$rsX>;R!wB&zfVt7F+B`4k0NTafu8>Kd z6UFMCm0Hav1eTfcSJyW9-5bW|kl%0^W(m|1@)ggfhzagL))Lgp(1r;y6o;kcVkI5R zAmcWr6dF#+=710y!U*gP;Fr;pG-QJl6Vb&TM^Qzua9XT4fdM?A4Qw$$u#DNI0jVu_ z7qA~fK|Cbtf?zu=J&RJ|%%eU0a{|bEv*Zj!X@TspArlNN*U=Jqf7Z$X<-%&~yV+lE z{WjRUhG}oV{BHtg^`YqUa%=O4U;n(Y`NuWD<XuoG^iZ7xVw|ksv8Yv?94=3Hp;G`* z-L%;jGHuA?5KXrr;YaH4;h00PBI+`P%V%>?djWNwfDRTWz?$4!nZjm=#RJVQ<h;`r z{RH`l^X+~;$u+hK*|IkQbSCJN`ms8LPk0jvwp#Tb5NM8hXd5y~I3M{9we$uW*&cx{ z_G_3KG69YJz>D0-4W@1LU9FrjrNes7yP$14#*=BkljXpjhK<I#cm1Zq95K#Ht%{@u zr209MHC!TBTT^d?i8_nqEhKp9$g!M5w@h#~fBZ*imc>9K8Zno-^w@C9^uLU`qC52$ D4PHeA literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcharsetprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c9f4a9c111619564d0f1cad1dc1fbf97a4928724 GIT binary patch literal 2188 zcma)7UvC>l5Z~SVle2Sn(xiV<0mXn?WQim^zynf2&?K~xs8b~lNGH(h;@vpsp6}ef zH8hs{LW26lXTW~sjgP?R*jJwN6;LIZSvw|?5{XTAZf0k9W_EUd<42WBnZSsCd+_~! zg^<5cI3F%BU&1Ut1|o={De2OPQsi06x=!SD-N>cnF%gb%Pl<3PJ#ivWczdMopHVng zr>3%T6stX{pQ-#nsyZ_va!J<S)3KH&d>Xfol1y5u1xIEB{o^RU1tLjA1&NrTks}sf zlS68KmLk{kp72kD$dkU96TvAtq0t=hB~i9~Am&AQN}`geh$?)`uZc^dd5Ch++<w|m zb@J#~%S&+%YULV?tCd#OXfYceA^3Hsv-k)YO*9>n6V_ovD(J5^WkbRpL4dk~3D#!7 zd4fO)P6LuOpT=36A10}m>I}`+ed87Vo>a;M$poAyS)w^Nw?tBCl^pbSl4m^5;`DeR zl_|Ay0XgMG*OYl07n-*q?T~G^km;fF(Ihn`&Rd`?IRBmey}7Qtz4czwTTQY;$7#CS z`l+3D^ovh$(N6xO%tWr%(Uy>Uy?cOMA$89_=34JqmB8|cFpB^Pp-a?<zrnj#CvNTh z8Z9gi9Qd8(?jZ>0xf`)DD2JrusC!6fva8lWb|<oc{9ec<Yp6M}QTG)_GfADNBm}JH zaRG~6g}8$%D0lo+acKd`B9a?GR$&&ni_j`urflcn?Q5=N&0o3?-f07EU=W)84228t zO!1wU8@b-@_EOoEnU-Qpsa#ECnFKM5#DvpS^DOSlPtlyMH#Yd-nm{h@|DW-wC9r#q z{{Ty}AGhUa7kpp$uIGDan82#Vr?7cokdc>v+Lxs#@V7~R_~R8Ipu<MakPg{hGN!Mb zp`+c7_nfH)X#CNf01R~kn57{bLz~g%&OD$dd`4bW?cNIP6|h>pw7LMRumZLh$K;he z1hm1*2#^SVVEu-09^!Xtw2acw9Yc6vak2u@2xo;Ly+eM%6I1<n1T45y3(Q)$3BGTE z?Kk%9?J+@abZ3m#SDw4-&3SAf--HVA8iV)l7d7~wz^8VU=o%nASG8Ez4xj~r&K9u3 z5<2?_M*Xhw6g-49PAW57#ipFemzo1)p;=&)G~U+k?#{09)4bh=Uf>CN&~K|{P^p_p z5Mah{>@@k)E#ps48h^XFhjQ@s&VFN)Z#Rv%*ZgX?X_ng(x<_9rC{f!*&@sZn!pFFW zQVM8JwtJU0x0+iU&F#ixv(U~pms#F#A8`@u*i@~ZJUdK;%v#bc?LFDqZEoy0dGpEc z76{*L);$YD6X4|`E@fx}g+Fa&)<b}0%`pTEjTt`F`w-FRFpD)H*mxEJsR1B1pswYR zPF9xK3N5oL3qb}w8@zQ5gz##Ypo5UJC5)W|o{@~`cnW4V=_U_AaW#Szsv?*Z;L^eU zYrJ006E=zv8$RM58h)AcZZ7&M@*(Fh`f)nd%yBOA7U#AH+s<VIs4V!=(8m{E9}{I` zF_mfiZ^<-;W3z;ww?W$h5xIDzz|I&rF01-s5W1loyki?`1Adw+mwpBmX32Om>vs!V dYql!w=Kp+5IP_qGhm#9^aSz>K1&4Ie`4<z`5p@6n literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcsgroupprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2a808549e0a1aad45702a72873502dfa2fa1a4c GIT binary patch literal 1079 zcmZ8fO>fgc5Z(1hK5VC@DF;p*k&M(vlp?hfLMSOz6cJUV719c6mDo;jSSRkTLj}qK zDV2KSHvmWe(ux}={sJdvHf~yVt(m+TuQT)BOuNzW2psnP!TaA;LjGWIbsPZC!PHl9 zF^Q=l8D*3rwuF`0%r@8-PUbS#U`JH4Dytgoidt4@b%QIy%Y5b=TopmqU=4$7Vl7)| z>ju}woos_`P;y9OFZM4;>?d?#vt}IhNZ9yGp^cF0X6Hj+_LAaIPG|YCoDLERS?~1Z z<=%DFJ9^byMgEJ^&e8EI3=Z2nk00%<VtoDj?RD5W-rwC{g<d-yJy}I~_vGC&jG&*@ zL9y_t``{A7XiS(DJC|fgV=J~V>dd|*4q*;ZarOF}cBglPKsU0?*M#724a^2p2jB`) z&^cLHV{1-h`VHhS>;)+tFc+)>Rt2kp)xo?48P(>5`*ZRm_(@P$sAzRTB46|;BR)(; z0g5%Wt7ds3r4Kc9jq`Mp7Mx40E0K(J(N)mFVi1W<$vQgR7+uYc@=CihQArV6+EIxZ z$^c$MtvctC=qttfFY@o8Rb+W9PxGyGqKdu{ThaMwGA_<`F=>o{N+$7Cwj!8qoD{8W z5UCLkcv)sU|18(wpC5v$yWj|IS`NMWc-EJDw^ZG}VinRZhz=wt{Vd^Jdz@#}cqR}B zoS)75V)@1t(T%eCC=miA*@SY&g;X{XV*^IF5P&ihqbBZ#o4Sb<K#?2WOT41JSuxyO z(lIJ)PmNPmCQxzhC$nf=GB)z-U^Kv0Eid6P%%zXA%;03SALX#HWd_Hjy#efOnZS{m gkBaj$gYz@(UNc)F<fUs*m(o1LMOMf+ptm0TKOndX)c^nh literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/mbcssm.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2cb60c93c703a0622ec099884cabf07ebc0ebb9 GIT binary patch literal 15634 zcmeHNZBrXJ5cYx3Z(!ar4k17w5S)b4q)8{4b~+8zd4(inlj)46Gah2e2^r&1>@+R^ zp#PyW{oH?(&-b;T?l1IHwX4(VPUalH5aKq+%}FcmKD(=xv?m|8nNFu7{Ez&(`qS^_ zNaSy5$iMfT_@3YOYBCa`5o%N;2L>^W2pu2;%y>P>?<m|9sG!^AJpGokh?ZKsbtOw; zG)m%ZfSN4E;xtC%f0!ge6C~-_QdWfzNiNB~pecthZM3R&zk=FQhxAvrp_YA6%YJX) zNwkhTNk;0^c}+Gd_ehEkks+3(!z{&yXc}WROh-tX4$>sQVO&z5#Orm?*d<QZI?mTG zRzlNy02%kLtdS8qN=8|l&(#PUrDN#t7#%0$P7KxD>eh5GB_Fj{#>fPnAd_sICfNj= zq?4$5icXPf@9gl1z$I6b)S=h9EpHoS<;dNUd2G14#H#dgf>2&9E?xPOWau=RVbe6j zGHiy<;E1v`OU^kuU0KJY;Mhr@yyMVmDHC<0BlSy;uWlM0=<`ZQw6Er)nx*H+d3KJE zYL=a+vpA|bdY)YHj;d)Lc{NK~AAxL3zTa||%+ootz%KB$H_sO61+=_K=gCEC(hT<p zatPlu+Bm#zX~9?1l(-~LwlN=>s>LZ~$D|9uL7NU<NJ=fdM*l0f$r4>8%j_bTUSiAi zBKm!a`@MpQ3@^L!+T`BAIADBOLtFGXCHMu}7x?AjNh#^6;K^QBr}Tc6E|JTO`^r|? zWx9;suhB~+=iouk8{<K`LWk)pz09qGb@KzG^I>&ep0;n!cz>sDv?Isr(c7+lo{Qn? z6bUO6u1;}Mz8fr$K3-BsH#J@D6vgKquTF7ZdAj0lwL|x0)0bh|u?8}g_v8v)BUf3D z=GYZ>m0rO;agAOrMsn9|gP*%{hBdsiSAMl$W5vc^gRMn)?-6i%E^MwOax~b3s$Q_C zGK4N;U=P5cqhZlS3}D`D44nz_>)*o0)fodP!{YxF19w()rk=ZSRRZ6JRcS>x_g~)1 znbuIbx>v848hbCQ%o-Mr%3itg=ExeVLr!&ABjs0nN2MyOIqhg|@8C4^t#G%OoY@QZ zQ|4Qdrawxmh{OJFw`d)McC~ywxj_GLQDYVxf${cbVPjlI!M~0RI{~mUx9C_w=Oz`x z=5MyVrvZ#}csOuEf;k7bF08s-%9C{6eCs)eskk8!nl`*$w9Kt%cW&Mh$Jf)z1Zp34 zsSg!&i49@>eD?dmu~e;`UMS4gm@InH5{OkhDWtsVxs7OG>gmq{raKqYe|O<3!u14R zAII{~x7Hs$JH_AnpZnP}@MIM-KJ+4~KlhR5RU1hmPy{!hDgx!sf`M+Fg`xk14VdIy z^rRD~NRf{VB1N9gVAPW8QXeYl5*xxge8%@vz|_j=g~DI;y(nmn#njUJXNx+EeyYbJ zI*G<rLJp}GZ*O7Fb8-E6r)>_5AiPsKPW-yg-j>%J?>^77W#>z&^+wR*95≤+Tmr z;q>L(%>I1G8hUkVZ@;~XGjNl`hPGn&H*b7({l@2+F#|)>B_m9c?WagBRv7WXCzuir z6gdlqawDX=ndzSANIT*8tk3_Wg1@@N4z>Gnnq46)S$wr$X_Ov4EQ);Tay&=W)_tg2 ziTL%mtwkw73d5lFb>0jNX6LFxg!AcH7>F<s{FK%0#_rGMqki1LHx14I??JEK2jp?$ z`R={->tAo?n<ZT#{FjlG+|GxmQNCu>Qz)c9Ni_VcQ~X!+q=%$-C^@sHdZF2$l*(TH z`4R-b!&0ARbxw^#YFDrc-n56HFVm{9he0k4B3W735Fr~KQc;@$F4_QnxiQb-R0$~x zm#elu)ml_b#GMQqTt7A;J>PzkTenPBdwWnng3rgT#OA~Mw@O>vMa#?=3Qr4`S=_x_ z*tKF0cZ;Q+ycI`&ao3s@f)DN%O56D-rQN%m+j%Q3xI3ktr$6Mktt5UOh1wE=<iIJX z(~lf+_%4)xEb!==fC>_zPNxQS_+IGaf(zxO1BK3JDDb_|-5*^jCmkqsHba3gp(*h` z1+hto=HO}B?MIJF2?<XW`Hu?($C2XDNzvs8rUh5RQqQ-FH#YOaszZZS+3g39N(mo) z+XLscghTfUaFCF2c*5TnP9p_Qi!MJfEw~QsugK8@Sm99o^UX%%;Bez`|8RZ3#y?xG zR@ck#Ue;bWe!dBvc$a=*HTvdg13qM?tg&(MqFk>Zd~x`jmH77H4Sic>-_3DV^*R2y z95$oN^TwiaX)ro4V2CSWMyD2yHTSya=PhTs{Gu^$ENT7ox)w(gWHtS06Z$zP;j_GQ wf;Y<<ZZB(0;5DaNo#MP%V~X=KhR&Na#?V*r7rdTz>N%$dThI?R@ceQ37va2)-2eap literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcharsetprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f2b15fb58da7a7b8743958d68cf07812f07312c7 GIT binary patch literal 2941 zcmZ`*&2JmW6`$D;a!HZ2B&&8*B?bc|Y1uYWQKT?hq?KcdmKDg9VbU$INHL%|BXX(b zlA2vwkxHE`AlF{oOQmBjIrPv!pnt~P+MaxAd+sIuy;;e!l4=(7c4ppuyf^Q?-<yZk zYMG&gfBxX}<vWc1lRB5hL*oHz`Z0)PlE-YsL(Zw~#LmbK-H{i1BR}*x+ho#}-YJuw z;xFB>ApJIL6kc&GZE#avA9QtFWl!~ZSLudp7HFW`%amU4W~x8dN2Wr|DCxH|jF`o? zI+&`Yr?#Vg6-R^dSoW~j>q5d&Nq0dM3%O*WBYEgbC-kHn`qG0Cx4&e2Toz?;S_+G{ zU6SR~APiJV&dJItd&$Ex+ErPz?Kyc%&Y!ZdA{XQ${?#v;$HE#^Su%Iq5H3~^k1};l zn^zAYL4<j%zh}$8*7|??BbBe#9<_Rxg3{l;sOe{DWGv$|_R=|X&KYMjw1qo!K)sm@ z>PrS%u(W7tU}?$H@{FC$(K^W>9B(x$#!sgcrF8*Yn?Q&ti83KfL5#*y#ik^*dZBcx zq^XFcJ5pj|ZDHm_+)Xnv)>3Ix6{$K9z40`GWm536an_A#@T${;<xE-ZX_`rGU#nDQ z4bOO~iua749~itoZ|;rb;0q-odN?u_;w$#wjn!;4S)D|a52GZ-QSpbp!+tW%4nC$q zTg3~N$gy6fv!u#a(_L!e#9V=oCP%sioqvFuE`cy!;{^vFzxs~rHyH1u%Zuufr&6K+ zYdifCo$Gdz)=tvt^UOQ*&)HILC9+#l5)CYcm0%aQ_39h!@CubR$~wT$+D9)^t4hQN zF^hebiDWtwy*wBqmFgOCZxNX%vH;TH`gZ=iOG9rFStdf;{Twx|fIxrfK2O>^$M4*v zx3$?dr5!9?r%m1lnXw_$HKIe_rXFHz87f(|oR+Cv*uc6{!_{=KeuoI*$%UY~gjZq` ze+@MyA7v0SaE{-*Nx(M`xF#nV$I5vRjql2N=1P7JnJ*;`;%?HPcKfQ~<x<izE2VL9 z?Kg-@lOCbIDe8?rba_ILu8<1(Bk5?xOyE%@CS72<gt+B12zUaT-lL1P*9$~lW+%=U zf6Lq%f5|u4@BaF^bK;(OKm-pQf97Z2(BEe|oB?Wv1?k>r4)9^-V~--n|6#|2i}3)X zrE8q>1qaA6oJ;?5$%p^?ci9OL2NL3>nTyj3$-R7E^6p{jyL^mRW(A)u1NHACTt2}r z@cq)k&wiWh>SLE8W;t1PSlf60!1Vw<I{VhXm-o)*&)G>ZBS{zR*aNf{&u+`YtT+qK zUCyu;_a(lU{Ls$2v(GN}p;<+mg%x+sJv;L*%|svf*$7(Z_P$aRp@7&?IuNnS0BB}` zoC=thqn#LaCz`_DEKIcODM{%DgPD%Lu)ci!-ur32H%|5<%c}pX{(kzC`k|^1x-V3{ zTR)7FMCs#S{J&YdDjpx!6V>l#5hkaDvCewatey=Jd4s_?me{QER_=)3--}|%2h0Xd zuwtA5bq|5bDPY~^!;%6%C=Gnj6ac2UzSHVF+u640VCLGNK6$#`6z#3BX`vzq7YiSA zn4Y5vr65z<Xm*<Govqd;GTKAYZ0$VXd@P<dw?*givu6A8&i00>5guJBZdRV|w6{82 zzrg{Icb;|DpLgDvT!_d0J}%dnYIoW<!K0n$tqrl&LF&mxUuiWrKfQ5vYo{ZgG#e!g zZ6?@7dc``e-z8yrWO&c`HaTemcWW0@zLM=*7-PIWrQ{RLOeuUBFXQuog=N0z28A+m z1Jw%U2w>#AGmq9HFFQ0^;{iAUzOwy0+@YRx{Ps;CMTflxCyIWujg9&i8j_-%;>y|g z^k<S{jAzae5oY6xtx&9Z6m=_%@BlsEate80y8AxX`NV@)7h3(_FMYlF_v6zwy@Kug zs3`wgGk3D1Nz{YOOvY(M{wClk(YQ~Om%je@TBDd}5}Q+O#tAMhY8^0l8Ok#aC$|IF z-?~`+BXDP^DQ&`Vr)8&(8w}7o{@|wjx$Z{|=TWP1iykNTMIi8spx4PXR(PmXggBUX z<D8=@o9hOV9~1d05kgg)>P&#tkGD>Cl&2hv==X_BLgEpVKQMYKj)l0=15j`CrcIdy z&*WnE$v{fj&#Bca<w~(q3|4KTZZ(RgdhNNP$;!s3XiRM+YKkhG#`Dx})7=%J!%Xl= QuI8^P1E#c~!k66t0f<z}Jpcdz literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sbcsgroupprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0b2e01d3aa7ffe0613620d4cba48e8463e2abc8f GIT binary patch literal 1569 zcmaJ>U2oeq6eT5FmTk$F9Vg9(ee|h-v9(#dIqgF+49T#p*jfy5fC9t-L6%rWEh)Q{ z+%ALr<O2N@1C{`L*<a%8p7s~^w0lV>Z8~5yba3v6#CtCfeGrBn0*n2A<7XWb@)sHx zs{!O2c>3GLlh2BxRH$cZ4Hd<{IvbhHSE?^q41GtR;Qs%QkDv4(phBLv&@p0vWQ< z*iF%seb$!|i;V4wfgG}-;VrQxM{H!cFSg|l+cCT?uE|}tOUV(*I$8HM$-11bUG_m1 zOvyO>n?i|Ws)vUsiJJ2INX?gvpVWND6?m^ri!vAd;I!tO_$K7((c_}LeP?p}@KhB- z6zRix#)a<uFfZ;Y%eQ_^>Y|)nO^6;Q=~Ykn!A#!U-?#4=V=^(u*wK;s#N8vs`7@g^ zu-kt5)&*%JyVJo^<cTVh(xz^2D!l53uKLFhru%okI6g@VyAiZ+b0^>Pnc^=myn!_@ z$1$|~952<gqB=2IDU9!Oxf@n}1cVbtGs2uV<O$7a=DhZq`-U_KYrx!H-Jc#DPT!e! ziU)xU#RGyO__68_fSS~FMb^%lb51C!-MX=+fK7v*!InYaVB28FVAo(^Ff`aR*k98; zSdloY2W#>Qzc$S13S{xhG2AiSUD30xm9uis9ZFW@X>>MPQM7aS9K^gLXWLj&MzEnr z-yM&4bhBD6xKcwXTl;ZbltmrK3R_Xwmuez-2rUF3p^bo-Np%qd1RQ|sAq)U?Yhe^w zsR&(tbPXzA#}Y*sZ-Uz6ztp_UbW?E%jvKmBaq&clC+1K$X?k1C^CC?|eAPXAQB=$K zy&#r$9H%0wsyP0W{PXQzEf;%>VsW!5t2z<lX8JNOpVrU6LZ^A+7f`}n?WJ&^GG6ah zv$V?bQrRkREl$-4>i-;`3W3m`<I(^8njQ_n-=MyU1++tb=hxl$M04w6#N#H8yG$gH zW8H~yFiU|vh~wwbmW`O5b-3v$<wC&Wd;&EX7*q8z@=p=)1V4kPasYg4>__7d^$`1l z>AusF!W7+yMs3J8Y7SiwL{jGI<}bpW*8l53_wa=r@4L;u)P){mWOi}IZS+zrI>cxV zH`)eJI=YWOd&<^pgcDfLrb-l)j?ByUR@+Qeo$2}Qcr3%=X#YNB!F<2Qc~v;7fClus L8_~!?20!;-w_Ksb literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/sjisprober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..588f49863918ed633abd942579f72c9a4f3bc589 GIT binary patch literal 2395 zcmZuzOK%%D5GJ_~tz=17?8LE)qHutwsDLK!At-tX+9tM>IEWvx6ck;wVAmooud=(6 zxm0T#%1JJA%|EDp?4QUF;k74Ud+ep1;rb!B-WAE=V>vV5y!5nIs}Oj?-#`2DL!FR6 zadPpvKzs)+{~0<#1WiavLrRfm2}_;Ov9y!8sTX>db`w7>g(XXSNsyMqvZei`l1_zF zX*H};@|=j02#$#eBpo|pO_W=tSvjM?rb*4*`Y_S)(?czn_afDjdQ0_pq=KE9<-Uls zZc9g6u1B4{IFqnC-+H;$T8VS5;+>(6``ME$N)GclhrL<cTkdCC9_WeX8ZPtJI$z&h zS$)-Hriwf+t~S;4%Ppf0NOk!*=TyE0gd`yqBxLW%E)`U;;~;b_?FbiWS9-z|{xKQT z&<EP840K79Mdg@;ftV6i7|ZX7OTr33P%{-2tkAcEaNvU@^2L@vf=&}nM`X-S*ePsk zN4sN~b5HwY0%J)Bb}Wy`Nd->`0(aAm=9KaB;Xo=?hD%Jqd7Q<XbA=ZxAJ@tq3oy@9 zg~m5`#00E7LR^pFdk^;-odVX&W#cKCOAV;IxlDFpEOXvTqCDsP5Ayf7OFA7a4dTIr zILmdEBo8{jcC((|e}s#+@n2*n`f8~Ib{A4F<-Ir`SmQq&9I7ecdLLSDJ(kvKg$D2* zSsNFaJ-pEAX7E0SudjnQB0Z;o@d6}Q;q?|GHH{QR1)!%I#c&IkX0V&Z4o`dmEl0Qr z$aK`Wvfx9D$2C#VmdkiPfDV|G9xZIcEFV)v)d57FMJf2U<yx@2;&~fB{SxnB&=GcY zcY@>O=QlG(K?O2p8zy)e4WbN;W?9_K&IC!6b%#+`qU&AooW%TMzhmWrL+BnQXjaiz zpz?cqz%1@`4DSm0>94m8lxHW-h>q9-Ii+u%5x8;Bd&ATg?D!`o0WRGOpp{4L)CD)M z^rpbMt6OBhVb9j!>@KX<udPnQYQx^$I3;i05fcnnK8zqd7ZC7U!g-A2%*m{sxg&QT z0^~Q`bx#?^z1ziJF$ZqNX^>Pncj44L0m>_=|9xjq*%NT~YInc!Jpmc~a~YVG;SNYY z_lCWv>Y3$n_Y{yq`egnT<yd&*;`~BKSh)jsD{UOzyPq$@uLzCBy;v_oQ1;bgq!)J} zZNlCez)uu<+ZkHr3`6|vA9$J{L70L;rEwCOsVc0SN(R}HLriL^&@YX*y1l)*ZTzI) z?Mh`lA$Nvdg?^{zutVb-e`B-F*H?{Sd};i(b_?ghv(48VD}1eOyjJ_kcH7K$!Jj)r zrDO&p_%|>%6%L7^m=>Pz?n)_C&9b+mnDWYMdv&?Jw(;Cdcl(;ltUv7TaS`dr)a{-9 zY&RA%>qs-xda=3PUVh!??HAjtFnP7o^lbE)03iVxm7y`j*Li|NWlez6aKynz*Hwsp z4q|)_E&mESLT}TCO*VB%H?F0y$MjRDbJV9ZYzEHE(+aDzI<3O#fE`UwgeB^B8IEWR zY&JYT0Rjw5PAIr5x;(QK(>655tjG?o#YkbMDIjvv=%DEo3W83yzHu0LP4zrw+u48h z!V7+YmSeUjR)?d72|2H$3Izj-1ZE=6!C*Y?i(!IvmGk{!loUHQFWW?D0`N$vFZyu8 zR}e}oxT&32gN{rRs5+OBL*B7j)h1LdO`k%`(K7>DEmd87gL^h3Z#3&>I^8+Xa)tjZ zbZ|3M7}k1DTKqMzbq&fC7L$oGR#Y~>H|S*gpeSWNT$w}7vo+9@*)YwmkK1S{O2MVH Yh1@8s2_6@Se1mnx3S0%_7jMJ)7voz#egFUf literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/universaldetector.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..de87d51a641540a1df44071b6c126f56a9d0a84c GIT binary patch literal 5785 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 AXaE2J literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/utf8prober.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07958fdedee73fee4ef5d0a61410b3765e6900d9 GIT binary patch literal 1926 zcmah~OKT%X5bmCrM)F8D_CgW}VM&OC!rEpbAzlb^*0R<%*piXP1coe)Jl)nxo*BzM zqhu}QlMQ>@Q|_^kx$IBL59m`uPCg~)oKn>zYvm;&16^HR{iy1%tG?MRmrDe`;OFJ< ze+BIi9Nc{tDBnU$cR+B$X+&ZgP>Q+{8L=6du@zW)Y({qM1di6Ns1Un>OUX9jHg~QF zcLcpOgCZ}qN!7ija9owDa_vP&wncUzPmhGG8p=bhmvq}%Clkus?}RUUiO?fhzF0fu zcaxJTJmk=Sw$9r7Y`?ix-wWa7>1R%~)CWb7fN~NToCfAAa!k3w%_}#sv~F=5bXz#w z;e{)5NrM9DE-z}`<t09MMId~Sm!U7cA{Ghe;3^eWLihOvy1BdGHbT4~e%NCW*wW8I zWF(_wa%o%}H!zu*nRN+cW^)448I$V*+Bt!vX`|{YI~@*$lm*zTT*i7yFJnyFFq973 zilK&trLiirWEivfh=l-Zs%$AzkpVtdDxzcPi;RU)Crugqh5Ws-mc@g$L2t0qOVX?p zMJwTt-K3wLeSt>Z*bgG%r*aLC<04xdX2<IT{ZOleb6EuM%g|C61fdmLq7EG`y#-_S zF4}(w<73!$AB-{Sn>j2TA+a<FM&lOGui6s*XdI-68s@B=!zn7uc~?QxJc<Prxa<+M z6oJYk94*Ymr}4QL9KKc!cVOCc3U6REMmF4gWnG^;ah3a+I#QknTx2Zi#NsjTH$V_$ z^xllO*){*`ROR>h4}WgdNxH*MSA03+YZm#t`B29Ji|{_!^yPj6<z;_Nx5)FO3j<Im z*K};$&<k^HW=7vUG32An>f4x*2jtAr)&f{J!Rp?#7QqTh3n!Fr0I(AqM;7VNapNmu z5H@$_d<Ti$_h4rk*1m=WuiT(z{=|~6@6N*&0Jhn<#ek(IhXwt@s+5SA8G{VXgv1*t zyWVOwTM`ROIgO^z_Up>Y7bs`fZ{yf~);w%%v0Y!;ZU1S@S4&-Zop30nNT7#&jzpr9 z2kJ{RO>wL4*K7W6V_Q}9+SBB?$3+qfwb<Tiw*1<m&-|TM9R_<_RZFLwa*xh40luZ8 zA!Na%5_POPJKm;<bu0vb0x_o_fgn&U9yFI)Q(2*lh6iQj8l(A{w84GTbU}3R;`$j^ zLE-cQN~I56d_v^%7<D~fB2UN#<>r{a4@@$KOxDF@HM(!Me;++~^XJAb7R7|G{@SP- zIU40=qt0qOPh0Gu)!YOtR+e&xNz^+L@1(ta2y=VTQvLhTS6RUDKbQ&sK9*GvISi|W zF;!wLKIOv*b&s*LVJFIG<Y#cG<`-SU$_3H^4$RKwB2GL&@hOUjAb|C9RtrTG0W(f< zhuYD6ps4`q^Al((ngDgfb3EI#Jj-3ul+vh{RC!XNImJoDTG;|9HPy+MXWwG}$U14_ r{O6>}SUK@gn5MBN<(#Fak>oL99LoJVzw$R9Vlc>P9$kP`@T`9T>cz1U literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2c08d6c0bf96a959ae054209a81eb3fac1f5079 GIT binary patch literal 395 zcmXv~Jx{|h5KY>YqM)wKHz7LIL84Ptp{jy`rAQPpL`abvyNMzGz;^oeXMmBJf0LDe zz{rFf(v$Al@9y;U?xww7=(&jB&YphU`@JWJXuHqEr8#v#yx1dt>{I`}MOq(z+$Qb0 z*AI4I;X}?0a7oI70^KlU4M<UJ!AdZUtAZ`JpsCf2u9(Qc<`h;`8zu#ak}s$Rxr8*w znot`qwdAm7HfI71wWUI83s?}S8_g7$a-negf-`DR7>;mhbE!vgjRi~#Eb1{hCs?4x zfle}xS%Ff?`{Ay0i7wEv^3kjxRNW*YGEI`|BuN@$j&zK3ZmaI&&HeoLZuaTvBX@=x ze#epJDpE`hm@pO>#UNd0;@Q3q_r*G$k|0t?jpL{hcH30P<Nsq_?FCKXAZP{t9|IwK Aga7~l literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py new file mode 100644 index 0000000..38f3251 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/big5freq.py @@ -0,0 +1,386 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Big5 frequency table +# by Taiwan's Mandarin Promotion Council +# <http://www.edu.tw:81/mandr/> +# +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Ideal Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +BIG5_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +#Char to FreqOrder table +BIG5_TABLE_SIZE = 5376 + +BIG5_CHAR_TO_FREQ_ORDER = ( + 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, # 16 +3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, # 32 +1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, # 48 + 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, # 64 +3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, # 80 +4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, # 96 +5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, # 112 + 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, # 128 + 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, # 144 + 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, # 160 +2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, # 176 +1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, # 192 +3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, # 208 + 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, # 224 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, # 240 +3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, # 256 +2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, # 272 + 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, # 288 +3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, # 304 +1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, # 320 +5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, # 336 + 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, # 352 +5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, # 368 +1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, # 384 + 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, # 400 + 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, # 416 +3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, # 432 +3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, # 448 + 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, # 464 +2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, # 480 +2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, # 496 + 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, # 512 + 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, # 528 +3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, # 544 +1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, # 560 +1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, # 576 +1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, # 592 +2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, # 608 + 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, # 624 +4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, # 640 +1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, # 656 +5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, # 672 +2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, # 688 + 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, # 704 + 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, # 720 + 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, # 736 + 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, # 752 +5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, # 768 + 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, # 784 +1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, # 800 + 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, # 816 + 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, # 832 +5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, # 848 +1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, # 864 + 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, # 880 +3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, # 896 +4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, # 912 +3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, # 928 + 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, # 944 + 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, # 960 +1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, # 976 +4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, # 992 +3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, # 1008 +3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, # 1024 +2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, # 1040 +5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, # 1056 +3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, # 1072 +5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, # 1088 +1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, # 1104 +2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, # 1120 +1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, # 1136 + 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, # 1152 +1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, # 1168 +4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, # 1184 +3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, # 1200 + 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, # 1216 + 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, # 1232 + 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, # 1248 +2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, # 1264 +5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, # 1280 +1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, # 1296 +2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, # 1312 +1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, # 1328 +1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, # 1344 +5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, # 1360 +5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, # 1376 +5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, # 1392 +3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, # 1408 +4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, # 1424 +4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, # 1440 +2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, # 1456 +5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, # 1472 +3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, # 1488 + 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, # 1504 +5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, # 1520 +5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, # 1536 +1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, # 1552 +2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, # 1568 +3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, # 1584 +4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, # 1600 +5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, # 1616 +3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, # 1632 +4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, # 1648 +1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, # 1664 +1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, # 1680 +4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, # 1696 +1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, # 1712 + 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, # 1728 +1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, # 1744 +1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, # 1760 +3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, # 1776 + 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, # 1792 +5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, # 1808 +2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, # 1824 +1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, # 1840 +1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, # 1856 +5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, # 1872 + 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, # 1888 +4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, # 1904 + 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, # 1920 +2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, # 1936 + 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, # 1952 +1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, # 1968 +1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, # 1984 + 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, # 2000 +4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, # 2016 +4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, # 2032 +1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, # 2048 +3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, # 2064 +5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, # 2080 +5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, # 2096 +1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, # 2112 +2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, # 2128 +1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, # 2144 +3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, # 2160 +2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, # 2176 +3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, # 2192 +2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, # 2208 +4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, # 2224 +4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, # 2240 +3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, # 2256 + 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, # 2272 +3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, # 2288 + 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, # 2304 +3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, # 2320 +4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, # 2336 +3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, # 2352 +1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, # 2368 +5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, # 2384 + 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, # 2400 +5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, # 2416 +1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, # 2432 + 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, # 2448 +4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, # 2464 +4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, # 2480 + 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, # 2496 +2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, # 2512 +2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, # 2528 +3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, # 2544 +1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, # 2560 +4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, # 2576 +2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, # 2592 +1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, # 2608 +1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, # 2624 +2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, # 2640 +3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, # 2656 +1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, # 2672 +5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, # 2688 +1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, # 2704 +4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, # 2720 +1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, # 2736 + 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, # 2752 +1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, # 2768 +4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, # 2784 +4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, # 2800 +2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, # 2816 +1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, # 2832 +4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, # 2848 + 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, # 2864 +5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, # 2880 +2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, # 2896 +3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, # 2912 +4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, # 2928 + 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, # 2944 +5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, # 2960 +5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, # 2976 +1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, # 2992 +4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, # 3008 +4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, # 3024 +2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, # 3040 +3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, # 3056 +3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, # 3072 +2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, # 3088 +1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, # 3104 +4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, # 3120 +3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, # 3136 +3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, # 3152 +2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, # 3168 +4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, # 3184 +5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, # 3200 +3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, # 3216 +2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, # 3232 +3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, # 3248 +1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, # 3264 +2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, # 3280 +3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, # 3296 +4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, # 3312 +2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, # 3328 +2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, # 3344 +5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, # 3360 +1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, # 3376 +2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, # 3392 +1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, # 3408 +3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, # 3424 +4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, # 3440 +2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, # 3456 +3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, # 3472 +3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, # 3488 +2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, # 3504 +4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, # 3520 +2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, # 3536 +3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, # 3552 +4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, # 3568 +5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, # 3584 +3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, # 3600 + 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, # 3616 +1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, # 3632 +4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, # 3648 +1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, # 3664 +4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, # 3680 +5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, # 3696 + 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, # 3712 +5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, # 3728 +5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, # 3744 +2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, # 3760 +3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, # 3776 +2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, # 3792 +2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, # 3808 + 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, # 3824 +1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, # 3840 +4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, # 3856 +3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, # 3872 +3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, # 3888 + 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, # 3904 +2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, # 3920 + 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, # 3936 +2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, # 3952 +4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, # 3968 +1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, # 3984 +4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, # 4000 +1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, # 4016 +3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, # 4032 + 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, # 4048 +3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, # 4064 +5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, # 4080 +5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, # 4096 +3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, # 4112 +3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, # 4128 +1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, # 4144 +2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, # 4160 +5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, # 4176 +1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, # 4192 +1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, # 4208 +3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, # 4224 + 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, # 4240 +1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, # 4256 +4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, # 4272 +5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, # 4288 +2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, # 4304 +3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, # 4320 + 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, # 4336 +1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, # 4352 +2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, # 4368 +2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, # 4384 +5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, # 4400 +5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, # 4416 +5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, # 4432 +2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, # 4448 +2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, # 4464 +1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, # 4480 +4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, # 4496 +3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, # 4512 +3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, # 4528 +4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, # 4544 +4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, # 4560 +2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, # 4576 +2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, # 4592 +5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, # 4608 +4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, # 4624 +5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, # 4640 +4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, # 4656 + 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, # 4672 + 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, # 4688 +1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, # 4704 +3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, # 4720 +4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, # 4736 +1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, # 4752 +5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, # 4768 +2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, # 4784 +2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, # 4800 +3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, # 4816 +5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, # 4832 +1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, # 4848 +3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, # 4864 +5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, # 4880 +1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, # 4896 +5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, # 4912 +2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, # 4928 +3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, # 4944 +2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, # 4960 +3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, # 4976 +3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, # 4992 +3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, # 5008 +4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, # 5024 + 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, # 5040 +2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, # 5056 +4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, # 5072 +3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, # 5088 +5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, # 5104 +1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, # 5120 +5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, # 5136 + 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, # 5152 +1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, # 5168 + 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, # 5184 +4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, # 5200 +1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, # 5216 +4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, # 5232 +1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, # 5248 + 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, # 5264 +3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, # 5280 +4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, # 5296 +5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, # 5312 + 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, # 5328 +3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, # 5344 + 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, # 5360 +2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, # 5376 +) + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py new file mode 100644 index 0000000..98f9970 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/big5prober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import Big5DistributionAnalysis +from .mbcssm import BIG5_SM_MODEL + + +class Big5Prober(MultiByteCharSetProber): + def __init__(self): + super(Big5Prober, self).__init__() + self.coding_sm = CodingStateMachine(BIG5_SM_MODEL) + self.distribution_analyzer = Big5DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "Big5" + + @property + def language(self): + return "Chinese" diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py new file mode 100644 index 0000000..c0395f4 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/chardistribution.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .euctwfreq import (EUCTW_CHAR_TO_FREQ_ORDER, EUCTW_TABLE_SIZE, + EUCTW_TYPICAL_DISTRIBUTION_RATIO) +from .euckrfreq import (EUCKR_CHAR_TO_FREQ_ORDER, EUCKR_TABLE_SIZE, + EUCKR_TYPICAL_DISTRIBUTION_RATIO) +from .gb2312freq import (GB2312_CHAR_TO_FREQ_ORDER, GB2312_TABLE_SIZE, + GB2312_TYPICAL_DISTRIBUTION_RATIO) +from .big5freq import (BIG5_CHAR_TO_FREQ_ORDER, BIG5_TABLE_SIZE, + BIG5_TYPICAL_DISTRIBUTION_RATIO) +from .jisfreq import (JIS_CHAR_TO_FREQ_ORDER, JIS_TABLE_SIZE, + JIS_TYPICAL_DISTRIBUTION_RATIO) + + +class CharDistributionAnalysis(object): + ENOUGH_DATA_THRESHOLD = 1024 + SURE_YES = 0.99 + SURE_NO = 0.01 + MINIMUM_DATA_THRESHOLD = 3 + + def __init__(self): + # Mapping table to get frequency order from char order (get from + # GetOrder()) + self._char_to_freq_order = None + self._table_size = None # Size of above table + # This is a constant value which varies from language to language, + # used in calculating confidence. See + # http://www.mozilla.org/projects/intl/UniversalCharsetDetection.html + # for further detail. + self.typical_distribution_ratio = None + self._done = None + self._total_chars = None + self._freq_chars = None + self.reset() + + def reset(self): + """reset analyser, clear any state""" + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + self._total_chars = 0 # Total characters encountered + # The number of characters whose frequency order is less than 512 + self._freq_chars = 0 + + def feed(self, char, char_len): + """feed a character with known length""" + if char_len == 2: + # we only care about 2-bytes character in our distribution analysis + order = self.get_order(char) + else: + order = -1 + if order >= 0: + self._total_chars += 1 + # order is valid + if order < self._table_size: + if 512 > self._char_to_freq_order[order]: + self._freq_chars += 1 + + def get_confidence(self): + """return confidence based on existing data""" + # if we didn't receive any character in our consideration range, + # return negative answer + if self._total_chars <= 0 or self._freq_chars <= self.MINIMUM_DATA_THRESHOLD: + return self.SURE_NO + + if self._total_chars != self._freq_chars: + r = (self._freq_chars / ((self._total_chars - self._freq_chars) + * self.typical_distribution_ratio)) + if r < self.SURE_YES: + return r + + # normalize confidence (we don't want to be 100% sure) + return self.SURE_YES + + def got_enough_data(self): + # It is not necessary to receive all data to draw conclusion. + # For charset detection, certain amount of data is enough + return self._total_chars > self.ENOUGH_DATA_THRESHOLD + + def get_order(self, byte_str): + # We do not handle characters based on the original encoding string, + # but convert this encoding string to a number, here called order. + # This allows multiple encodings of a language to share one frequency + # table. + return -1 + + +class EUCTWDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCTWDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCTW_CHAR_TO_FREQ_ORDER + self._table_size = EUCTW_TABLE_SIZE + self.typical_distribution_ratio = EUCTW_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-TW encoding, we are interested + # first byte range: 0xc4 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xC4: + return 94 * (first_char - 0xC4) + byte_str[1] - 0xA1 + else: + return -1 + + +class EUCKRDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCKRDistributionAnalysis, self).__init__() + self._char_to_freq_order = EUCKR_CHAR_TO_FREQ_ORDER + self._table_size = EUCKR_TABLE_SIZE + self.typical_distribution_ratio = EUCKR_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-KR encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char = byte_str[0] + if first_char >= 0xB0: + return 94 * (first_char - 0xB0) + byte_str[1] - 0xA1 + else: + return -1 + + +class GB2312DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(GB2312DistributionAnalysis, self).__init__() + self._char_to_freq_order = GB2312_CHAR_TO_FREQ_ORDER + self._table_size = GB2312_TABLE_SIZE + self.typical_distribution_ratio = GB2312_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for GB2312 encoding, we are interested + # first byte range: 0xb0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0xB0) and (second_char >= 0xA1): + return 94 * (first_char - 0xB0) + second_char - 0xA1 + else: + return -1 + + +class Big5DistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(Big5DistributionAnalysis, self).__init__() + self._char_to_freq_order = BIG5_CHAR_TO_FREQ_ORDER + self._table_size = BIG5_TABLE_SIZE + self.typical_distribution_ratio = BIG5_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for big5 encoding, we are interested + # first byte range: 0xa4 -- 0xfe + # second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if first_char >= 0xA4: + if second_char >= 0xA1: + return 157 * (first_char - 0xA4) + second_char - 0xA1 + 63 + else: + return 157 * (first_char - 0xA4) + second_char - 0x40 + else: + return -1 + + +class SJISDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(SJISDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for sjis encoding, we are interested + # first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe + # second byte range: 0x40 -- 0x7e, 0x81 -- oxfe + # no validation needed here. State machine has done that + first_char, second_char = byte_str[0], byte_str[1] + if (first_char >= 0x81) and (first_char <= 0x9F): + order = 188 * (first_char - 0x81) + elif (first_char >= 0xE0) and (first_char <= 0xEF): + order = 188 * (first_char - 0xE0 + 31) + else: + return -1 + order = order + second_char - 0x40 + if second_char > 0x7F: + order = -1 + return order + + +class EUCJPDistributionAnalysis(CharDistributionAnalysis): + def __init__(self): + super(EUCJPDistributionAnalysis, self).__init__() + self._char_to_freq_order = JIS_CHAR_TO_FREQ_ORDER + self._table_size = JIS_TABLE_SIZE + self.typical_distribution_ratio = JIS_TYPICAL_DISTRIBUTION_RATIO + + def get_order(self, byte_str): + # for euc-JP encoding, we are interested + # first byte range: 0xa0 -- 0xfe + # second byte range: 0xa1 -- 0xfe + # no validation needed here. State machine has done that + char = byte_str[0] + if char >= 0xA0: + return 94 * (char - 0xA1) + byte_str[1] - 0xa1 + else: + return -1 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py new file mode 100644 index 0000000..8b3738e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/charsetgroupprober.py @@ -0,0 +1,106 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState +from .charsetprober import CharSetProber + + +class CharSetGroupProber(CharSetProber): + def __init__(self, lang_filter=None): + super(CharSetGroupProber, self).__init__(lang_filter=lang_filter) + self._active_num = 0 + self.probers = [] + self._best_guess_prober = None + + def reset(self): + super(CharSetGroupProber, self).reset() + self._active_num = 0 + for prober in self.probers: + if prober: + prober.reset() + prober.active = True + self._active_num += 1 + self._best_guess_prober = None + + @property + def charset_name(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.charset_name + + @property + def language(self): + if not self._best_guess_prober: + self.get_confidence() + if not self._best_guess_prober: + return None + return self._best_guess_prober.language + + def feed(self, byte_str): + for prober in self.probers: + if not prober: + continue + if not prober.active: + continue + state = prober.feed(byte_str) + if not state: + continue + if state == ProbingState.FOUND_IT: + self._best_guess_prober = prober + return self.state + elif state == ProbingState.NOT_ME: + prober.active = False + self._active_num -= 1 + if self._active_num <= 0: + self._state = ProbingState.NOT_ME + return self.state + return self.state + + def get_confidence(self): + state = self.state + if state == ProbingState.FOUND_IT: + return 0.99 + elif state == ProbingState.NOT_ME: + return 0.01 + best_conf = 0.0 + self._best_guess_prober = None + for prober in self.probers: + if not prober: + continue + if not prober.active: + self.logger.debug('%s not active', prober.charset_name) + continue + conf = prober.get_confidence() + self.logger.debug('%s %s confidence = %s', prober.charset_name, prober.language, conf) + if best_conf < conf: + best_conf = conf + self._best_guess_prober = prober + if not self._best_guess_prober: + return 0.0 + return best_conf diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py new file mode 100644 index 0000000..eac4e59 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/charsetprober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging +import re + +from .enums import ProbingState + + +class CharSetProber(object): + + SHORTCUT_THRESHOLD = 0.95 + + def __init__(self, lang_filter=None): + self._state = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + + def reset(self): + self._state = ProbingState.DETECTING + + @property + def charset_name(self): + return None + + def feed(self, buf): + pass + + @property + def state(self): + return self._state + + def get_confidence(self): + return 0.0 + + @staticmethod + def filter_high_byte_only(buf): + buf = re.sub(b'([\x00-\x7F])+', b' ', buf) + return buf + + @staticmethod + def filter_international_words(buf): + """ + We define three types of bytes: + alphabet: english alphabets [a-zA-Z] + international: international characters [\x80-\xFF] + marker: everything else [^a-zA-Z\x80-\xFF] + + The input buffer can be thought to contain a series of words delimited + by markers. This function works to filter all words that contain at + least one international character. All contiguous sequences of markers + are replaced by a single space ascii character. + + This filter applies to all scripts which do not use English characters. + """ + filtered = bytearray() + + # This regex expression filters out only words that have at-least one + # international character. The word may include one marker character at + # the end. + words = re.findall(b'[a-zA-Z]*[\x80-\xFF]+[a-zA-Z]*[^a-zA-Z\x80-\xFF]?', + buf) + + for word in words: + filtered.extend(word[:-1]) + + # If the last character in the word is a marker, replace it with a + # space as markers shouldn't affect our analysis (they are used + # similarly across all languages and may thus have similar + # frequencies). + last_char = word[-1:] + if not last_char.isalpha() and last_char < b'\x80': + last_char = b' ' + filtered.extend(last_char) + + return filtered + + @staticmethod + def filter_with_english_letters(buf): + """ + Returns a copy of ``buf`` that retains only the sequences of English + alphabet and high byte characters that are not between <> characters. + Also retains English alphabet and high byte characters immediately + before occurrences of >. + + This filter can be applied to all scripts which contain both English + characters and extended ASCII characters, but is currently only used by + ``Latin1Prober``. + """ + filtered = bytearray() + in_tag = False + prev = 0 + + for curr in range(len(buf)): + # Slice here to get bytes instead of an int with Python 3 + buf_char = buf[curr:curr + 1] + # Check if we're coming out of or entering an HTML tag + if buf_char == b'>': + in_tag = False + elif buf_char == b'<': + in_tag = True + + # If current character is not extended-ASCII and not alphabetic... + if buf_char < b'\x80' and not buf_char.isalpha(): + # ...and we're not in a tag + if curr > prev and not in_tag: + # Keep everything after last non-extended-ASCII, + # non-alphabetic character + filtered.extend(buf[prev:curr]) + # Output a space to delimit stretch we kept + filtered.extend(b' ') + prev = curr + 1 + + # If we're not in a tag... + if not in_tag: + # Keep everything after last non-extended-ASCII, non-alphabetic + # character + filtered.extend(buf[prev:]) + + return filtered diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__init__.py @@ -0,0 +1 @@ + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3d8424a8c6b7f2b4d3409554d2aa41c1f9c4bc1c GIT binary patch literal 152 zcmZ?b<>g`kf~fgwF^oX^F^B^LAOQy;E@lA|DGb33nv8xc8Hzx{2;!Hceo1bDenDn| zZf0I_Nn%cpZgP2gURFt=2}lr(<I7U>Qu2%RlQR;FQc_FwlXEil<Kr{)GE3s)^$IF) TaoFVMr<CTT+JTHN24V&Py89%q literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/__pycache__/chardetect.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c6a9f6e6d5ca8ee9f3eed1fa920d4928114d8feb GIT binary patch literal 2641 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 KN0*~34fkI_Y!3?n literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py new file mode 100644 index 0000000..c61136b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/cli/chardetect.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +""" +Script which takes one or more file paths and reports on their detected +encodings + +Example:: + + % chardetect somefile someotherfile + somefile: windows-1252 with confidence 0.5 + someotherfile: ascii with confidence 1.0 + +If no paths are provided, it takes its input from stdin. + +""" + +from __future__ import absolute_import, print_function, unicode_literals + +import argparse +import sys + +from pip._vendor.chardet import __version__ +from pip._vendor.chardet.compat import PY2 +from pip._vendor.chardet.universaldetector import UniversalDetector + + +def description_of(lines, name='stdin'): + """ + Return a string describing the probable encoding of a file or + list of strings. + + :param lines: The lines to get the encoding of. + :type lines: Iterable of bytes + :param name: Name of file or collection of lines + :type name: str + """ + u = UniversalDetector() + for line in lines: + line = bytearray(line) + u.feed(line) + # shortcut out of the loop to save reading further - particularly useful if we read a BOM. + if u.done: + break + u.close() + result = u.result + if PY2: + name = name.decode(sys.getfilesystemencoding(), 'ignore') + if result['encoding']: + return '{0}: {1} with confidence {2}'.format(name, result['encoding'], + result['confidence']) + else: + return '{0}: no result'.format(name) + + +def main(argv=None): + """ + Handles command line arguments and gets things started. + + :param argv: List of arguments, as if specified on the command-line. + If None, ``sys.argv[1:]`` is used instead. + :type argv: list of str + """ + # Get command line arguments + parser = argparse.ArgumentParser( + description="Takes one or more file paths and reports their detected \ + encodings") + parser.add_argument('input', + help='File whose encoding we would like to determine. \ + (default: stdin)', + type=argparse.FileType('rb'), nargs='*', + default=[sys.stdin if PY2 else sys.stdin.buffer]) + parser.add_argument('--version', action='version', + version='%(prog)s {0}'.format(__version__)) + args = parser.parse_args(argv) + + for f in args.input: + if f.isatty(): + print("You are running chardetect interactively. Press " + + "CTRL-D twice at the start of a blank line to signal the " + + "end of your input. If you want help, run chardetect " + + "--help\n", file=sys.stderr) + print(description_of(f, f.name)) + + +if __name__ == '__main__': + main() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py new file mode 100644 index 0000000..68fba44 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/codingstatemachine.py @@ -0,0 +1,88 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import logging + +from .enums import MachineState + + +class CodingStateMachine(object): + """ + A state machine to verify a byte sequence for a particular encoding. For + each byte the detector receives, it will feed that byte to every active + state machine available, one byte at a time. The state machine changes its + state based on its previous state and the byte it receives. There are 3 + states in a state machine that are of interest to an auto-detector: + + START state: This is the state to start with, or a legal byte sequence + (i.e. a valid code point) for character has been identified. + + ME state: This indicates that the state machine identified a byte sequence + that is specific to the charset it is designed for and that + there is no other possible encoding which can contain this byte + sequence. This will to lead to an immediate positive answer for + the detector. + + ERROR state: This indicates the state machine identified an illegal byte + sequence for that encoding. This will lead to an immediate + negative answer for this encoding. Detector will exclude this + encoding from consideration from here on. + """ + def __init__(self, sm): + self._model = sm + self._curr_byte_pos = 0 + self._curr_char_len = 0 + self._curr_state = None + self.logger = logging.getLogger(__name__) + self.reset() + + def reset(self): + self._curr_state = MachineState.START + + def next_state(self, c): + # for each byte we get its class + # if it is first byte, we also get byte length + byte_class = self._model['class_table'][c] + if self._curr_state == MachineState.START: + self._curr_byte_pos = 0 + self._curr_char_len = self._model['char_len_table'][byte_class] + # from byte's class and state_table, we get its next state + curr_state = (self._curr_state * self._model['class_factor'] + + byte_class) + self._curr_state = self._model['state_table'][curr_state] + self._curr_byte_pos += 1 + return self._curr_state + + def get_current_charlen(self): + return self._curr_char_len + + def get_coding_state_machine(self): + return self._model['name'] + + @property + def language(self): + return self._model['language'] diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py new file mode 100644 index 0000000..ddd7468 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/compat.py @@ -0,0 +1,34 @@ +######################## BEGIN LICENSE BLOCK ######################## +# Contributor(s): +# Dan Blanchard +# Ian Cordasco +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +import sys + + +if sys.version_info < (3, 0): + PY2 = True + PY3 = False + base_str = (str, unicode) + text_type = unicode +else: + PY2 = False + PY3 = True + base_str = (bytes, str) + text_type = str diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py new file mode 100644 index 0000000..efd793a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/cp949prober.py @@ -0,0 +1,49 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .chardistribution import EUCKRDistributionAnalysis +from .codingstatemachine import CodingStateMachine +from .mbcharsetprober import MultiByteCharSetProber +from .mbcssm import CP949_SM_MODEL + + +class CP949Prober(MultiByteCharSetProber): + def __init__(self): + super(CP949Prober, self).__init__() + self.coding_sm = CodingStateMachine(CP949_SM_MODEL) + # NOTE: CP949 is a superset of EUC-KR, so the distribution should be + # not different. + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "CP949" + + @property + def language(self): + return "Korean" diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py new file mode 100644 index 0000000..0451207 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/enums.py @@ -0,0 +1,76 @@ +""" +All of the Enums that are used throughout the chardet package. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + + +class InputState(object): + """ + This enum represents the different states a universal detector can be in. + """ + PURE_ASCII = 0 + ESC_ASCII = 1 + HIGH_BYTE = 2 + + +class LanguageFilter(object): + """ + This enum represents the different language filters we can apply to a + ``UniversalDetector``. + """ + CHINESE_SIMPLIFIED = 0x01 + CHINESE_TRADITIONAL = 0x02 + JAPANESE = 0x04 + KOREAN = 0x08 + NON_CJK = 0x10 + ALL = 0x1F + CHINESE = CHINESE_SIMPLIFIED | CHINESE_TRADITIONAL + CJK = CHINESE | JAPANESE | KOREAN + + +class ProbingState(object): + """ + This enum represents the different states a prober can be in. + """ + DETECTING = 0 + FOUND_IT = 1 + NOT_ME = 2 + + +class MachineState(object): + """ + This enum represents the different states a state machine can be in. + """ + START = 0 + ERROR = 1 + ITS_ME = 2 + + +class SequenceLikelihood(object): + """ + This enum represents the likelihood of a character following the previous one. + """ + NEGATIVE = 0 + UNLIKELY = 1 + LIKELY = 2 + POSITIVE = 3 + + @classmethod + def get_num_categories(cls): + """:returns: The number of likelihood categories in the enum.""" + return 4 + + +class CharacterCategory(object): + """ + This enum represents the different categories language models for + ``SingleByteCharsetProber`` put characters into. + + Anything less than CONTROL is considered a letter. + """ + UNDEFINED = 255 + LINE_BREAK = 254 + SYMBOL = 253 + DIGIT = 252 + CONTROL = 251 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py new file mode 100644 index 0000000..c70493f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/escprober.py @@ -0,0 +1,101 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .codingstatemachine import CodingStateMachine +from .enums import LanguageFilter, ProbingState, MachineState +from .escsm import (HZ_SM_MODEL, ISO2022CN_SM_MODEL, ISO2022JP_SM_MODEL, + ISO2022KR_SM_MODEL) + + +class EscCharSetProber(CharSetProber): + """ + This CharSetProber uses a "code scheme" approach for detecting encodings, + whereby easily recognizable escape or shift sequences are relied on to + identify these encodings. + """ + + def __init__(self, lang_filter=None): + super(EscCharSetProber, self).__init__(lang_filter=lang_filter) + self.coding_sm = [] + if self.lang_filter & LanguageFilter.CHINESE_SIMPLIFIED: + self.coding_sm.append(CodingStateMachine(HZ_SM_MODEL)) + self.coding_sm.append(CodingStateMachine(ISO2022CN_SM_MODEL)) + if self.lang_filter & LanguageFilter.JAPANESE: + self.coding_sm.append(CodingStateMachine(ISO2022JP_SM_MODEL)) + if self.lang_filter & LanguageFilter.KOREAN: + self.coding_sm.append(CodingStateMachine(ISO2022KR_SM_MODEL)) + self.active_sm_count = None + self._detected_charset = None + self._detected_language = None + self._state = None + self.reset() + + def reset(self): + super(EscCharSetProber, self).reset() + for coding_sm in self.coding_sm: + if not coding_sm: + continue + coding_sm.active = True + coding_sm.reset() + self.active_sm_count = len(self.coding_sm) + self._detected_charset = None + self._detected_language = None + + @property + def charset_name(self): + return self._detected_charset + + @property + def language(self): + return self._detected_language + + def get_confidence(self): + if self._detected_charset: + return 0.99 + else: + return 0.00 + + def feed(self, byte_str): + for c in byte_str: + for coding_sm in self.coding_sm: + if not coding_sm or not coding_sm.active: + continue + coding_state = coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + coding_sm.active = False + self.active_sm_count -= 1 + if self.active_sm_count <= 0: + self._state = ProbingState.NOT_ME + return self.state + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + self._detected_charset = coding_sm.get_coding_state_machine() + self._detected_language = coding_sm.language + return self.state + + return self.state diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py new file mode 100644 index 0000000..0069523 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/escsm.py @@ -0,0 +1,246 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +HZ_CLS = ( +1,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,0,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,4,0,5,2,0, # 78 - 7f +1,1,1,1,1,1,1,1, # 80 - 87 +1,1,1,1,1,1,1,1, # 88 - 8f +1,1,1,1,1,1,1,1, # 90 - 97 +1,1,1,1,1,1,1,1, # 98 - 9f +1,1,1,1,1,1,1,1, # a0 - a7 +1,1,1,1,1,1,1,1, # a8 - af +1,1,1,1,1,1,1,1, # b0 - b7 +1,1,1,1,1,1,1,1, # b8 - bf +1,1,1,1,1,1,1,1, # c0 - c7 +1,1,1,1,1,1,1,1, # c8 - cf +1,1,1,1,1,1,1,1, # d0 - d7 +1,1,1,1,1,1,1,1, # d8 - df +1,1,1,1,1,1,1,1, # e0 - e7 +1,1,1,1,1,1,1,1, # e8 - ef +1,1,1,1,1,1,1,1, # f0 - f7 +1,1,1,1,1,1,1,1, # f8 - ff +) + +HZ_ST = ( +MachineState.START,MachineState.ERROR, 3,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START, 4,MachineState.ERROR,# 10-17 + 5,MachineState.ERROR, 6,MachineState.ERROR, 5, 5, 4,MachineState.ERROR,# 18-1f + 4,MachineState.ERROR, 4, 4, 4,MachineState.ERROR, 4,MachineState.ERROR,# 20-27 + 4,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 28-2f +) + +HZ_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +HZ_SM_MODEL = {'class_table': HZ_CLS, + 'class_factor': 6, + 'state_table': HZ_ST, + 'char_len_table': HZ_CHAR_LEN_TABLE, + 'name': "HZ-GB-2312", + 'language': 'Chinese'} + +ISO2022CN_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,0,0,0,0, # 20 - 27 +0,3,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,4,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022CN_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 20-27 + 5, 6,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,# 38-3f +) + +ISO2022CN_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022CN_SM_MODEL = {'class_table': ISO2022CN_CLS, + 'class_factor': 9, + 'state_table': ISO2022CN_ST, + 'char_len_table': ISO2022CN_CHAR_LEN_TABLE, + 'name': "ISO-2022-CN", + 'language': 'Chinese'} + +ISO2022JP_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,2,2, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,7,0,0,0, # 20 - 27 +3,0,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +6,0,4,0,8,0,0,0, # 40 - 47 +0,9,5,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022JP_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 00-07 +MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 08-0f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 10-17 +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 20-27 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 6,MachineState.ITS_ME,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,# 28-2f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,# 30-37 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 38-3f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.START,# 40-47 +) + +ISO2022JP_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + +ISO2022JP_SM_MODEL = {'class_table': ISO2022JP_CLS, + 'class_factor': 10, + 'state_table': ISO2022JP_ST, + 'char_len_table': ISO2022JP_CHAR_LEN_TABLE, + 'name': "ISO-2022-JP", + 'language': 'Japanese'} + +ISO2022KR_CLS = ( +2,0,0,0,0,0,0,0, # 00 - 07 +0,0,0,0,0,0,0,0, # 08 - 0f +0,0,0,0,0,0,0,0, # 10 - 17 +0,0,0,1,0,0,0,0, # 18 - 1f +0,0,0,0,3,0,0,0, # 20 - 27 +0,4,0,0,0,0,0,0, # 28 - 2f +0,0,0,0,0,0,0,0, # 30 - 37 +0,0,0,0,0,0,0,0, # 38 - 3f +0,0,0,5,0,0,0,0, # 40 - 47 +0,0,0,0,0,0,0,0, # 48 - 4f +0,0,0,0,0,0,0,0, # 50 - 57 +0,0,0,0,0,0,0,0, # 58 - 5f +0,0,0,0,0,0,0,0, # 60 - 67 +0,0,0,0,0,0,0,0, # 68 - 6f +0,0,0,0,0,0,0,0, # 70 - 77 +0,0,0,0,0,0,0,0, # 78 - 7f +2,2,2,2,2,2,2,2, # 80 - 87 +2,2,2,2,2,2,2,2, # 88 - 8f +2,2,2,2,2,2,2,2, # 90 - 97 +2,2,2,2,2,2,2,2, # 98 - 9f +2,2,2,2,2,2,2,2, # a0 - a7 +2,2,2,2,2,2,2,2, # a8 - af +2,2,2,2,2,2,2,2, # b0 - b7 +2,2,2,2,2,2,2,2, # b8 - bf +2,2,2,2,2,2,2,2, # c0 - c7 +2,2,2,2,2,2,2,2, # c8 - cf +2,2,2,2,2,2,2,2, # d0 - d7 +2,2,2,2,2,2,2,2, # d8 - df +2,2,2,2,2,2,2,2, # e0 - e7 +2,2,2,2,2,2,2,2, # e8 - ef +2,2,2,2,2,2,2,2, # f0 - f7 +2,2,2,2,2,2,2,2, # f8 - ff +) + +ISO2022KR_ST = ( +MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,# 00-07 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,# 08-0f +MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 4,MachineState.ERROR,MachineState.ERROR,# 10-17 +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,# 18-1f +MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.START,MachineState.START,MachineState.START,MachineState.START,# 20-27 +) + +ISO2022KR_CHAR_LEN_TABLE = (0, 0, 0, 0, 0, 0) + +ISO2022KR_SM_MODEL = {'class_table': ISO2022KR_CLS, + 'class_factor': 6, + 'state_table': ISO2022KR_ST, + 'char_len_table': ISO2022KR_CHAR_LEN_TABLE, + 'name': "ISO-2022-KR", + 'language': 'Korean'} + + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py new file mode 100644 index 0000000..20ce8f7 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/eucjpprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import ProbingState, MachineState +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCJPDistributionAnalysis +from .jpcntx import EUCJPContextAnalysis +from .mbcssm import EUCJP_SM_MODEL + + +class EUCJPProber(MultiByteCharSetProber): + def __init__(self): + super(EUCJPProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCJP_SM_MODEL) + self.distribution_analyzer = EUCJPDistributionAnalysis() + self.context_analyzer = EUCJPContextAnalysis() + self.reset() + + def reset(self): + super(EUCJPProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return "EUC-JP" + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + # PY3K: byte_str is a byte array, so byte_str[i] is an int, not a byte + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char, char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py new file mode 100644 index 0000000..b68078c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/euckrfreq.py @@ -0,0 +1,195 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology + +# 128 --> 0.79 +# 256 --> 0.92 +# 512 --> 0.986 +# 1024 --> 0.99944 +# 2048 --> 0.99999 +# +# Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 +# Random Distribution Ration = 512 / (2350-512) = 0.279. +# +# Typical Distribution Ratio + +EUCKR_TYPICAL_DISTRIBUTION_RATIO = 6.0 + +EUCKR_TABLE_SIZE = 2352 + +# Char to FreqOrder table , +EUCKR_CHAR_TO_FREQ_ORDER = ( + 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, +1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, +1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, + 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, + 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, + 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, +1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, + 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, + 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, +1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, +1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, +1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, +1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, +1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, + 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, +1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, +1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, +1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, +1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, + 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, +1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, + 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, + 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, +1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, + 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, +1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, + 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, + 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, +1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, +1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, +1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, +1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, + 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, +1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, + 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, + 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, +1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, +1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, +1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, +1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, +1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, +1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, + 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, + 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, + 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, +1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, + 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, +1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, + 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, + 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, +2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, + 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, + 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, +2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, +2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, +2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, + 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, + 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, +2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, + 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, +1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, +2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, +1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, +2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, +2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, +1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, + 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, +2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, +2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, + 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, + 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, +2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, +1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, +2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, +2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, +2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, +2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, +2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, +2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, +1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, +2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, +2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, +2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, +2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, +2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, +1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, +1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, +2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, +1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, +2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, +1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, + 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, +2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, + 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, +2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, + 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, +2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, +2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, + 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, +2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, +1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, + 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, +1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, +2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, +1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, +2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, + 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, +2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, +1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, +2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, +1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, +2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, +1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, + 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, +2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, +2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, + 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, + 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, +1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, +1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, + 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, +2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, +2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, + 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, + 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, + 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, +2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, + 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, + 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, +2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, +2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, + 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, +2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, +1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, + 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, +2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, +2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, +2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, + 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, + 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, + 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, +2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, +2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, +2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, +1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, +2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, + 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, # 512, 256 +) + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py new file mode 100644 index 0000000..345a060 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/euckrprober.py @@ -0,0 +1,47 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCKRDistributionAnalysis +from .mbcssm import EUCKR_SM_MODEL + + +class EUCKRProber(MultiByteCharSetProber): + def __init__(self): + super(EUCKRProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCKR_SM_MODEL) + self.distribution_analyzer = EUCKRDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-KR" + + @property + def language(self): + return "Korean" diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py new file mode 100644 index 0000000..ed7a995 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/euctwfreq.py @@ -0,0 +1,387 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# EUCTW frequency table +# Converted from big5 work +# by Taiwan's Mandarin Promotion Council +# <http:#www.edu.tw:81/mandr/> + +# 128 --> 0.42261 +# 256 --> 0.57851 +# 512 --> 0.74851 +# 1024 --> 0.89384 +# 2048 --> 0.97583 +# +# Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 +# Random Distribution Ration = 512/(5401-512)=0.105 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR + +EUCTW_TYPICAL_DISTRIBUTION_RATIO = 0.75 + +# Char to FreqOrder table , +EUCTW_TABLE_SIZE = 5376 + +EUCTW_CHAR_TO_FREQ_ORDER = ( + 1,1800,1506, 255,1431, 198, 9, 82, 6,7310, 177, 202,3615,1256,2808, 110, # 2742 +3735, 33,3241, 261, 76, 44,2113, 16,2931,2184,1176, 659,3868, 26,3404,2643, # 2758 +1198,3869,3313,4060, 410,2211, 302, 590, 361,1963, 8, 204, 58,4296,7311,1931, # 2774 + 63,7312,7313, 317,1614, 75, 222, 159,4061,2412,1480,7314,3500,3068, 224,2809, # 2790 +3616, 3, 10,3870,1471, 29,2774,1135,2852,1939, 873, 130,3242,1123, 312,7315, # 2806 +4297,2051, 507, 252, 682,7316, 142,1914, 124, 206,2932, 34,3501,3173, 64, 604, # 2822 +7317,2494,1976,1977, 155,1990, 645, 641,1606,7318,3405, 337, 72, 406,7319, 80, # 2838 + 630, 238,3174,1509, 263, 939,1092,2644, 756,1440,1094,3406, 449, 69,2969, 591, # 2854 + 179,2095, 471, 115,2034,1843, 60, 50,2970, 134, 806,1868, 734,2035,3407, 180, # 2870 + 995,1607, 156, 537,2893, 688,7320, 319,1305, 779,2144, 514,2374, 298,4298, 359, # 2886 +2495, 90,2707,1338, 663, 11, 906,1099,2545, 20,2436, 182, 532,1716,7321, 732, # 2902 +1376,4062,1311,1420,3175, 25,2312,1056, 113, 399, 382,1949, 242,3408,2467, 529, # 2918 +3243, 475,1447,3617,7322, 117, 21, 656, 810,1297,2295,2329,3502,7323, 126,4063, # 2934 + 706, 456, 150, 613,4299, 71,1118,2036,4064, 145,3069, 85, 835, 486,2114,1246, # 2950 +1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,7324,2127,2354, 347,3736, 221, # 2966 +3503,3110,7325,1955,1153,4065, 83, 296,1199,3070, 192, 624, 93,7326, 822,1897, # 2982 +2810,3111, 795,2064, 991,1554,1542,1592, 27, 43,2853, 859, 139,1456, 860,4300, # 2998 + 437, 712,3871, 164,2392,3112, 695, 211,3017,2096, 195,3872,1608,3504,3505,3618, # 3014 +3873, 234, 811,2971,2097,3874,2229,1441,3506,1615,2375, 668,2076,1638, 305, 228, # 3030 +1664,4301, 467, 415,7327, 262,2098,1593, 239, 108, 300, 200,1033, 512,1247,2077, # 3046 +7328,7329,2173,3176,3619,2673, 593, 845,1062,3244, 88,1723,2037,3875,1950, 212, # 3062 + 266, 152, 149, 468,1898,4066,4302, 77, 187,7330,3018, 37, 5,2972,7331,3876, # 3078 +7332,7333, 39,2517,4303,2894,3177,2078, 55, 148, 74,4304, 545, 483,1474,1029, # 3094 +1665, 217,1869,1531,3113,1104,2645,4067, 24, 172,3507, 900,3877,3508,3509,4305, # 3110 + 32,1408,2811,1312, 329, 487,2355,2247,2708, 784,2674, 4,3019,3314,1427,1788, # 3126 + 188, 109, 499,7334,3620,1717,1789, 888,1217,3020,4306,7335,3510,7336,3315,1520, # 3142 +3621,3878, 196,1034, 775,7337,7338, 929,1815, 249, 439, 38,7339,1063,7340, 794, # 3158 +3879,1435,2296, 46, 178,3245,2065,7341,2376,7342, 214,1709,4307, 804, 35, 707, # 3174 + 324,3622,1601,2546, 140, 459,4068,7343,7344,1365, 839, 272, 978,2257,2572,3409, # 3190 +2128,1363,3623,1423, 697, 100,3071, 48, 70,1231, 495,3114,2193,7345,1294,7346, # 3206 +2079, 462, 586,1042,3246, 853, 256, 988, 185,2377,3410,1698, 434,1084,7347,3411, # 3222 + 314,2615,2775,4308,2330,2331, 569,2280, 637,1816,2518, 757,1162,1878,1616,3412, # 3238 + 287,1577,2115, 768,4309,1671,2854,3511,2519,1321,3737, 909,2413,7348,4069, 933, # 3254 +3738,7349,2052,2356,1222,4310, 765,2414,1322, 786,4311,7350,1919,1462,1677,2895, # 3270 +1699,7351,4312,1424,2437,3115,3624,2590,3316,1774,1940,3413,3880,4070, 309,1369, # 3286 +1130,2812, 364,2230,1653,1299,3881,3512,3882,3883,2646, 525,1085,3021, 902,2000, # 3302 +1475, 964,4313, 421,1844,1415,1057,2281, 940,1364,3116, 376,4314,4315,1381, 7, # 3318 +2520, 983,2378, 336,1710,2675,1845, 321,3414, 559,1131,3022,2742,1808,1132,1313, # 3334 + 265,1481,1857,7352, 352,1203,2813,3247, 167,1089, 420,2814, 776, 792,1724,3513, # 3350 +4071,2438,3248,7353,4072,7354, 446, 229, 333,2743, 901,3739,1200,1557,4316,2647, # 3366 +1920, 395,2744,2676,3740,4073,1835, 125, 916,3178,2616,4317,7355,7356,3741,7357, # 3382 +7358,7359,4318,3117,3625,1133,2547,1757,3415,1510,2313,1409,3514,7360,2145, 438, # 3398 +2591,2896,2379,3317,1068, 958,3023, 461, 311,2855,2677,4074,1915,3179,4075,1978, # 3414 + 383, 750,2745,2617,4076, 274, 539, 385,1278,1442,7361,1154,1964, 384, 561, 210, # 3430 + 98,1295,2548,3515,7362,1711,2415,1482,3416,3884,2897,1257, 129,7363,3742, 642, # 3446 + 523,2776,2777,2648,7364, 141,2231,1333, 68, 176, 441, 876, 907,4077, 603,2592, # 3462 + 710, 171,3417, 404, 549, 18,3118,2393,1410,3626,1666,7365,3516,4319,2898,4320, # 3478 +7366,2973, 368,7367, 146, 366, 99, 871,3627,1543, 748, 807,1586,1185, 22,2258, # 3494 + 379,3743,3180,7368,3181, 505,1941,2618,1991,1382,2314,7369, 380,2357, 218, 702, # 3510 +1817,1248,3418,3024,3517,3318,3249,7370,2974,3628, 930,3250,3744,7371, 59,7372, # 3526 + 585, 601,4078, 497,3419,1112,1314,4321,1801,7373,1223,1472,2174,7374, 749,1836, # 3542 + 690,1899,3745,1772,3885,1476, 429,1043,1790,2232,2116, 917,4079, 447,1086,1629, # 3558 +7375, 556,7376,7377,2020,1654, 844,1090, 105, 550, 966,1758,2815,1008,1782, 686, # 3574 +1095,7378,2282, 793,1602,7379,3518,2593,4322,4080,2933,2297,4323,3746, 980,2496, # 3590 + 544, 353, 527,4324, 908,2678,2899,7380, 381,2619,1942,1348,7381,1341,1252, 560, # 3606 +3072,7382,3420,2856,7383,2053, 973, 886,2080, 143,4325,7384,7385, 157,3886, 496, # 3622 +4081, 57, 840, 540,2038,4326,4327,3421,2117,1445, 970,2259,1748,1965,2081,4082, # 3638 +3119,1234,1775,3251,2816,3629, 773,1206,2129,1066,2039,1326,3887,1738,1725,4083, # 3654 + 279,3120, 51,1544,2594, 423,1578,2130,2066, 173,4328,1879,7386,7387,1583, 264, # 3670 + 610,3630,4329,2439, 280, 154,7388,7389,7390,1739, 338,1282,3073, 693,2857,1411, # 3686 +1074,3747,2440,7391,4330,7392,7393,1240, 952,2394,7394,2900,1538,2679, 685,1483, # 3702 +4084,2468,1436, 953,4085,2054,4331, 671,2395, 79,4086,2441,3252, 608, 567,2680, # 3718 +3422,4087,4088,1691, 393,1261,1791,2396,7395,4332,7396,7397,7398,7399,1383,1672, # 3734 +3748,3182,1464, 522,1119, 661,1150, 216, 675,4333,3888,1432,3519, 609,4334,2681, # 3750 +2397,7400,7401,7402,4089,3025, 0,7403,2469, 315, 231,2442, 301,3319,4335,2380, # 3766 +7404, 233,4090,3631,1818,4336,4337,7405, 96,1776,1315,2082,7406, 257,7407,1809, # 3782 +3632,2709,1139,1819,4091,2021,1124,2163,2778,1777,2649,7408,3074, 363,1655,3183, # 3798 +7409,2975,7410,7411,7412,3889,1567,3890, 718, 103,3184, 849,1443, 341,3320,2934, # 3814 +1484,7413,1712, 127, 67, 339,4092,2398, 679,1412, 821,7414,7415, 834, 738, 351, # 3830 +2976,2146, 846, 235,1497,1880, 418,1992,3749,2710, 186,1100,2147,2746,3520,1545, # 3846 +1355,2935,2858,1377, 583,3891,4093,2573,2977,7416,1298,3633,1078,2549,3634,2358, # 3862 + 78,3750,3751, 267,1289,2099,2001,1594,4094, 348, 369,1274,2194,2175,1837,4338, # 3878 +1820,2817,3635,2747,2283,2002,4339,2936,2748, 144,3321, 882,4340,3892,2749,3423, # 3894 +4341,2901,7417,4095,1726, 320,7418,3893,3026, 788,2978,7419,2818,1773,1327,2859, # 3910 +3894,2819,7420,1306,4342,2003,1700,3752,3521,2359,2650, 787,2022, 506, 824,3636, # 3926 + 534, 323,4343,1044,3322,2023,1900, 946,3424,7421,1778,1500,1678,7422,1881,4344, # 3942 + 165, 243,4345,3637,2521, 123, 683,4096, 764,4346, 36,3895,1792, 589,2902, 816, # 3958 + 626,1667,3027,2233,1639,1555,1622,3753,3896,7423,3897,2860,1370,1228,1932, 891, # 3974 +2083,2903, 304,4097,7424, 292,2979,2711,3522, 691,2100,4098,1115,4347, 118, 662, # 3990 +7425, 611,1156, 854,2381,1316,2861, 2, 386, 515,2904,7426,7427,3253, 868,2234, # 4006 +1486, 855,2651, 785,2212,3028,7428,1040,3185,3523,7429,3121, 448,7430,1525,7431, # 4022 +2164,4348,7432,3754,7433,4099,2820,3524,3122, 503, 818,3898,3123,1568, 814, 676, # 4038 +1444, 306,1749,7434,3755,1416,1030, 197,1428, 805,2821,1501,4349,7435,7436,7437, # 4054 +1993,7438,4350,7439,7440,2195, 13,2779,3638,2980,3124,1229,1916,7441,3756,2131, # 4070 +7442,4100,4351,2399,3525,7443,2213,1511,1727,1120,7444,7445, 646,3757,2443, 307, # 4086 +7446,7447,1595,3186,7448,7449,7450,3639,1113,1356,3899,1465,2522,2523,7451, 519, # 4102 +7452, 128,2132, 92,2284,1979,7453,3900,1512, 342,3125,2196,7454,2780,2214,1980, # 4118 +3323,7455, 290,1656,1317, 789, 827,2360,7456,3758,4352, 562, 581,3901,7457, 401, # 4134 +4353,2248, 94,4354,1399,2781,7458,1463,2024,4355,3187,1943,7459, 828,1105,4101, # 4150 +1262,1394,7460,4102, 605,4356,7461,1783,2862,7462,2822, 819,2101, 578,2197,2937, # 4166 +7463,1502, 436,3254,4103,3255,2823,3902,2905,3425,3426,7464,2712,2315,7465,7466, # 4182 +2332,2067, 23,4357, 193, 826,3759,2102, 699,1630,4104,3075, 390,1793,1064,3526, # 4198 +7467,1579,3076,3077,1400,7468,4105,1838,1640,2863,7469,4358,4359, 137,4106, 598, # 4214 +3078,1966, 780, 104, 974,2938,7470, 278, 899, 253, 402, 572, 504, 493,1339,7471, # 4230 +3903,1275,4360,2574,2550,7472,3640,3029,3079,2249, 565,1334,2713, 863, 41,7473, # 4246 +7474,4361,7475,1657,2333, 19, 463,2750,4107, 606,7476,2981,3256,1087,2084,1323, # 4262 +2652,2982,7477,1631,1623,1750,4108,2682,7478,2864, 791,2714,2653,2334, 232,2416, # 4278 +7479,2983,1498,7480,2654,2620, 755,1366,3641,3257,3126,2025,1609, 119,1917,3427, # 4294 + 862,1026,4109,7481,3904,3760,4362,3905,4363,2260,1951,2470,7482,1125, 817,4110, # 4310 +4111,3906,1513,1766,2040,1487,4112,3030,3258,2824,3761,3127,7483,7484,1507,7485, # 4326 +2683, 733, 40,1632,1106,2865, 345,4113, 841,2524, 230,4364,2984,1846,3259,3428, # 4342 +7486,1263, 986,3429,7487, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562,3907, # 4358 +3908,2939, 967,2751,2655,1349, 592,2133,1692,3324,2985,1994,4114,1679,3909,1901, # 4374 +2185,7488, 739,3642,2715,1296,1290,7489,4115,2198,2199,1921,1563,2595,2551,1870, # 4390 +2752,2986,7490, 435,7491, 343,1108, 596, 17,1751,4365,2235,3430,3643,7492,4366, # 4406 + 294,3527,2940,1693, 477, 979, 281,2041,3528, 643,2042,3644,2621,2782,2261,1031, # 4422 +2335,2134,2298,3529,4367, 367,1249,2552,7493,3530,7494,4368,1283,3325,2004, 240, # 4438 +1762,3326,4369,4370, 836,1069,3128, 474,7495,2148,2525, 268,3531,7496,3188,1521, # 4454 +1284,7497,1658,1546,4116,7498,3532,3533,7499,4117,3327,2684,1685,4118, 961,1673, # 4470 +2622, 190,2005,2200,3762,4371,4372,7500, 570,2497,3645,1490,7501,4373,2623,3260, # 4486 +1956,4374, 584,1514, 396,1045,1944,7502,4375,1967,2444,7503,7504,4376,3910, 619, # 4502 +7505,3129,3261, 215,2006,2783,2553,3189,4377,3190,4378, 763,4119,3763,4379,7506, # 4518 +7507,1957,1767,2941,3328,3646,1174, 452,1477,4380,3329,3130,7508,2825,1253,2382, # 4534 +2186,1091,2285,4120, 492,7509, 638,1169,1824,2135,1752,3911, 648, 926,1021,1324, # 4550 +4381, 520,4382, 997, 847,1007, 892,4383,3764,2262,1871,3647,7510,2400,1784,4384, # 4566 +1952,2942,3080,3191,1728,4121,2043,3648,4385,2007,1701,3131,1551, 30,2263,4122, # 4582 +7511,2026,4386,3534,7512, 501,7513,4123, 594,3431,2165,1821,3535,3432,3536,3192, # 4598 + 829,2826,4124,7514,1680,3132,1225,4125,7515,3262,4387,4126,3133,2336,7516,4388, # 4614 +4127,7517,3912,3913,7518,1847,2383,2596,3330,7519,4389, 374,3914, 652,4128,4129, # 4630 + 375,1140, 798,7520,7521,7522,2361,4390,2264, 546,1659, 138,3031,2445,4391,7523, # 4646 +2250, 612,1848, 910, 796,3765,1740,1371, 825,3766,3767,7524,2906,2554,7525, 692, # 4662 + 444,3032,2624, 801,4392,4130,7526,1491, 244,1053,3033,4131,4132, 340,7527,3915, # 4678 +1041,2987, 293,1168, 87,1357,7528,1539, 959,7529,2236, 721, 694,4133,3768, 219, # 4694 +1478, 644,1417,3331,2656,1413,1401,1335,1389,3916,7530,7531,2988,2362,3134,1825, # 4710 + 730,1515, 184,2827, 66,4393,7532,1660,2943, 246,3332, 378,1457, 226,3433, 975, # 4726 +3917,2944,1264,3537, 674, 696,7533, 163,7534,1141,2417,2166, 713,3538,3333,4394, # 4742 +3918,7535,7536,1186, 15,7537,1079,1070,7538,1522,3193,3539, 276,1050,2716, 758, # 4758 +1126, 653,2945,3263,7539,2337, 889,3540,3919,3081,2989, 903,1250,4395,3920,3434, # 4774 +3541,1342,1681,1718, 766,3264, 286, 89,2946,3649,7540,1713,7541,2597,3334,2990, # 4790 +7542,2947,2215,3194,2866,7543,4396,2498,2526, 181, 387,1075,3921, 731,2187,3335, # 4806 +7544,3265, 310, 313,3435,2299, 770,4134, 54,3034, 189,4397,3082,3769,3922,7545, # 4822 +1230,1617,1849, 355,3542,4135,4398,3336, 111,4136,3650,1350,3135,3436,3035,4137, # 4838 +2149,3266,3543,7546,2784,3923,3924,2991, 722,2008,7547,1071, 247,1207,2338,2471, # 4854 +1378,4399,2009, 864,1437,1214,4400, 373,3770,1142,2216, 667,4401, 442,2753,2555, # 4870 +3771,3925,1968,4138,3267,1839, 837, 170,1107, 934,1336,1882,7548,7549,2118,4139, # 4886 +2828, 743,1569,7550,4402,4140, 582,2384,1418,3437,7551,1802,7552, 357,1395,1729, # 4902 +3651,3268,2418,1564,2237,7553,3083,3772,1633,4403,1114,2085,4141,1532,7554, 482, # 4918 +2446,4404,7555,7556,1492, 833,1466,7557,2717,3544,1641,2829,7558,1526,1272,3652, # 4934 +4142,1686,1794, 416,2556,1902,1953,1803,7559,3773,2785,3774,1159,2316,7560,2867, # 4950 +4405,1610,1584,3036,2419,2754, 443,3269,1163,3136,7561,7562,3926,7563,4143,2499, # 4966 +3037,4406,3927,3137,2103,1647,3545,2010,1872,4144,7564,4145, 431,3438,7565, 250, # 4982 + 97, 81,4146,7566,1648,1850,1558, 160, 848,7567, 866, 740,1694,7568,2201,2830, # 4998 +3195,4147,4407,3653,1687, 950,2472, 426, 469,3196,3654,3655,3928,7569,7570,1188, # 5014 + 424,1995, 861,3546,4148,3775,2202,2685, 168,1235,3547,4149,7571,2086,1674,4408, # 5030 +3337,3270, 220,2557,1009,7572,3776, 670,2992, 332,1208, 717,7573,7574,3548,2447, # 5046 +3929,3338,7575, 513,7576,1209,2868,3339,3138,4409,1080,7577,7578,7579,7580,2527, # 5062 +3656,3549, 815,1587,3930,3931,7581,3550,3439,3777,1254,4410,1328,3038,1390,3932, # 5078 +1741,3933,3778,3934,7582, 236,3779,2448,3271,7583,7584,3657,3780,1273,3781,4411, # 5094 +7585, 308,7586,4412, 245,4413,1851,2473,1307,2575, 430, 715,2136,2449,7587, 270, # 5110 + 199,2869,3935,7588,3551,2718,1753, 761,1754, 725,1661,1840,4414,3440,3658,7589, # 5126 +7590, 587, 14,3272, 227,2598, 326, 480,2265, 943,2755,3552, 291, 650,1883,7591, # 5142 +1702,1226, 102,1547, 62,3441, 904,4415,3442,1164,4150,7592,7593,1224,1548,2756, # 5158 + 391, 498,1493,7594,1386,1419,7595,2055,1177,4416, 813, 880,1081,2363, 566,1145, # 5174 +4417,2286,1001,1035,2558,2599,2238, 394,1286,7596,7597,2068,7598, 86,1494,1730, # 5190 +3936, 491,1588, 745, 897,2948, 843,3340,3937,2757,2870,3273,1768, 998,2217,2069, # 5206 + 397,1826,1195,1969,3659,2993,3341, 284,7599,3782,2500,2137,2119,1903,7600,3938, # 5222 +2150,3939,4151,1036,3443,1904, 114,2559,4152, 209,1527,7601,7602,2949,2831,2625, # 5238 +2385,2719,3139, 812,2560,7603,3274,7604,1559, 737,1884,3660,1210, 885, 28,2686, # 5254 +3553,3783,7605,4153,1004,1779,4418,7606, 346,1981,2218,2687,4419,3784,1742, 797, # 5270 +1642,3940,1933,1072,1384,2151, 896,3941,3275,3661,3197,2871,3554,7607,2561,1958, # 5286 +4420,2450,1785,7608,7609,7610,3942,4154,1005,1308,3662,4155,2720,4421,4422,1528, # 5302 +2600, 161,1178,4156,1982, 987,4423,1101,4157, 631,3943,1157,3198,2420,1343,1241, # 5318 +1016,2239,2562, 372, 877,2339,2501,1160, 555,1934, 911,3944,7611, 466,1170, 169, # 5334 +1051,2907,2688,3663,2474,2994,1182,2011,2563,1251,2626,7612, 992,2340,3444,1540, # 5350 +2721,1201,2070,2401,1996,2475,7613,4424, 528,1922,2188,1503,1873,1570,2364,3342, # 5366 +3276,7614, 557,1073,7615,1827,3445,2087,2266,3140,3039,3084, 767,3085,2786,4425, # 5382 +1006,4158,4426,2341,1267,2176,3664,3199, 778,3945,3200,2722,1597,2657,7616,4427, # 5398 +7617,3446,7618,7619,7620,3277,2689,1433,3278, 131, 95,1504,3946, 723,4159,3141, # 5414 +1841,3555,2758,2189,3947,2027,2104,3665,7621,2995,3948,1218,7622,3343,3201,3949, # 5430 +4160,2576, 248,1634,3785, 912,7623,2832,3666,3040,3786, 654, 53,7624,2996,7625, # 5446 +1688,4428, 777,3447,1032,3950,1425,7626, 191, 820,2120,2833, 971,4429, 931,3202, # 5462 + 135, 664, 783,3787,1997, 772,2908,1935,3951,3788,4430,2909,3203, 282,2723, 640, # 5478 +1372,3448,1127, 922, 325,3344,7627,7628, 711,2044,7629,7630,3952,2219,2787,1936, # 5494 +3953,3345,2220,2251,3789,2300,7631,4431,3790,1258,3279,3954,3204,2138,2950,3955, # 5510 +3956,7632,2221, 258,3205,4432, 101,1227,7633,3280,1755,7634,1391,3281,7635,2910, # 5526 +2056, 893,7636,7637,7638,1402,4161,2342,7639,7640,3206,3556,7641,7642, 878,1325, # 5542 +1780,2788,4433, 259,1385,2577, 744,1183,2267,4434,7643,3957,2502,7644, 684,1024, # 5558 +4162,7645, 472,3557,3449,1165,3282,3958,3959, 322,2152, 881, 455,1695,1152,1340, # 5574 + 660, 554,2153,4435,1058,4436,4163, 830,1065,3346,3960,4437,1923,7646,1703,1918, # 5590 +7647, 932,2268, 122,7648,4438, 947, 677,7649,3791,2627, 297,1905,1924,2269,4439, # 5606 +2317,3283,7650,7651,4164,7652,4165, 84,4166, 112, 989,7653, 547,1059,3961, 701, # 5622 +3558,1019,7654,4167,7655,3450, 942, 639, 457,2301,2451, 993,2951, 407, 851, 494, # 5638 +4440,3347, 927,7656,1237,7657,2421,3348, 573,4168, 680, 921,2911,1279,1874, 285, # 5654 + 790,1448,1983, 719,2167,7658,7659,4441,3962,3963,1649,7660,1541, 563,7661,1077, # 5670 +7662,3349,3041,3451, 511,2997,3964,3965,3667,3966,1268,2564,3350,3207,4442,4443, # 5686 +7663, 535,1048,1276,1189,2912,2028,3142,1438,1373,2834,2952,1134,2012,7664,4169, # 5702 +1238,2578,3086,1259,7665, 700,7666,2953,3143,3668,4170,7667,4171,1146,1875,1906, # 5718 +4444,2601,3967, 781,2422, 132,1589, 203, 147, 273,2789,2402, 898,1786,2154,3968, # 5734 +3969,7668,3792,2790,7669,7670,4445,4446,7671,3208,7672,1635,3793, 965,7673,1804, # 5750 +2690,1516,3559,1121,1082,1329,3284,3970,1449,3794, 65,1128,2835,2913,2759,1590, # 5766 +3795,7674,7675, 12,2658, 45, 976,2579,3144,4447, 517,2528,1013,1037,3209,7676, # 5782 +3796,2836,7677,3797,7678,3452,7679,2602, 614,1998,2318,3798,3087,2724,2628,7680, # 5798 +2580,4172, 599,1269,7681,1810,3669,7682,2691,3088, 759,1060, 489,1805,3351,3285, # 5814 +1358,7683,7684,2386,1387,1215,2629,2252, 490,7685,7686,4173,1759,2387,2343,7687, # 5830 +4448,3799,1907,3971,2630,1806,3210,4449,3453,3286,2760,2344, 874,7688,7689,3454, # 5846 +3670,1858, 91,2914,3671,3042,3800,4450,7690,3145,3972,2659,7691,3455,1202,1403, # 5862 +3801,2954,2529,1517,2503,4451,3456,2504,7692,4452,7693,2692,1885,1495,1731,3973, # 5878 +2365,4453,7694,2029,7695,7696,3974,2693,1216, 237,2581,4174,2319,3975,3802,4454, # 5894 +4455,2694,3560,3457, 445,4456,7697,7698,7699,7700,2761, 61,3976,3672,1822,3977, # 5910 +7701, 687,2045, 935, 925, 405,2660, 703,1096,1859,2725,4457,3978,1876,1367,2695, # 5926 +3352, 918,2105,1781,2476, 334,3287,1611,1093,4458, 564,3146,3458,3673,3353, 945, # 5942 +2631,2057,4459,7702,1925, 872,4175,7703,3459,2696,3089, 349,4176,3674,3979,4460, # 5958 +3803,4177,3675,2155,3980,4461,4462,4178,4463,2403,2046, 782,3981, 400, 251,4179, # 5974 +1624,7704,7705, 277,3676, 299,1265, 476,1191,3804,2121,4180,4181,1109, 205,7706, # 5990 +2582,1000,2156,3561,1860,7707,7708,7709,4464,7710,4465,2565, 107,2477,2157,3982, # 6006 +3460,3147,7711,1533, 541,1301, 158, 753,4182,2872,3562,7712,1696, 370,1088,4183, # 6022 +4466,3563, 579, 327, 440, 162,2240, 269,1937,1374,3461, 968,3043, 56,1396,3090, # 6038 +2106,3288,3354,7713,1926,2158,4467,2998,7714,3564,7715,7716,3677,4468,2478,7717, # 6054 +2791,7718,1650,4469,7719,2603,7720,7721,3983,2661,3355,1149,3356,3984,3805,3985, # 6070 +7722,1076, 49,7723, 951,3211,3289,3290, 450,2837, 920,7724,1811,2792,2366,4184, # 6086 +1908,1138,2367,3806,3462,7725,3212,4470,1909,1147,1518,2423,4471,3807,7726,4472, # 6102 +2388,2604, 260,1795,3213,7727,7728,3808,3291, 708,7729,3565,1704,7730,3566,1351, # 6118 +1618,3357,2999,1886, 944,4185,3358,4186,3044,3359,4187,7731,3678, 422, 413,1714, # 6134 +3292, 500,2058,2345,4188,2479,7732,1344,1910, 954,7733,1668,7734,7735,3986,2404, # 6150 +4189,3567,3809,4190,7736,2302,1318,2505,3091, 133,3092,2873,4473, 629, 31,2838, # 6166 +2697,3810,4474, 850, 949,4475,3987,2955,1732,2088,4191,1496,1852,7737,3988, 620, # 6182 +3214, 981,1242,3679,3360,1619,3680,1643,3293,2139,2452,1970,1719,3463,2168,7738, # 6198 +3215,7739,7740,3361,1828,7741,1277,4476,1565,2047,7742,1636,3568,3093,7743, 869, # 6214 +2839, 655,3811,3812,3094,3989,3000,3813,1310,3569,4477,7744,7745,7746,1733, 558, # 6230 +4478,3681, 335,1549,3045,1756,4192,3682,1945,3464,1829,1291,1192, 470,2726,2107, # 6246 +2793, 913,1054,3990,7747,1027,7748,3046,3991,4479, 982,2662,3362,3148,3465,3216, # 6262 +3217,1946,2794,7749, 571,4480,7750,1830,7751,3570,2583,1523,2424,7752,2089, 984, # 6278 +4481,3683,1959,7753,3684, 852, 923,2795,3466,3685, 969,1519, 999,2048,2320,1705, # 6294 +7754,3095, 615,1662, 151, 597,3992,2405,2321,1049, 275,4482,3686,4193, 568,3687, # 6310 +3571,2480,4194,3688,7755,2425,2270, 409,3218,7756,1566,2874,3467,1002, 769,2840, # 6326 + 194,2090,3149,3689,2222,3294,4195, 628,1505,7757,7758,1763,2177,3001,3993, 521, # 6342 +1161,2584,1787,2203,2406,4483,3994,1625,4196,4197, 412, 42,3096, 464,7759,2632, # 6358 +4484,3363,1760,1571,2875,3468,2530,1219,2204,3814,2633,2140,2368,4485,4486,3295, # 6374 +1651,3364,3572,7760,7761,3573,2481,3469,7762,3690,7763,7764,2271,2091, 460,7765, # 6390 +4487,7766,3002, 962, 588,3574, 289,3219,2634,1116, 52,7767,3047,1796,7768,7769, # 6406 +7770,1467,7771,1598,1143,3691,4198,1984,1734,1067,4488,1280,3365, 465,4489,1572, # 6422 + 510,7772,1927,2241,1812,1644,3575,7773,4490,3692,7774,7775,2663,1573,1534,7776, # 6438 +7777,4199, 536,1807,1761,3470,3815,3150,2635,7778,7779,7780,4491,3471,2915,1911, # 6454 +2796,7781,3296,1122, 377,3220,7782, 360,7783,7784,4200,1529, 551,7785,2059,3693, # 6470 +1769,2426,7786,2916,4201,3297,3097,2322,2108,2030,4492,1404, 136,1468,1479, 672, # 6486 +1171,3221,2303, 271,3151,7787,2762,7788,2049, 678,2727, 865,1947,4493,7789,2013, # 6502 +3995,2956,7790,2728,2223,1397,3048,3694,4494,4495,1735,2917,3366,3576,7791,3816, # 6518 + 509,2841,2453,2876,3817,7792,7793,3152,3153,4496,4202,2531,4497,2304,1166,1010, # 6534 + 552, 681,1887,7794,7795,2957,2958,3996,1287,1596,1861,3154, 358, 453, 736, 175, # 6550 + 478,1117, 905,1167,1097,7796,1853,1530,7797,1706,7798,2178,3472,2287,3695,3473, # 6566 +3577,4203,2092,4204,7799,3367,1193,2482,4205,1458,2190,2205,1862,1888,1421,3298, # 6582 +2918,3049,2179,3474, 595,2122,7800,3997,7801,7802,4206,1707,2636, 223,3696,1359, # 6598 + 751,3098, 183,3475,7803,2797,3003, 419,2369, 633, 704,3818,2389, 241,7804,7805, # 6614 +7806, 838,3004,3697,2272,2763,2454,3819,1938,2050,3998,1309,3099,2242,1181,7807, # 6630 +1136,2206,3820,2370,1446,4207,2305,4498,7808,7809,4208,1055,2605, 484,3698,7810, # 6646 +3999, 625,4209,2273,3368,1499,4210,4000,7811,4001,4211,3222,2274,2275,3476,7812, # 6662 +7813,2764, 808,2606,3699,3369,4002,4212,3100,2532, 526,3370,3821,4213, 955,7814, # 6678 +1620,4214,2637,2427,7815,1429,3700,1669,1831, 994, 928,7816,3578,1260,7817,7818, # 6694 +7819,1948,2288, 741,2919,1626,4215,2729,2455, 867,1184, 362,3371,1392,7820,7821, # 6710 +4003,4216,1770,1736,3223,2920,4499,4500,1928,2698,1459,1158,7822,3050,3372,2877, # 6726 +1292,1929,2506,2842,3701,1985,1187,2071,2014,2607,4217,7823,2566,2507,2169,3702, # 6742 +2483,3299,7824,3703,4501,7825,7826, 666,1003,3005,1022,3579,4218,7827,4502,1813, # 6758 +2253, 574,3822,1603, 295,1535, 705,3823,4219, 283, 858, 417,7828,7829,3224,4503, # 6774 +4504,3051,1220,1889,1046,2276,2456,4004,1393,1599, 689,2567, 388,4220,7830,2484, # 6790 + 802,7831,2798,3824,2060,1405,2254,7832,4505,3825,2109,1052,1345,3225,1585,7833, # 6806 + 809,7834,7835,7836, 575,2730,3477, 956,1552,1469,1144,2323,7837,2324,1560,2457, # 6822 +3580,3226,4005, 616,2207,3155,2180,2289,7838,1832,7839,3478,4506,7840,1319,3704, # 6838 +3705,1211,3581,1023,3227,1293,2799,7841,7842,7843,3826, 607,2306,3827, 762,2878, # 6854 +1439,4221,1360,7844,1485,3052,7845,4507,1038,4222,1450,2061,2638,4223,1379,4508, # 6870 +2585,7846,7847,4224,1352,1414,2325,2921,1172,7848,7849,3828,3829,7850,1797,1451, # 6886 +7851,7852,7853,7854,2922,4006,4007,2485,2346, 411,4008,4009,3582,3300,3101,4509, # 6902 +1561,2664,1452,4010,1375,7855,7856, 47,2959, 316,7857,1406,1591,2923,3156,7858, # 6918 +1025,2141,3102,3157, 354,2731, 884,2224,4225,2407, 508,3706, 726,3583, 996,2428, # 6934 +3584, 729,7859, 392,2191,1453,4011,4510,3707,7860,7861,2458,3585,2608,1675,2800, # 6950 + 919,2347,2960,2348,1270,4511,4012, 73,7862,7863, 647,7864,3228,2843,2255,1550, # 6966 +1346,3006,7865,1332, 883,3479,7866,7867,7868,7869,3301,2765,7870,1212, 831,1347, # 6982 +4226,4512,2326,3830,1863,3053, 720,3831,4513,4514,3832,7871,4227,7872,7873,4515, # 6998 +7874,7875,1798,4516,3708,2609,4517,3586,1645,2371,7876,7877,2924, 669,2208,2665, # 7014 +2429,7878,2879,7879,7880,1028,3229,7881,4228,2408,7882,2256,1353,7883,7884,4518, # 7030 +3158, 518,7885,4013,7886,4229,1960,7887,2142,4230,7888,7889,3007,2349,2350,3833, # 7046 + 516,1833,1454,4014,2699,4231,4519,2225,2610,1971,1129,3587,7890,2766,7891,2961, # 7062 +1422, 577,1470,3008,1524,3373,7892,7893, 432,4232,3054,3480,7894,2586,1455,2508, # 7078 +2226,1972,1175,7895,1020,2732,4015,3481,4520,7896,2733,7897,1743,1361,3055,3482, # 7094 +2639,4016,4233,4521,2290, 895, 924,4234,2170, 331,2243,3056, 166,1627,3057,1098, # 7110 +7898,1232,2880,2227,3374,4522, 657, 403,1196,2372, 542,3709,3375,1600,4235,3483, # 7126 +7899,4523,2767,3230, 576, 530,1362,7900,4524,2533,2666,3710,4017,7901, 842,3834, # 7142 +7902,2801,2031,1014,4018, 213,2700,3376, 665, 621,4236,7903,3711,2925,2430,7904, # 7158 +2431,3302,3588,3377,7905,4237,2534,4238,4525,3589,1682,4239,3484,1380,7906, 724, # 7174 +2277, 600,1670,7907,1337,1233,4526,3103,2244,7908,1621,4527,7909, 651,4240,7910, # 7190 +1612,4241,2611,7911,2844,7912,2734,2307,3058,7913, 716,2459,3059, 174,1255,2701, # 7206 +4019,3590, 548,1320,1398, 728,4020,1574,7914,1890,1197,3060,4021,7915,3061,3062, # 7222 +3712,3591,3713, 747,7916, 635,4242,4528,7917,7918,7919,4243,7920,7921,4529,7922, # 7238 +3378,4530,2432, 451,7923,3714,2535,2072,4244,2735,4245,4022,7924,1764,4531,7925, # 7254 +4246, 350,7926,2278,2390,2486,7927,4247,4023,2245,1434,4024, 488,4532, 458,4248, # 7270 +4025,3715, 771,1330,2391,3835,2568,3159,2159,2409,1553,2667,3160,4249,7928,2487, # 7286 +2881,2612,1720,2702,4250,3379,4533,7929,2536,4251,7930,3231,4252,2768,7931,2015, # 7302 +2736,7932,1155,1017,3716,3836,7933,3303,2308, 201,1864,4253,1430,7934,4026,7935, # 7318 +7936,7937,7938,7939,4254,1604,7940, 414,1865, 371,2587,4534,4535,3485,2016,3104, # 7334 +4536,1708, 960,4255, 887, 389,2171,1536,1663,1721,7941,2228,4027,2351,2926,1580, # 7350 +7942,7943,7944,1744,7945,2537,4537,4538,7946,4539,7947,2073,7948,7949,3592,3380, # 7366 +2882,4256,7950,4257,2640,3381,2802, 673,2703,2460, 709,3486,4028,3593,4258,7951, # 7382 +1148, 502, 634,7952,7953,1204,4540,3594,1575,4541,2613,3717,7954,3718,3105, 948, # 7398 +3232, 121,1745,3837,1110,7955,4259,3063,2509,3009,4029,3719,1151,1771,3838,1488, # 7414 +4030,1986,7956,2433,3487,7957,7958,2093,7959,4260,3839,1213,1407,2803, 531,2737, # 7430 +2538,3233,1011,1537,7960,2769,4261,3106,1061,7961,3720,3721,1866,2883,7962,2017, # 7446 + 120,4262,4263,2062,3595,3234,2309,3840,2668,3382,1954,4542,7963,7964,3488,1047, # 7462 +2704,1266,7965,1368,4543,2845, 649,3383,3841,2539,2738,1102,2846,2669,7966,7967, # 7478 +1999,7968,1111,3596,2962,7969,2488,3842,3597,2804,1854,3384,3722,7970,7971,3385, # 7494 +2410,2884,3304,3235,3598,7972,2569,7973,3599,2805,4031,1460, 856,7974,3600,7975, # 7510 +2885,2963,7976,2886,3843,7977,4264, 632,2510, 875,3844,1697,3845,2291,7978,7979, # 7526 +4544,3010,1239, 580,4545,4265,7980, 914, 936,2074,1190,4032,1039,2123,7981,7982, # 7542 +7983,3386,1473,7984,1354,4266,3846,7985,2172,3064,4033, 915,3305,4267,4268,3306, # 7558 +1605,1834,7986,2739, 398,3601,4269,3847,4034, 328,1912,2847,4035,3848,1331,4270, # 7574 +3011, 937,4271,7987,3602,4036,4037,3387,2160,4546,3388, 524, 742, 538,3065,1012, # 7590 +7988,7989,3849,2461,7990, 658,1103, 225,3850,7991,7992,4547,7993,4548,7994,3236, # 7606 +1243,7995,4038, 963,2246,4549,7996,2705,3603,3161,7997,7998,2588,2327,7999,4550, # 7622 +8000,8001,8002,3489,3307, 957,3389,2540,2032,1930,2927,2462, 870,2018,3604,1746, # 7638 +2770,2771,2434,2463,8003,3851,8004,3723,3107,3724,3490,3390,3725,8005,1179,3066, # 7654 +8006,3162,2373,4272,3726,2541,3163,3108,2740,4039,8007,3391,1556,2542,2292, 977, # 7670 +2887,2033,4040,1205,3392,8008,1765,3393,3164,2124,1271,1689, 714,4551,3491,8009, # 7686 +2328,3852, 533,4273,3605,2181, 617,8010,2464,3308,3492,2310,8011,8012,3165,8013, # 7702 +8014,3853,1987, 618, 427,2641,3493,3394,8015,8016,1244,1690,8017,2806,4274,4552, # 7718 +8018,3494,8019,8020,2279,1576, 473,3606,4275,3395, 972,8021,3607,8022,3067,8023, # 7734 +8024,4553,4554,8025,3727,4041,4042,8026, 153,4555, 356,8027,1891,2888,4276,2143, # 7750 + 408, 803,2352,8028,3854,8029,4277,1646,2570,2511,4556,4557,3855,8030,3856,4278, # 7766 +8031,2411,3396, 752,8032,8033,1961,2964,8034, 746,3012,2465,8035,4279,3728, 698, # 7782 +4558,1892,4280,3608,2543,4559,3609,3857,8036,3166,3397,8037,1823,1302,4043,2706, # 7798 +3858,1973,4281,8038,4282,3167, 823,1303,1288,1236,2848,3495,4044,3398, 774,3859, # 7814 +8039,1581,4560,1304,2849,3860,4561,8040,2435,2161,1083,3237,4283,4045,4284, 344, # 7830 +1173, 288,2311, 454,1683,8041,8042,1461,4562,4046,2589,8043,8044,4563, 985, 894, # 7846 +8045,3399,3168,8046,1913,2928,3729,1988,8047,2110,1974,8048,4047,8049,2571,1194, # 7862 + 425,8050,4564,3169,1245,3730,4285,8051,8052,2850,8053, 636,4565,1855,3861, 760, # 7878 +1799,8054,4286,2209,1508,4566,4048,1893,1684,2293,8055,8056,8057,4287,4288,2210, # 7894 + 479,8058,8059, 832,8060,4049,2489,8061,2965,2490,3731, 990,3109, 627,1814,2642, # 7910 +4289,1582,4290,2125,2111,3496,4567,8062, 799,4291,3170,8063,4568,2112,1737,3013, # 7926 +1018, 543, 754,4292,3309,1676,4569,4570,4050,8064,1489,8065,3497,8066,2614,2889, # 7942 +4051,8067,8068,2966,8069,8070,8071,8072,3171,4571,4572,2182,1722,8073,3238,3239, # 7958 +1842,3610,1715, 481, 365,1975,1856,8074,8075,1962,2491,4573,8076,2126,3611,3240, # 7974 + 433,1894,2063,2075,8077, 602,2741,8078,8079,8080,8081,8082,3014,1628,3400,8083, # 7990 +3172,4574,4052,2890,4575,2512,8084,2544,2772,8085,8086,8087,3310,4576,2891,8088, # 8006 +4577,8089,2851,4578,4579,1221,2967,4053,2513,8090,8091,8092,1867,1989,8093,8094, # 8022 +8095,1895,8096,8097,4580,1896,4054, 318,8098,2094,4055,4293,8099,8100, 485,8101, # 8038 + 938,3862, 553,2670, 116,8102,3863,3612,8103,3498,2671,2773,3401,3311,2807,8104, # 8054 +3613,2929,4056,1747,2930,2968,8105,8106, 207,8107,8108,2672,4581,2514,8109,3015, # 8070 + 890,3614,3864,8110,1877,3732,3402,8111,2183,2353,3403,1652,8112,8113,8114, 941, # 8086 +2294, 208,3499,4057,2019, 330,4294,3865,2892,2492,3733,4295,8115,8116,8117,8118, # 8102 +) + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py new file mode 100644 index 0000000..35669cc --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/euctwprober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import EUCTWDistributionAnalysis +from .mbcssm import EUCTW_SM_MODEL + +class EUCTWProber(MultiByteCharSetProber): + def __init__(self): + super(EUCTWProber, self).__init__() + self.coding_sm = CodingStateMachine(EUCTW_SM_MODEL) + self.distribution_analyzer = EUCTWDistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "EUC-TW" + + @property + def language(self): + return "Taiwan" diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py new file mode 100644 index 0000000..697837b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312freq.py @@ -0,0 +1,283 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# GB2312 most frequently used character table +# +# Char to FreqOrder table , from hz6763 + +# 512 --> 0.79 -- 0.79 +# 1024 --> 0.92 -- 0.13 +# 2048 --> 0.98 -- 0.06 +# 6768 --> 1.00 -- 0.02 +# +# Ideal Distribution Ratio = 0.79135/(1-0.79135) = 3.79 +# Random Distribution Ration = 512 / (3755 - 512) = 0.157 +# +# Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR + +GB2312_TYPICAL_DISTRIBUTION_RATIO = 0.9 + +GB2312_TABLE_SIZE = 3760 + +GB2312_CHAR_TO_FREQ_ORDER = ( +1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, +2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, +2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, + 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, +1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, +1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, + 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, +1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, +2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, +3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, + 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, +1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, + 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, +2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, + 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, +2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, +1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, +3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, + 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, +1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, + 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, +2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, +1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, +3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, +1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, +2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, +1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, + 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, +3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, +3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, + 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, +3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, + 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, +1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, +3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, +2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, +1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, + 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, +1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, +4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, + 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, +3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, +3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, + 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, +1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, +2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, +1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, +1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, + 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, +3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, +3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, +4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, + 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, +3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, +1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, +1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, +4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, + 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, + 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, +3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, +1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, + 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, +1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, +2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, + 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, + 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, + 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, +3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, +4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, +3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, + 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, +2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, +2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, +2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, + 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, +2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, + 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, + 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, + 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, +3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, +2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, +2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, +1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, + 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, +2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, + 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, + 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, +1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, +1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, + 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, + 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, +1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, +2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, +3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, +2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, +2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, +2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, +3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, +1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, +1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, +2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, +1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, +3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, +1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, +1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, +3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, + 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, +2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, +1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, +4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, +1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, +1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, +3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, +1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, + 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, + 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, +1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, + 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, +1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, +1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, + 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, +3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, +4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, +3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, +2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, +2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, +1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, +3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, +2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, +1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, +1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, + 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, +2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, +2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, +3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, +4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, +3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, + 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, +3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, +2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, +1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, + 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, + 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, +3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, +4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, +2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, +1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, +1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, + 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, +1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, +3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, + 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, + 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, +1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, + 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, +1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, + 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, +2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, + 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, +2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, +2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, +1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, +1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, +2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, + 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, +1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, +1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, +2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, +2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, +3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, +1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, +4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, + 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, + 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, +3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, +1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, + 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, +3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, +1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, +4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, +1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, +2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, +1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, + 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, +1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, +3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, + 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, +2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, + 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, +1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, +1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, +1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, +3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, +2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, +3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, +3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, +3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, + 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, +2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, + 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, +2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, + 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, +1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, + 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, + 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, +1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, +3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, +3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, +1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, +1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, +3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, +2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, +2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, +1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, +3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, + 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, +4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, +1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, +2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, +3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, +3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, +1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, + 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, + 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, +2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, + 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, +1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, + 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, +1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, +1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, +1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, +1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, +1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, + 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, + 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, #last 512 +) + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py new file mode 100644 index 0000000..8446d2d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/gb2312prober.py @@ -0,0 +1,46 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import GB2312DistributionAnalysis +from .mbcssm import GB2312_SM_MODEL + +class GB2312Prober(MultiByteCharSetProber): + def __init__(self): + super(GB2312Prober, self).__init__() + self.coding_sm = CodingStateMachine(GB2312_SM_MODEL) + self.distribution_analyzer = GB2312DistributionAnalysis() + self.reset() + + @property + def charset_name(self): + return "GB2312" + + @property + def language(self): + return "Chinese" diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py new file mode 100644 index 0000000..b0e1bf4 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/hebrewprober.py @@ -0,0 +1,292 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Shy Shalom +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +# This prober doesn't actually recognize a language or a charset. +# It is a helper prober for the use of the Hebrew model probers + +### General ideas of the Hebrew charset recognition ### +# +# Four main charsets exist in Hebrew: +# "ISO-8859-8" - Visual Hebrew +# "windows-1255" - Logical Hebrew +# "ISO-8859-8-I" - Logical Hebrew +# "x-mac-hebrew" - ?? Logical Hebrew ?? +# +# Both "ISO" charsets use a completely identical set of code points, whereas +# "windows-1255" and "x-mac-hebrew" are two different proper supersets of +# these code points. windows-1255 defines additional characters in the range +# 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific +# diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. +# x-mac-hebrew defines similar additional code points but with a different +# mapping. +# +# As far as an average Hebrew text with no diacritics is concerned, all four +# charsets are identical with respect to code points. Meaning that for the +# main Hebrew alphabet, all four map the same values to all 27 Hebrew letters +# (including final letters). +# +# The dominant difference between these charsets is their directionality. +# "Visual" directionality means that the text is ordered as if the renderer is +# not aware of a BIDI rendering algorithm. The renderer sees the text and +# draws it from left to right. The text itself when ordered naturally is read +# backwards. A buffer of Visual Hebrew generally looks like so: +# "[last word of first line spelled backwards] [whole line ordered backwards +# and spelled backwards] [first word of first line spelled backwards] +# [end of line] [last word of second line] ... etc' " +# adding punctuation marks, numbers and English text to visual text is +# naturally also "visual" and from left to right. +# +# "Logical" directionality means the text is ordered "naturally" according to +# the order it is read. It is the responsibility of the renderer to display +# the text from right to left. A BIDI algorithm is used to place general +# punctuation marks, numbers and English text in the text. +# +# Texts in x-mac-hebrew are almost impossible to find on the Internet. From +# what little evidence I could find, it seems that its general directionality +# is Logical. +# +# To sum up all of the above, the Hebrew probing mechanism knows about two +# charsets: +# Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are +# backwards while line order is natural. For charset recognition purposes +# the line order is unimportant (In fact, for this implementation, even +# word order is unimportant). +# Logical Hebrew - "windows-1255" - normal, naturally ordered text. +# +# "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be +# specifically identified. +# "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew +# that contain special punctuation marks or diacritics is displayed with +# some unconverted characters showing as question marks. This problem might +# be corrected using another model prober for x-mac-hebrew. Due to the fact +# that x-mac-hebrew texts are so rare, writing another model prober isn't +# worth the effort and performance hit. +# +#### The Prober #### +# +# The prober is divided between two SBCharSetProbers and a HebrewProber, +# all of which are managed, created, fed data, inquired and deleted by the +# SBCSGroupProber. The two SBCharSetProbers identify that the text is in +# fact some kind of Hebrew, Logical or Visual. The final decision about which +# one is it is made by the HebrewProber by combining final-letter scores +# with the scores of the two SBCharSetProbers to produce a final answer. +# +# The SBCSGroupProber is responsible for stripping the original text of HTML +# tags, English characters, numbers, low-ASCII punctuation characters, spaces +# and new lines. It reduces any sequence of such characters to a single space. +# The buffer fed to each prober in the SBCS group prober is pure text in +# high-ASCII. +# The two SBCharSetProbers (model probers) share the same language model: +# Win1255Model. +# The first SBCharSetProber uses the model normally as any other +# SBCharSetProber does, to recognize windows-1255, upon which this model was +# built. The second SBCharSetProber is told to make the pair-of-letter +# lookup in the language model backwards. This in practice exactly simulates +# a visual Hebrew model using the windows-1255 logical Hebrew model. +# +# The HebrewProber is not using any language model. All it does is look for +# final-letter evidence suggesting the text is either logical Hebrew or visual +# Hebrew. Disjointed from the model probers, the results of the HebrewProber +# alone are meaningless. HebrewProber always returns 0.00 as confidence +# since it never identifies a charset by itself. Instead, the pointer to the +# HebrewProber is passed to the model probers as a helper "Name Prober". +# When the Group prober receives a positive identification from any prober, +# it asks for the name of the charset identified. If the prober queried is a +# Hebrew model prober, the model prober forwards the call to the +# HebrewProber to make the final decision. In the HebrewProber, the +# decision is made according to the final-letters scores maintained and Both +# model probers scores. The answer is returned in the form of the name of the +# charset identified, either "windows-1255" or "ISO-8859-8". + +class HebrewProber(CharSetProber): + # windows-1255 / ISO-8859-8 code points of interest + FINAL_KAF = 0xea + NORMAL_KAF = 0xeb + FINAL_MEM = 0xed + NORMAL_MEM = 0xee + FINAL_NUN = 0xef + NORMAL_NUN = 0xf0 + FINAL_PE = 0xf3 + NORMAL_PE = 0xf4 + FINAL_TSADI = 0xf5 + NORMAL_TSADI = 0xf6 + + # Minimum Visual vs Logical final letter score difference. + # If the difference is below this, don't rely solely on the final letter score + # distance. + MIN_FINAL_CHAR_DISTANCE = 5 + + # Minimum Visual vs Logical model score difference. + # If the difference is below this, don't rely at all on the model score + # distance. + MIN_MODEL_DISTANCE = 0.01 + + VISUAL_HEBREW_NAME = "ISO-8859-8" + LOGICAL_HEBREW_NAME = "windows-1255" + + def __init__(self): + super(HebrewProber, self).__init__() + self._final_char_logical_score = None + self._final_char_visual_score = None + self._prev = None + self._before_prev = None + self._logical_prober = None + self._visual_prober = None + self.reset() + + def reset(self): + self._final_char_logical_score = 0 + self._final_char_visual_score = 0 + # The two last characters seen in the previous buffer, + # mPrev and mBeforePrev are initialized to space in order to simulate + # a word delimiter at the beginning of the data + self._prev = ' ' + self._before_prev = ' ' + # These probers are owned by the group prober. + + def set_model_probers(self, logicalProber, visualProber): + self._logical_prober = logicalProber + self._visual_prober = visualProber + + def is_final(self, c): + return c in [self.FINAL_KAF, self.FINAL_MEM, self.FINAL_NUN, + self.FINAL_PE, self.FINAL_TSADI] + + def is_non_final(self, c): + # The normal Tsadi is not a good Non-Final letter due to words like + # 'lechotet' (to chat) containing an apostrophe after the tsadi. This + # apostrophe is converted to a space in FilterWithoutEnglishLetters + # causing the Non-Final tsadi to appear at an end of a word even + # though this is not the case in the original text. + # The letters Pe and Kaf rarely display a related behavior of not being + # a good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' + # for example legally end with a Non-Final Pe or Kaf. However, the + # benefit of these letters as Non-Final letters outweighs the damage + # since these words are quite rare. + return c in [self.NORMAL_KAF, self.NORMAL_MEM, + self.NORMAL_NUN, self.NORMAL_PE] + + def feed(self, byte_str): + # Final letter analysis for logical-visual decision. + # Look for evidence that the received buffer is either logical Hebrew + # or visual Hebrew. + # The following cases are checked: + # 1) A word longer than 1 letter, ending with a final letter. This is + # an indication that the text is laid out "naturally" since the + # final letter really appears at the end. +1 for logical score. + # 2) A word longer than 1 letter, ending with a Non-Final letter. In + # normal Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, + # should not end with the Non-Final form of that letter. Exceptions + # to this rule are mentioned above in isNonFinal(). This is an + # indication that the text is laid out backwards. +1 for visual + # score + # 3) A word longer than 1 letter, starting with a final letter. Final + # letters should not appear at the beginning of a word. This is an + # indication that the text is laid out backwards. +1 for visual + # score. + # + # The visual score and logical score are accumulated throughout the + # text and are finally checked against each other in GetCharSetName(). + # No checking for final letters in the middle of words is done since + # that case is not an indication for either Logical or Visual text. + # + # We automatically filter out all 7-bit characters (replace them with + # spaces) so the word boundary detection works properly. [MAP] + + if self.state == ProbingState.NOT_ME: + # Both model probers say it's not them. No reason to continue. + return ProbingState.NOT_ME + + byte_str = self.filter_high_byte_only(byte_str) + + for cur in byte_str: + if cur == ' ': + # We stand on a space - a word just ended + if self._before_prev != ' ': + # next-to-last char was not a space so self._prev is not a + # 1 letter word + if self.is_final(self._prev): + # case (1) [-2:not space][-1:final letter][cur:space] + self._final_char_logical_score += 1 + elif self.is_non_final(self._prev): + # case (2) [-2:not space][-1:Non-Final letter][ + # cur:space] + self._final_char_visual_score += 1 + else: + # Not standing on a space + if ((self._before_prev == ' ') and + (self.is_final(self._prev)) and (cur != ' ')): + # case (3) [-2:space][-1:final letter][cur:not space] + self._final_char_visual_score += 1 + self._before_prev = self._prev + self._prev = cur + + # Forever detecting, till the end or until both model probers return + # ProbingState.NOT_ME (handled above) + return ProbingState.DETECTING + + @property + def charset_name(self): + # Make the decision: is it Logical or Visual? + # If the final letter score distance is dominant enough, rely on it. + finalsub = self._final_char_logical_score - self._final_char_visual_score + if finalsub >= self.MIN_FINAL_CHAR_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if finalsub <= -self.MIN_FINAL_CHAR_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # It's not dominant enough, try to rely on the model scores instead. + modelsub = (self._logical_prober.get_confidence() + - self._visual_prober.get_confidence()) + if modelsub > self.MIN_MODEL_DISTANCE: + return self.LOGICAL_HEBREW_NAME + if modelsub < -self.MIN_MODEL_DISTANCE: + return self.VISUAL_HEBREW_NAME + + # Still no good, back to final letter distance, maybe it'll save the + # day. + if finalsub < 0.0: + return self.VISUAL_HEBREW_NAME + + # (finalsub > 0 - Logical) or (don't know what to do) default to + # Logical. + return self.LOGICAL_HEBREW_NAME + + @property + def language(self): + return 'Hebrew' + + @property + def state(self): + # Remain active as long as any of the model probers are active. + if (self._logical_prober.state == ProbingState.NOT_ME) and \ + (self._visual_prober.state == ProbingState.NOT_ME): + return ProbingState.NOT_ME + return ProbingState.DETECTING diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py new file mode 100644 index 0000000..83fc082 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/jisfreq.py @@ -0,0 +1,325 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# Sampling from about 20M text materials include literature and computer technology +# +# Japanese frequency table, applied to both S-JIS and EUC-JP +# They are sorted in order. + +# 128 --> 0.77094 +# 256 --> 0.85710 +# 512 --> 0.92635 +# 1024 --> 0.97130 +# 2048 --> 0.99431 +# +# Ideal Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 +# Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 +# +# Typical Distribution Ratio, 25% of IDR + +JIS_TYPICAL_DISTRIBUTION_RATIO = 3.0 + +# Char to FreqOrder table , +JIS_TABLE_SIZE = 4368 + +JIS_CHAR_TO_FREQ_ORDER = ( + 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, # 16 +3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, # 32 +1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, # 48 +2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, # 64 +2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, # 80 +5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, # 96 +1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, # 112 +5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, # 128 +5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, # 144 +5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, # 160 +5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, # 176 +5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, # 192 +5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, # 208 +1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, # 224 +1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, # 240 +1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, # 256 +2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, # 272 +3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, # 288 +3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, # 304 + 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, # 320 + 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, # 336 +1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, # 352 + 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, # 368 +5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, # 384 + 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, # 400 + 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, # 416 + 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, # 432 + 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, # 448 + 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, # 464 +5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, # 480 +5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, # 496 +5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, # 512 +4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, # 528 +5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, # 544 +5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, # 560 +5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, # 576 +5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, # 592 +5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, # 608 +5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, # 624 +5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, # 640 +5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, # 656 +5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, # 672 +3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, # 688 +5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, # 704 +5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, # 720 +5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, # 736 +5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, # 752 +5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, # 768 +5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, # 784 +5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, # 800 +5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, # 816 +5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, # 832 +5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, # 848 +5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, # 864 +5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, # 880 +5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, # 896 +5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, # 912 +5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, # 928 +5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, # 944 +5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, # 960 +5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, # 976 +5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, # 992 +5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, # 1008 +5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, # 1024 +5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, # 1040 +5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, # 1056 +5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, # 1072 +5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, # 1088 +5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, # 1104 +5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, # 1120 +5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, # 1136 +5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, # 1152 +5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, # 1168 +5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, # 1184 +5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, # 1200 +5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, # 1216 +5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, # 1232 +5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, # 1248 +5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, # 1264 +5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, # 1280 +5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, # 1296 +6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, # 1312 +6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, # 1328 +6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, # 1344 +6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, # 1360 +6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, # 1376 +6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, # 1392 +6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, # 1408 +6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, # 1424 +4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, # 1440 + 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, # 1456 + 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, # 1472 +1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, # 1488 +1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, # 1504 + 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, # 1520 +3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, # 1536 +3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, # 1552 + 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, # 1568 +3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, # 1584 +3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, # 1600 + 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, # 1616 +2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, # 1632 + 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, # 1648 +3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, # 1664 +1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, # 1680 + 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, # 1696 +1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, # 1712 + 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, # 1728 +2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, # 1744 +2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, # 1760 +2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, # 1776 +2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, # 1792 +1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, # 1808 +1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, # 1824 +1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, # 1840 +1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, # 1856 +2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, # 1872 +1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, # 1888 +2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, # 1904 +1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, # 1920 +1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, # 1936 +1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, # 1952 +1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, # 1968 +1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, # 1984 +1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, # 2000 + 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, # 2016 + 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, # 2032 +1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, # 2048 +2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, # 2064 +2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, # 2080 +2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, # 2096 +3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, # 2112 +3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, # 2128 + 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, # 2144 +3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, # 2160 +1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, # 2176 + 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, # 2192 +2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, # 2208 +1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, # 2224 + 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, # 2240 +3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, # 2256 +4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, # 2272 +2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, # 2288 +1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, # 2304 +2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, # 2320 +1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, # 2336 + 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, # 2352 + 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, # 2368 +1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, # 2384 +2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, # 2400 +2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, # 2416 +2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, # 2432 +3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, # 2448 +1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, # 2464 +2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, # 2480 + 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, # 2496 + 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, # 2512 + 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, # 2528 +1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, # 2544 +2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, # 2560 + 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, # 2576 +1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, # 2592 +1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, # 2608 + 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, # 2624 +1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, # 2640 +1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, # 2656 +1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, # 2672 + 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, # 2688 +2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, # 2704 + 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, # 2720 +2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, # 2736 +3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, # 2752 +2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, # 2768 +1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, # 2784 +6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, # 2800 +1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, # 2816 +2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, # 2832 +1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, # 2848 + 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, # 2864 + 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, # 2880 +3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, # 2896 +3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, # 2912 +1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, # 2928 +1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, # 2944 +1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, # 2960 +1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, # 2976 + 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, # 2992 + 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, # 3008 +2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, # 3024 + 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, # 3040 +3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, # 3056 +2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, # 3072 + 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, # 3088 +1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, # 3104 +2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, # 3120 + 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, # 3136 +1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, # 3152 + 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, # 3168 +4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, # 3184 +2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, # 3200 +1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, # 3216 + 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, # 3232 +1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, # 3248 +2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, # 3264 + 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, # 3280 +6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, # 3296 +1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, # 3312 +1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, # 3328 +2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, # 3344 +3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, # 3360 + 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, # 3376 +3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, # 3392 +1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, # 3408 + 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, # 3424 +1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, # 3440 + 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, # 3456 +3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, # 3472 + 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, # 3488 +2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, # 3504 + 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, # 3520 +4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, # 3536 +2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, # 3552 +1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, # 3568 +1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, # 3584 +1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, # 3600 + 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, # 3616 +1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, # 3632 +3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, # 3648 +1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, # 3664 +3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, # 3680 + 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, # 3696 + 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, # 3712 + 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, # 3728 +2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, # 3744 +1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, # 3760 + 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, # 3776 +1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, # 3792 + 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, # 3808 +1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, # 3824 + 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, # 3840 + 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, # 3856 + 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, # 3872 +1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, # 3888 +1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, # 3904 +2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, # 3920 +4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, # 3936 + 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, # 3952 +1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, # 3968 + 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, # 3984 +1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, # 4000 +3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, # 4016 +1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, # 4032 +2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, # 4048 +2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, # 4064 +1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, # 4080 +1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, # 4096 +2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, # 4112 + 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, # 4128 +2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, # 4144 +1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, # 4160 +1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, # 4176 +1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, # 4192 +1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, # 4208 +3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, # 4224 +2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, # 4240 +2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, # 4256 + 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, # 4272 +3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, # 4288 +3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, # 4304 +1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, # 4320 +2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, # 4336 +1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, # 4352 +2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, # 4368 #last 512 +) + + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py new file mode 100644 index 0000000..20044e4 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/jpcntx.py @@ -0,0 +1,233 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + + +# This is hiragana 2-char sequence table, the number in each cell represents its frequency category +jp2CharContext = ( +(0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1), +(2,4,0,4,0,3,0,4,0,3,4,4,4,2,4,3,3,4,3,2,3,3,4,2,3,3,3,2,4,1,4,3,3,1,5,4,3,4,3,4,3,5,3,0,3,5,4,2,0,3,1,0,3,3,0,3,3,0,1,1,0,4,3,0,3,3,0,4,0,2,0,3,5,5,5,5,4,0,4,1,0,3,4), +(0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2), +(0,4,0,5,0,5,0,4,0,4,5,4,4,3,5,3,5,1,5,3,4,3,4,4,3,4,3,3,4,3,5,4,4,3,5,5,3,5,5,5,3,5,5,3,4,5,5,3,1,3,2,0,3,4,0,4,2,0,4,2,1,5,3,2,3,5,0,4,0,2,0,5,4,4,5,4,5,0,4,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,4,0,3,0,3,0,4,5,4,3,3,3,3,4,3,5,4,4,3,5,4,4,3,4,3,4,4,4,4,5,3,4,4,3,4,5,5,4,5,5,1,4,5,4,3,0,3,3,1,3,3,0,4,4,0,3,3,1,5,3,3,3,5,0,4,0,3,0,4,4,3,4,3,3,0,4,1,1,3,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,4,0,3,0,3,0,4,0,3,4,4,3,2,2,1,2,1,3,1,3,3,3,3,3,4,3,1,3,3,5,3,3,0,4,3,0,5,4,3,3,5,4,4,3,4,4,5,0,1,2,0,1,2,0,2,2,0,1,0,0,5,2,2,1,4,0,3,0,1,0,4,4,3,5,4,3,0,2,1,0,4,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,5,0,4,0,2,1,4,4,2,4,1,4,2,4,2,4,3,3,3,4,3,3,3,3,1,4,2,3,3,3,1,4,4,1,1,1,4,3,3,2,0,2,4,3,2,0,3,3,0,3,1,1,0,0,0,3,3,0,4,2,2,3,4,0,4,0,3,0,4,4,5,3,4,4,0,3,0,0,1,4), +(1,4,0,4,0,4,0,4,0,3,5,4,4,3,4,3,5,4,3,3,4,3,5,4,4,4,4,3,4,2,4,3,3,1,5,4,3,2,4,5,4,5,5,4,4,5,4,4,0,3,2,2,3,3,0,4,3,1,3,2,1,4,3,3,4,5,0,3,0,2,0,4,5,5,4,5,4,0,4,0,0,5,4), +(0,5,0,5,0,4,0,3,0,4,4,3,4,3,3,3,4,0,4,4,4,3,4,3,4,3,3,1,4,2,4,3,4,0,5,4,1,4,5,4,4,5,3,2,4,3,4,3,2,4,1,3,3,3,2,3,2,0,4,3,3,4,3,3,3,4,0,4,0,3,0,4,5,4,4,4,3,0,4,1,0,1,3), +(0,3,1,4,0,3,0,2,0,3,4,4,3,1,4,2,3,3,4,3,4,3,4,3,4,4,3,2,3,1,5,4,4,1,4,4,3,5,4,4,3,5,5,4,3,4,4,3,1,2,3,1,2,2,0,3,2,0,3,1,0,5,3,3,3,4,3,3,3,3,4,4,4,4,5,4,2,0,3,3,2,4,3), +(0,2,0,3,0,1,0,1,0,0,3,2,0,0,2,0,1,0,2,1,3,3,3,1,2,3,1,0,1,0,4,2,1,1,3,3,0,4,3,3,1,4,3,3,0,3,3,2,0,0,0,0,1,0,0,2,0,0,0,0,0,4,1,0,2,3,2,2,2,1,3,3,3,4,4,3,2,0,3,1,0,3,3), +(0,4,0,4,0,3,0,3,0,4,4,4,3,3,3,3,3,3,4,3,4,2,4,3,4,3,3,2,4,3,4,5,4,1,4,5,3,5,4,5,3,5,4,0,3,5,5,3,1,3,3,2,2,3,0,3,4,1,3,3,2,4,3,3,3,4,0,4,0,3,0,4,5,4,4,5,3,0,4,1,0,3,4), +(0,2,0,3,0,3,0,0,0,2,2,2,1,0,1,0,0,0,3,0,3,0,3,0,1,3,1,0,3,1,3,3,3,1,3,3,3,0,1,3,1,3,4,0,0,3,1,1,0,3,2,0,0,0,0,1,3,0,1,0,0,3,3,2,0,3,0,0,0,0,0,3,4,3,4,3,3,0,3,0,0,2,3), +(2,3,0,3,0,2,0,1,0,3,3,4,3,1,3,1,1,1,3,1,4,3,4,3,3,3,0,0,3,1,5,4,3,1,4,3,2,5,5,4,4,4,4,3,3,4,4,4,0,2,1,1,3,2,0,1,2,0,0,1,0,4,1,3,3,3,0,3,0,1,0,4,4,4,5,5,3,0,2,0,0,4,4), +(0,2,0,1,0,3,1,3,0,2,3,3,3,0,3,1,0,0,3,0,3,2,3,1,3,2,1,1,0,0,4,2,1,0,2,3,1,4,3,2,0,4,4,3,1,3,1,3,0,1,0,0,1,0,0,0,1,0,0,0,0,4,1,1,1,2,0,3,0,0,0,3,4,2,4,3,2,0,1,0,0,3,3), +(0,1,0,4,0,5,0,4,0,2,4,4,2,3,3,2,3,3,5,3,3,3,4,3,4,2,3,0,4,3,3,3,4,1,4,3,2,1,5,5,3,4,5,1,3,5,4,2,0,3,3,0,1,3,0,4,2,0,1,3,1,4,3,3,3,3,0,3,0,1,0,3,4,4,4,5,5,0,3,0,1,4,5), +(0,2,0,3,0,3,0,0,0,2,3,1,3,0,4,0,1,1,3,0,3,4,3,2,3,1,0,3,3,2,3,1,3,0,2,3,0,2,1,4,1,2,2,0,0,3,3,0,0,2,0,0,0,1,0,0,0,0,2,2,0,3,2,1,3,3,0,2,0,2,0,0,3,3,1,2,4,0,3,0,2,2,3), +(2,4,0,5,0,4,0,4,0,2,4,4,4,3,4,3,3,3,1,2,4,3,4,3,4,4,5,0,3,3,3,3,2,0,4,3,1,4,3,4,1,4,4,3,3,4,4,3,1,2,3,0,4,2,0,4,1,0,3,3,0,4,3,3,3,4,0,4,0,2,0,3,5,3,4,5,2,0,3,0,0,4,5), +(0,3,0,4,0,1,0,1,0,1,3,2,2,1,3,0,3,0,2,0,2,0,3,0,2,0,0,0,1,0,1,1,0,0,3,1,0,0,0,4,0,3,1,0,2,1,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,4,2,2,3,1,0,3,0,0,0,1,4,4,4,3,0,0,4,0,0,1,4), +(1,4,1,5,0,3,0,3,0,4,5,4,4,3,5,3,3,4,4,3,4,1,3,3,3,3,2,1,4,1,5,4,3,1,4,4,3,5,4,4,3,5,4,3,3,4,4,4,0,3,3,1,2,3,0,3,1,0,3,3,0,5,4,4,4,4,4,4,3,3,5,4,4,3,3,5,4,0,3,2,0,4,4), +(0,2,0,3,0,1,0,0,0,1,3,3,3,2,4,1,3,0,3,1,3,0,2,2,1,1,0,0,2,0,4,3,1,0,4,3,0,4,4,4,1,4,3,1,1,3,3,1,0,2,0,0,1,3,0,0,0,0,2,0,0,4,3,2,4,3,5,4,3,3,3,4,3,3,4,3,3,0,2,1,0,3,3), +(0,2,0,4,0,3,0,2,0,2,5,5,3,4,4,4,4,1,4,3,3,0,4,3,4,3,1,3,3,2,4,3,0,3,4,3,0,3,4,4,2,4,4,0,4,5,3,3,2,2,1,1,1,2,0,1,5,0,3,3,2,4,3,3,3,4,0,3,0,2,0,4,4,3,5,5,0,0,3,0,2,3,3), +(0,3,0,4,0,3,0,1,0,3,4,3,3,1,3,3,3,0,3,1,3,0,4,3,3,1,1,0,3,0,3,3,0,0,4,4,0,1,5,4,3,3,5,0,3,3,4,3,0,2,0,1,1,1,0,1,3,0,1,2,1,3,3,2,3,3,0,3,0,1,0,1,3,3,4,4,1,0,1,2,2,1,3), +(0,1,0,4,0,4,0,3,0,1,3,3,3,2,3,1,1,0,3,0,3,3,4,3,2,4,2,0,1,0,4,3,2,0,4,3,0,5,3,3,2,4,4,4,3,3,3,4,0,1,3,0,0,1,0,0,1,0,0,0,0,4,2,3,3,3,0,3,0,0,0,4,4,4,5,3,2,0,3,3,0,3,5), +(0,2,0,3,0,0,0,3,0,1,3,0,2,0,0,0,1,0,3,1,1,3,3,0,0,3,0,0,3,0,2,3,1,0,3,1,0,3,3,2,0,4,2,2,0,2,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,2,1,2,0,1,0,1,0,0,0,1,3,1,2,0,0,0,1,0,0,1,4), +(0,3,0,3,0,5,0,1,0,2,4,3,1,3,3,2,1,1,5,2,1,0,5,1,2,0,0,0,3,3,2,2,3,2,4,3,0,0,3,3,1,3,3,0,2,5,3,4,0,3,3,0,1,2,0,2,2,0,3,2,0,2,2,3,3,3,0,2,0,1,0,3,4,4,2,5,4,0,3,0,0,3,5), +(0,3,0,3,0,3,0,1,0,3,3,3,3,0,3,0,2,0,2,1,1,0,2,0,1,0,0,0,2,1,0,0,1,0,3,2,0,0,3,3,1,2,3,1,0,3,3,0,0,1,0,0,0,0,0,2,0,0,0,0,0,2,3,1,2,3,0,3,0,1,0,3,2,1,0,4,3,0,1,1,0,3,3), +(0,4,0,5,0,3,0,3,0,4,5,5,4,3,5,3,4,3,5,3,3,2,5,3,4,4,4,3,4,3,4,5,5,3,4,4,3,4,4,5,4,4,4,3,4,5,5,4,2,3,4,2,3,4,0,3,3,1,4,3,2,4,3,3,5,5,0,3,0,3,0,5,5,5,5,4,4,0,4,0,1,4,4), +(0,4,0,4,0,3,0,3,0,3,5,4,4,2,3,2,5,1,3,2,5,1,4,2,3,2,3,3,4,3,3,3,3,2,5,4,1,3,3,5,3,4,4,0,4,4,3,1,1,3,1,0,2,3,0,2,3,0,3,0,0,4,3,1,3,4,0,3,0,2,0,4,4,4,3,4,5,0,4,0,0,3,4), +(0,3,0,3,0,3,1,2,0,3,4,4,3,3,3,0,2,2,4,3,3,1,3,3,3,1,1,0,3,1,4,3,2,3,4,4,2,4,4,4,3,4,4,3,2,4,4,3,1,3,3,1,3,3,0,4,1,0,2,2,1,4,3,2,3,3,5,4,3,3,5,4,4,3,3,0,4,0,3,2,2,4,4), +(0,2,0,1,0,0,0,0,0,1,2,1,3,0,0,0,0,0,2,0,1,2,1,0,0,1,0,0,0,0,3,0,0,1,0,1,1,3,1,0,0,0,1,1,0,1,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,1,2,2,0,3,4,0,0,0,1,1,0,0,1,0,0,0,0,0,1,1), +(0,1,0,0,0,1,0,0,0,0,4,0,4,1,4,0,3,0,4,0,3,0,4,0,3,0,3,0,4,1,5,1,4,0,0,3,0,5,0,5,2,0,1,0,0,0,2,1,4,0,1,3,0,0,3,0,0,3,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0), +(1,4,0,5,0,3,0,2,0,3,5,4,4,3,4,3,5,3,4,3,3,0,4,3,3,3,3,3,3,2,4,4,3,1,3,4,4,5,4,4,3,4,4,1,3,5,4,3,3,3,1,2,2,3,3,1,3,1,3,3,3,5,3,3,4,5,0,3,0,3,0,3,4,3,4,4,3,0,3,0,2,4,3), +(0,1,0,4,0,0,0,0,0,1,4,0,4,1,4,2,4,0,3,0,1,0,1,0,0,0,0,0,2,0,3,1,1,1,0,3,0,0,0,1,2,1,0,0,1,1,1,1,0,1,0,0,0,1,0,0,3,0,0,0,0,3,2,0,2,2,0,1,0,0,0,2,3,2,3,3,0,0,0,0,2,1,0), +(0,5,1,5,0,3,0,3,0,5,4,4,5,1,5,3,3,0,4,3,4,3,5,3,4,3,3,2,4,3,4,3,3,0,3,3,1,4,4,3,4,4,4,3,4,5,5,3,2,3,1,1,3,3,1,3,1,1,3,3,2,4,5,3,3,5,0,4,0,3,0,4,4,3,5,3,3,0,3,4,0,4,3), +(0,5,0,5,0,3,0,2,0,4,4,3,5,2,4,3,3,3,4,4,4,3,5,3,5,3,3,1,4,0,4,3,3,0,3,3,0,4,4,4,4,5,4,3,3,5,5,3,2,3,1,2,3,2,0,1,0,0,3,2,2,4,4,3,1,5,0,4,0,3,0,4,3,1,3,2,1,0,3,3,0,3,3), +(0,4,0,5,0,5,0,4,0,4,5,5,5,3,4,3,3,2,5,4,4,3,5,3,5,3,4,0,4,3,4,4,3,2,4,4,3,4,5,4,4,5,5,0,3,5,5,4,1,3,3,2,3,3,1,3,1,0,4,3,1,4,4,3,4,5,0,4,0,2,0,4,3,4,4,3,3,0,4,0,0,5,5), +(0,4,0,4,0,5,0,1,1,3,3,4,4,3,4,1,3,0,5,1,3,0,3,1,3,1,1,0,3,0,3,3,4,0,4,3,0,4,4,4,3,4,4,0,3,5,4,1,0,3,0,0,2,3,0,3,1,0,3,1,0,3,2,1,3,5,0,3,0,1,0,3,2,3,3,4,4,0,2,2,0,4,4), +(2,4,0,5,0,4,0,3,0,4,5,5,4,3,5,3,5,3,5,3,5,2,5,3,4,3,3,4,3,4,5,3,2,1,5,4,3,2,3,4,5,3,4,1,2,5,4,3,0,3,3,0,3,2,0,2,3,0,4,1,0,3,4,3,3,5,0,3,0,1,0,4,5,5,5,4,3,0,4,2,0,3,5), +(0,5,0,4,0,4,0,2,0,5,4,3,4,3,4,3,3,3,4,3,4,2,5,3,5,3,4,1,4,3,4,4,4,0,3,5,0,4,4,4,4,5,3,1,3,4,5,3,3,3,3,3,3,3,0,2,2,0,3,3,2,4,3,3,3,5,3,4,1,3,3,5,3,2,0,0,0,0,4,3,1,3,3), +(0,1,0,3,0,3,0,1,0,1,3,3,3,2,3,3,3,0,3,0,0,0,3,1,3,0,0,0,2,2,2,3,0,0,3,2,0,1,2,4,1,3,3,0,0,3,3,3,0,1,0,0,2,1,0,0,3,0,3,1,0,3,0,0,1,3,0,2,0,1,0,3,3,1,3,3,0,0,1,1,0,3,3), +(0,2,0,3,0,2,1,4,0,2,2,3,1,1,3,1,1,0,2,0,3,1,2,3,1,3,0,0,1,0,4,3,2,3,3,3,1,4,2,3,3,3,3,1,0,3,1,4,0,1,1,0,1,2,0,1,1,0,1,1,0,3,1,3,2,2,0,1,0,0,0,2,3,3,3,1,0,0,0,0,0,2,3), +(0,5,0,4,0,5,0,2,0,4,5,5,3,3,4,3,3,1,5,4,4,2,4,4,4,3,4,2,4,3,5,5,4,3,3,4,3,3,5,5,4,5,5,1,3,4,5,3,1,4,3,1,3,3,0,3,3,1,4,3,1,4,5,3,3,5,0,4,0,3,0,5,3,3,1,4,3,0,4,0,1,5,3), +(0,5,0,5,0,4,0,2,0,4,4,3,4,3,3,3,3,3,5,4,4,4,4,4,4,5,3,3,5,2,4,4,4,3,4,4,3,3,4,4,5,5,3,3,4,3,4,3,3,4,3,3,3,3,1,2,2,1,4,3,3,5,4,4,3,4,0,4,0,3,0,4,4,4,4,4,1,0,4,2,0,2,4), +(0,4,0,4,0,3,0,1,0,3,5,2,3,0,3,0,2,1,4,2,3,3,4,1,4,3,3,2,4,1,3,3,3,0,3,3,0,0,3,3,3,5,3,3,3,3,3,2,0,2,0,0,2,0,0,2,0,0,1,0,0,3,1,2,2,3,0,3,0,2,0,4,4,3,3,4,1,0,3,0,0,2,4), +(0,0,0,4,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,1,0,2,0,1,0,0,0,0,0,3,1,3,0,3,2,0,0,0,1,0,3,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,4,0,2,0,0,0,0,0,0,2), +(0,2,1,3,0,2,0,2,0,3,3,3,3,1,3,1,3,3,3,3,3,3,4,2,2,1,2,1,4,0,4,3,1,3,3,3,2,4,3,5,4,3,3,3,3,3,3,3,0,1,3,0,2,0,0,1,0,0,1,0,0,4,2,0,2,3,0,3,3,0,3,3,4,2,3,1,4,0,1,2,0,2,3), +(0,3,0,3,0,1,0,3,0,2,3,3,3,0,3,1,2,0,3,3,2,3,3,2,3,2,3,1,3,0,4,3,2,0,3,3,1,4,3,3,2,3,4,3,1,3,3,1,1,0,1,1,0,1,0,1,0,1,0,0,0,4,1,1,0,3,0,3,1,0,2,3,3,3,3,3,1,0,0,2,0,3,3), +(0,0,0,0,0,0,0,0,0,0,3,0,2,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,3,0,3,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,2,0,2,3,0,0,0,0,0,0,0,0,3), +(0,2,0,3,1,3,0,3,0,2,3,3,3,1,3,1,3,1,3,1,3,3,3,1,3,0,2,3,1,1,4,3,3,2,3,3,1,2,2,4,1,3,3,0,1,4,2,3,0,1,3,0,3,0,0,1,3,0,2,0,0,3,3,2,1,3,0,3,0,2,0,3,4,4,4,3,1,0,3,0,0,3,3), +(0,2,0,1,0,2,0,0,0,1,3,2,2,1,3,0,1,1,3,0,3,2,3,1,2,0,2,0,1,1,3,3,3,0,3,3,1,1,2,3,2,3,3,1,2,3,2,0,0,1,0,0,0,0,0,0,3,0,1,0,0,2,1,2,1,3,0,3,0,0,0,3,4,4,4,3,2,0,2,0,0,2,4), +(0,0,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,3,1,0,0,0,0,0,0,0,3), +(0,3,0,3,0,2,0,3,0,3,3,3,2,3,2,2,2,0,3,1,3,3,3,2,3,3,0,0,3,0,3,2,2,0,2,3,1,4,3,4,3,3,2,3,1,5,4,4,0,3,1,2,1,3,0,3,1,1,2,0,2,3,1,3,1,3,0,3,0,1,0,3,3,4,4,2,1,0,2,1,0,2,4), +(0,1,0,3,0,1,0,2,0,1,4,2,5,1,4,0,2,0,2,1,3,1,4,0,2,1,0,0,2,1,4,1,1,0,3,3,0,5,1,3,2,3,3,1,0,3,2,3,0,1,0,0,0,0,0,0,1,0,0,0,0,4,0,1,0,3,0,2,0,1,0,3,3,3,4,3,3,0,0,0,0,2,3), +(0,0,0,1,0,0,0,0,0,0,2,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,1,0,0,1,0,0,0,0,0,3), +(0,1,0,3,0,4,0,3,0,2,4,3,1,0,3,2,2,1,3,1,2,2,3,1,1,1,2,1,3,0,1,2,0,1,3,2,1,3,0,5,5,1,0,0,1,3,2,1,0,3,0,0,1,0,0,0,0,0,3,4,0,1,1,1,3,2,0,2,0,1,0,2,3,3,1,2,3,0,1,0,1,0,4), +(0,0,0,1,0,3,0,3,0,2,2,1,0,0,4,0,3,0,3,1,3,0,3,0,3,0,1,0,3,0,3,1,3,0,3,3,0,0,1,2,1,1,1,0,1,2,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,2,2,1,2,0,0,2,0,0,0,0,2,3,3,3,3,0,0,0,0,1,4), +(0,0,0,3,0,3,0,0,0,0,3,1,1,0,3,0,1,0,2,0,1,0,0,0,0,0,0,0,1,0,3,0,2,0,2,3,0,0,2,2,3,1,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,2,3), +(2,4,0,5,0,5,0,4,0,3,4,3,3,3,4,3,3,3,4,3,4,4,5,4,5,5,5,2,3,0,5,5,4,1,5,4,3,1,5,4,3,4,4,3,3,4,3,3,0,3,2,0,2,3,0,3,0,0,3,3,0,5,3,2,3,3,0,3,0,3,0,3,4,5,4,5,3,0,4,3,0,3,4), +(0,3,0,3,0,3,0,3,0,3,3,4,3,2,3,2,3,0,4,3,3,3,3,3,3,3,3,0,3,2,4,3,3,1,3,4,3,4,4,4,3,4,4,3,2,4,4,1,0,2,0,0,1,1,0,2,0,0,3,1,0,5,3,2,1,3,0,3,0,1,2,4,3,2,4,3,3,0,3,2,0,4,4), +(0,3,0,3,0,1,0,0,0,1,4,3,3,2,3,1,3,1,4,2,3,2,4,2,3,4,3,0,2,2,3,3,3,0,3,3,3,0,3,4,1,3,3,0,3,4,3,3,0,1,1,0,1,0,0,0,4,0,3,0,0,3,1,2,1,3,0,4,0,1,0,4,3,3,4,3,3,0,2,0,0,3,3), +(0,3,0,4,0,1,0,3,0,3,4,3,3,0,3,3,3,1,3,1,3,3,4,3,3,3,0,0,3,1,5,3,3,1,3,3,2,5,4,3,3,4,5,3,2,5,3,4,0,1,0,0,0,0,0,2,0,0,1,1,0,4,2,2,1,3,0,3,0,2,0,4,4,3,5,3,2,0,1,1,0,3,4), +(0,5,0,4,0,5,0,2,0,4,4,3,3,2,3,3,3,1,4,3,4,1,5,3,4,3,4,0,4,2,4,3,4,1,5,4,0,4,4,4,4,5,4,1,3,5,4,2,1,4,1,1,3,2,0,3,1,0,3,2,1,4,3,3,3,4,0,4,0,3,0,4,4,4,3,3,3,0,4,2,0,3,4), +(1,4,0,4,0,3,0,1,0,3,3,3,1,1,3,3,2,2,3,3,1,0,3,2,2,1,2,0,3,1,2,1,2,0,3,2,0,2,2,3,3,4,3,0,3,3,1,2,0,1,1,3,1,2,0,0,3,0,1,1,0,3,2,2,3,3,0,3,0,0,0,2,3,3,4,3,3,0,1,0,0,1,4), +(0,4,0,4,0,4,0,0,0,3,4,4,3,1,4,2,3,2,3,3,3,1,4,3,4,0,3,0,4,2,3,3,2,2,5,4,2,1,3,4,3,4,3,1,3,3,4,2,0,2,1,0,3,3,0,0,2,0,3,1,0,4,4,3,4,3,0,4,0,1,0,2,4,4,4,4,4,0,3,2,0,3,3), +(0,0,0,1,0,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,3,2,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2), +(0,2,0,3,0,4,0,4,0,1,3,3,3,0,4,0,2,1,2,1,1,1,2,0,3,1,1,0,1,0,3,1,0,0,3,3,2,0,1,1,0,0,0,0,0,1,0,2,0,2,2,0,3,1,0,0,1,0,1,1,0,1,2,0,3,0,0,0,0,1,0,0,3,3,4,3,1,0,1,0,3,0,2), +(0,0,0,3,0,5,0,0,0,0,1,0,2,0,3,1,0,1,3,0,0,0,2,0,0,0,1,0,0,0,1,1,0,0,4,0,0,0,2,3,0,1,4,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,1,0,0,0,0,0,0,0,2,0,0,3,0,0,0,0,0,3), +(0,2,0,5,0,5,0,1,0,2,4,3,3,2,5,1,3,2,3,3,3,0,4,1,2,0,3,0,4,0,2,2,1,1,5,3,0,0,1,4,2,3,2,0,3,3,3,2,0,2,4,1,1,2,0,1,1,0,3,1,0,1,3,1,2,3,0,2,0,0,0,1,3,5,4,4,4,0,3,0,0,1,3), +(0,4,0,5,0,4,0,4,0,4,5,4,3,3,4,3,3,3,4,3,4,4,5,3,4,5,4,2,4,2,3,4,3,1,4,4,1,3,5,4,4,5,5,4,4,5,5,5,2,3,3,1,4,3,1,3,3,0,3,3,1,4,3,4,4,4,0,3,0,4,0,3,3,4,4,5,0,0,4,3,0,4,5), +(0,4,0,4,0,3,0,3,0,3,4,4,4,3,3,2,4,3,4,3,4,3,5,3,4,3,2,1,4,2,4,4,3,1,3,4,2,4,5,5,3,4,5,4,1,5,4,3,0,3,2,2,3,2,1,3,1,0,3,3,3,5,3,3,3,5,4,4,2,3,3,4,3,3,3,2,1,0,3,2,1,4,3), +(0,4,0,5,0,4,0,3,0,3,5,5,3,2,4,3,4,0,5,4,4,1,4,4,4,3,3,3,4,3,5,5,2,3,3,4,1,2,5,5,3,5,5,2,3,5,5,4,0,3,2,0,3,3,1,1,5,1,4,1,0,4,3,2,3,5,0,4,0,3,0,5,4,3,4,3,0,0,4,1,0,4,4), +(1,3,0,4,0,2,0,2,0,2,5,5,3,3,3,3,3,0,4,2,3,4,4,4,3,4,0,0,3,4,5,4,3,3,3,3,2,5,5,4,5,5,5,4,3,5,5,5,1,3,1,0,1,0,0,3,2,0,4,2,0,5,2,3,2,4,1,3,0,3,0,4,5,4,5,4,3,0,4,2,0,5,4), +(0,3,0,4,0,5,0,3,0,3,4,4,3,2,3,2,3,3,3,3,3,2,4,3,3,2,2,0,3,3,3,3,3,1,3,3,3,0,4,4,3,4,4,1,1,4,4,2,0,3,1,0,1,1,0,4,1,0,2,3,1,3,3,1,3,4,0,3,0,1,0,3,1,3,0,0,1,0,2,0,0,4,4), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), +(0,3,0,3,0,2,0,3,0,1,5,4,3,3,3,1,4,2,1,2,3,4,4,2,4,4,5,0,3,1,4,3,4,0,4,3,3,3,2,3,2,5,3,4,3,2,2,3,0,0,3,0,2,1,0,1,2,0,0,0,0,2,1,1,3,1,0,2,0,4,0,3,4,4,4,5,2,0,2,0,0,1,3), +(0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,1,0,0,1,1,0,0,0,4,2,1,1,0,1,0,3,2,0,0,3,1,1,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,1,0,0,0,2,0,0,0,1,4,0,4,2,1,0,0,0,0,0,1), +(0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,0,0,0,0,3,1,0,0,0,2,0,2,1,0,0,1,2,1,0,1,1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,1,3,1,0,0,0,0,0,1,0,0,2,1,0,0,0,0,0,0,0,0,2), +(0,4,0,4,0,4,0,3,0,4,4,3,4,2,4,3,2,0,4,4,4,3,5,3,5,3,3,2,4,2,4,3,4,3,1,4,0,2,3,4,4,4,3,3,3,4,4,4,3,4,1,3,4,3,2,1,2,1,3,3,3,4,4,3,3,5,0,4,0,3,0,4,3,3,3,2,1,0,3,0,0,3,3), +(0,4,0,3,0,3,0,3,0,3,5,5,3,3,3,3,4,3,4,3,3,3,4,4,4,3,3,3,3,4,3,5,3,3,1,3,2,4,5,5,5,5,4,3,4,5,5,3,2,2,3,3,3,3,2,3,3,1,2,3,2,4,3,3,3,4,0,4,0,2,0,4,3,2,2,1,2,0,3,0,0,4,1), +) + +class JapaneseContextAnalysis(object): + NUM_OF_CATEGORY = 6 + DONT_KNOW = -1 + ENOUGH_REL_THRESHOLD = 100 + MAX_REL_THRESHOLD = 1000 + MINIMUM_DATA_THRESHOLD = 4 + + def __init__(self): + self._total_rel = None + self._rel_sample = None + self._need_to_skip_char_num = None + self._last_char_order = None + self._done = None + self.reset() + + def reset(self): + self._total_rel = 0 # total sequence received + # category counters, each integer counts sequence in its category + self._rel_sample = [0] * self.NUM_OF_CATEGORY + # if last byte in current buffer is not the last byte of a character, + # we need to know how many bytes to skip in next buffer + self._need_to_skip_char_num = 0 + self._last_char_order = -1 # The order of previous char + # If this flag is set to True, detection is done and conclusion has + # been made + self._done = False + + def feed(self, byte_str, num_bytes): + if self._done: + return + + # The buffer we got is byte oriented, and a character may span in more than one + # buffers. In case the last one or two byte in last buffer is not + # complete, we record how many byte needed to complete that character + # and skip these bytes here. We can choose to record those bytes as + # well and analyse the character once it is complete, but since a + # character will not make much difference, by simply skipping + # this character will simply our logic and improve performance. + i = self._need_to_skip_char_num + while i < num_bytes: + order, char_len = self.get_order(byte_str[i:i + 2]) + i += char_len + if i > num_bytes: + self._need_to_skip_char_num = i - num_bytes + self._last_char_order = -1 + else: + if (order != -1) and (self._last_char_order != -1): + self._total_rel += 1 + if self._total_rel > self.MAX_REL_THRESHOLD: + self._done = True + break + self._rel_sample[jp2CharContext[self._last_char_order][order]] += 1 + self._last_char_order = order + + def got_enough_data(self): + return self._total_rel > self.ENOUGH_REL_THRESHOLD + + def get_confidence(self): + # This is just one way to calculate confidence. It works well for me. + if self._total_rel > self.MINIMUM_DATA_THRESHOLD: + return (self._total_rel - self._rel_sample[0]) / self._total_rel + else: + return self.DONT_KNOW + + def get_order(self, byte_str): + return -1, 1 + +class SJISContextAnalysis(JapaneseContextAnalysis): + def __init__(self): + super(SJISContextAnalysis, self).__init__() + self._charset_name = "SHIFT_JIS" + + @property + def charset_name(self): + return self._charset_name + + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (0x81 <= first_char <= 0x9F) or (0xE0 <= first_char <= 0xFC): + char_len = 2 + if (first_char == 0x87) or (0xFA <= first_char <= 0xFC): + self._charset_name = "CP932" + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 202) and (0x9F <= second_char <= 0xF1): + return second_char - 0x9F, char_len + + return -1, char_len + +class EUCJPContextAnalysis(JapaneseContextAnalysis): + def get_order(self, byte_str): + if not byte_str: + return -1, 1 + # find out current char's byte length + first_char = byte_str[0] + if (first_char == 0x8E) or (0xA1 <= first_char <= 0xFE): + char_len = 2 + elif first_char == 0x8F: + char_len = 3 + else: + char_len = 1 + + # return its order if it is hiragana + if len(byte_str) > 1: + second_char = byte_str[1] + if (first_char == 0xA4) and (0xA1 <= second_char <= 0xF3): + return second_char - 0xA1, char_len + + return -1, char_len + + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py new file mode 100644 index 0000000..2aa4fb2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langbulgarianmodel.py @@ -0,0 +1,228 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +# this table is modified base on win1251BulgarianCharToOrderMap, so +# only number <64 is sure valid + +Latin5_BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209, # 80 +210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225, # 90 + 81,226,227,228,229,230,105,231,232,233,234,235,236, 45,237,238, # a0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # b0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,239, 67,240, 60, 56, # c0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # d0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,241, 42, 16, # e0 + 62,242,243,244, 58,245, 98,246,247,248,249,250,251, 91,252,253, # f0 +) + +win1251BulgarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 77, 90, 99,100, 72,109,107,101, 79,185, 81,102, 76, 94, 82, # 40 +110,186,108, 91, 74,119, 84, 96,111,187,115,253,253,253,253,253, # 50 +253, 65, 69, 70, 66, 63, 68,112,103, 92,194,104, 95, 86, 87, 71, # 60 +116,195, 85, 93, 97,113,196,197,198,199,200,253,253,253,253,253, # 70 +206,207,208,209,210,211,212,213,120,214,215,216,217,218,219,220, # 80 +221, 78, 64, 83,121, 98,117,105,222,223,224,225,226,227,228,229, # 90 + 88,230,231,232,233,122, 89,106,234,235,236,237,238, 45,239,240, # a0 + 73, 80,118,114,241,242,243,244,245, 62, 58,246,247,248,249,250, # b0 + 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, # c0 + 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61,251, 67,252, 60, 56, # d0 + 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, # e0 + 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52,253, 42, 16, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 96.9392% +# first 1024 sequences:3.0618% +# rest sequences: 0.2992% +# negative sequences: 0.0020% +BulgarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,2,2,1,2,2, +3,1,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,0,1, +0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,3,3,0,3,1,0, +0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,1,3,2,3,3,3,3,3,3,3,3,0,3,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,2,2,1,3,3,3,3,2,2,2,1,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,2,2,3,3,1,1,2,3,3,2,3,3,3,3,2,1,2,0,2,0,3,0,0, +0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,1,3,3,3,3,3,2,3,2,3,3,3,3,3,2,3,3,1,3,0,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,1,3,3,2,3,3,3,1,3,3,2,3,2,2,2,0,0,2,0,2,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,0,3,3,3,2,2,3,3,3,1,2,2,3,2,1,1,2,0,2,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,2,3,3,1,2,3,2,2,2,3,3,3,3,3,2,2,3,1,2,0,2,1,2,0,0, +0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,3,3,3,3,2,3,3,3,2,3,3,2,3,2,2,2,3,1,2,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,2,2,1,3,1,3,2,2,3,0,0,1,0,1,0,1,0,0, +0,0,0,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,2,3,2,2,3,1,2,1,1,1,2,3,1,3,1,2,2,0,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,1,3,2,2,3,3,1,2,3,1,1,3,3,3,3,1,2,2,1,1,1,0,2,0,2,0,1, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,2,2,3,3,3,2,2,1,1,2,0,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,0,1,2,1,3,3,2,3,3,3,3,3,2,3,2,1,0,3,1,2,1,2,1,2,3,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,1,3,3,2,3,3,2,2,2,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,3,3,3,3,3,2,1,1,2,1,3,3,0,3,1,1,1,1,3,2,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,2,2,3,3,3,3,3,3,3,3,3,3,3,1,1,3,1,3,3,2,3,2,2,2,3,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,2,3,2,1,1,1,1,1,3,1,3,1,1,0,0,0,1,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,2,0,3,2,0,3,0,2,0,0,2,1,3,1,0,0,1,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,1,1,1,2,1,1,2,1,1,1,2,2,1,2,1,1,1,0,1,1,0,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,2,1,3,1,1,2,1,3,2,1,1,0,1,2,3,2,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,2,2,1,0,1,0,0,1,0,0,0,2,1,0,3,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,2,3,2,3,3,1,3,2,1,1,1,2,1,1,2,1,3,0,1,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,2,3,2,2,2,3,1,2,2,1,1,2,1,1,2,2,0,1,1,0,1,0,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,1,0,2,2,1,3,2,1,0,0,2,0,2,0,1,0,0,0,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,3,1,2,0,2,3,1,2,3,2,0,1,3,1,2,1,1,1,0,0,1,0,0,2,2,2,3, +2,2,2,2,1,2,1,1,2,2,1,1,2,0,1,1,1,0,0,1,1,0,0,1,1,0,0,0,1,1,0,1, +3,3,3,3,3,2,1,2,2,1,2,0,2,0,1,0,1,2,1,2,1,1,0,0,0,1,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1, +3,3,2,3,3,1,1,3,1,0,3,2,1,0,0,0,1,2,0,2,0,1,0,0,0,1,0,1,2,1,2,2, +1,1,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,0,1,2,1,1,1,0,0,0,0,0,1,1,0,0, +3,1,0,1,0,2,3,2,2,2,3,2,2,2,2,2,1,0,2,1,2,1,1,1,0,1,2,1,2,2,2,1, +1,1,2,2,2,2,1,2,1,1,0,1,2,1,2,2,2,1,1,1,0,1,1,1,1,2,0,1,0,0,0,0, +2,3,2,3,3,0,0,2,1,0,2,1,0,0,0,0,2,3,0,2,0,0,0,0,0,1,0,0,2,0,1,2, +2,1,2,1,2,2,1,1,1,2,1,1,1,0,1,2,2,1,1,1,1,1,0,1,1,1,0,0,1,2,0,0, +3,3,2,2,3,0,2,3,1,1,2,0,0,0,1,0,0,2,0,2,0,0,0,1,0,1,0,1,2,0,2,2, +1,1,1,1,2,1,0,1,2,2,2,1,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,1,0,0, +2,3,2,3,3,0,0,3,0,1,1,0,1,0,0,0,2,2,1,2,0,0,0,0,0,0,0,0,2,0,1,2, +2,2,1,1,1,1,1,2,2,2,1,0,2,0,1,0,1,0,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +3,3,3,3,2,2,2,2,2,0,2,1,1,1,1,2,1,2,1,1,0,2,0,1,0,1,0,0,2,0,1,2, +1,1,1,1,1,1,1,2,2,1,1,0,2,0,1,0,2,0,0,1,1,1,0,0,2,0,0,0,1,1,0,0, +2,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0,0,0,0,1,2,0,1,2, +2,2,2,1,1,2,1,1,2,2,2,1,2,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,1,1,0,0, +2,3,3,3,3,0,2,2,0,2,1,0,0,0,1,1,1,2,0,2,0,0,0,3,0,0,0,0,2,0,2,2, +1,1,1,2,1,2,1,1,2,2,2,1,2,0,1,1,1,0,1,1,1,1,0,2,1,0,0,0,1,1,0,0, +2,3,3,3,3,0,2,1,0,0,2,0,0,0,0,0,1,2,0,2,0,0,0,0,0,0,0,0,2,0,1,2, +1,1,1,2,1,1,1,1,2,2,2,0,1,0,1,1,1,0,0,1,1,1,0,0,1,0,0,0,0,1,0,0, +3,3,2,2,3,0,1,0,1,0,0,0,0,0,0,0,1,1,0,3,0,0,0,0,0,0,0,0,1,0,2,2, +1,1,1,1,1,2,1,1,2,2,1,2,2,1,0,1,1,1,1,1,0,1,0,0,1,0,0,0,1,1,0,0, +3,1,0,1,0,2,2,2,2,3,2,1,1,1,2,3,0,0,1,0,2,1,1,0,1,1,1,1,2,1,1,1, +1,2,2,1,2,1,2,2,1,1,0,1,2,1,2,2,1,1,1,0,0,1,1,1,2,1,0,1,0,0,0,0, +2,1,0,1,0,3,1,2,2,2,2,1,2,2,1,1,1,0,2,1,2,2,1,1,2,1,1,0,2,1,1,1, +1,2,2,2,2,2,2,2,1,2,0,1,1,0,2,1,1,1,1,1,0,0,1,1,1,1,0,1,0,0,0,0, +2,1,1,1,1,2,2,2,2,1,2,2,2,1,2,2,1,1,2,1,2,3,2,2,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,1,2,0,1,2,1,1,0,1,0,1,2,1,2,0,0,0,1,1,0,0,0,1,0,0,2, +1,1,0,0,1,1,0,1,1,1,1,0,2,0,1,1,1,0,0,1,1,0,0,0,0,1,0,0,0,1,0,0, +2,0,0,0,0,1,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,2,1,1,1, +1,2,2,2,2,1,1,2,1,2,1,1,1,0,2,1,2,1,1,1,0,2,1,1,1,1,0,1,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,3,2,0,0,0,0,1,0,0,0,0,0,0,1,1,0,2,0,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,1,1,0,0,2,2,2,2,2,0,1,1,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1, +2,3,1,2,1,0,1,1,0,2,2,2,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,1,2, +1,1,1,1,2,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0, +2,2,2,2,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,0,2,2, +1,1,1,1,1,0,0,1,2,1,1,0,1,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,2,0,1,1,0,0,0,1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,1,1, +0,0,0,1,1,1,1,1,1,1,1,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,3,2,0,0,1,0,0,1,0,0,0,0,0,0,1,0,2,0,0,0,1,0,0,0,0,0,0,0,2, +1,1,0,0,1,0,0,0,1,1,0,0,1,0,1,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,2,2,1,2,1,2,2,1,1,2,1,1,1,0,1,1,1,1,2,0,1,0,1,1,1,1,0,1,1, +1,1,2,1,1,1,1,1,1,0,0,1,2,1,1,1,1,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0, +1,0,0,1,3,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,0,1,0,2,0,0,0,0,0,1,1,1,0,1,0,0,0,0,0,0,0,0,2,0,0,1, +0,2,0,1,0,0,1,1,2,0,1,0,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,1,1,0,2,1,0,1,1,1,0,0,1,0,2,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,0,0,1,0,0,0,1,1,0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,1,0,1,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,1,2,1,1,1,1,1,1,2,2,1,0,0,1,0,1,0,0,0,0,1,1,1,1,0,0,0, +1,1,2,1,1,1,1,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,1,2,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +0,1,1,0,1,1,1,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,2,0,0,2,0,1,0,0,1,0,0,1, +1,1,0,0,1,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0, +1,1,1,1,1,1,1,2,0,0,0,0,0,0,2,1,0,1,1,0,0,1,1,1,0,1,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,1,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +) + +Latin5BulgarianModel = { + 'char_to_order_map': Latin5_BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Bulgairan', +} + +Win1251BulgarianModel = { + 'char_to_order_map': win1251BulgarianCharToOrderMap, + 'precedence_matrix': BulgarianLangModel, + 'typical_positive_ratio': 0.969392, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Bulgarian', +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py new file mode 100644 index 0000000..e5f9a1f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langcyrillicmodel.py @@ -0,0 +1,333 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# KOI8-R language model +# Character Mapping Table: +KOI8R_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, # 80 +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, # 90 +223,224,225, 68,226,227,228,229,230,231,232,233,234,235,236,237, # a0 +238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253, # b0 + 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, # c0 + 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, # d0 + 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, # e0 + 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, # f0 +) + +win1251_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246, 68,247,248,249,250,251,252,253, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +) + +latin5_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +macCyrillic_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, +239,240,241,242,243,244,245,246,247,248,249,250,251,252, 68, 16, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27,255, +) + +IBM855_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 +191,192,193,194, 68,195,196,197,198,199,200,201,202,203,204,205, +206,207,208,209,210,211,212,213,214,215,216,217, 27, 59, 54, 70, + 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46,218,219, +220,221,222,223,224, 26, 55, 4, 42,225,226,227,228, 23, 60,229, +230,231,232,233,234,235, 11, 36,236,237,238,239,240,241,242,243, + 8, 49, 12, 38, 5, 31, 1, 34, 15,244,245,246,247, 35, 16,248, + 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61,249, +250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50,251,252,255, +) + +IBM866_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,142,143,144,145,146,147,148,149,150,151,152, 74,153, 75,154, # 40 +155,156,157,158,159,160,161,162,163,164,165,253,253,253,253,253, # 50 +253, 71,172, 66,173, 65,174, 76,175, 64,176,177, 77, 72,178, 69, # 60 + 67,179, 78, 73,180,181, 79,182,183,184,185,253,253,253,253,253, # 70 + 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, + 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, + 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, +191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206, +207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222, +223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238, + 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, +239, 68,240,241,242,243,244,245,246,247,248,249,250,251,252,255, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 97.6601% +# first 1024 sequences: 2.3389% +# rest sequences: 0.1237% +# negative sequences: 0.0009% +RussianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,1,3,3,3,3,1,3,3,3,2,3,2,3,3, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,2,2,2,2,2,0,0,2, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,2,3,3,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,0,0,3,3,3,3,3,3,3,3,3,3,3,2,1, +0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,2,3,1,3,3,1,3,3,3,3,2,2,3,0,2,2,2,3,3,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,2,3,2,3,3,3,2,1,2,2,0,1,2,2,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,3,0,2,2,3,3,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,1,2,3,2,2,3,2,3,3,3,3,2,2,3,0,3,2,2,3,1,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,3,3,3,3,2,2,2,0,3,3,3,2,2,2,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,3,2,3,3,3,3,3,3,2,3,2,2,0,1,3,2,1,2,2,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,2,1,1,3,0,1,1,1,1,2,1,1,0,2,2,2,1,2,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,2,2,2,2,1,3,2,3,2,3,2,1,2,2,0,1,1,2,1,2,1,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,2,3,3,3,2,2,2,2,0,2,2,2,2,3,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,2,3,2,2,3,3,3,3,3,3,3,3,3,1,3,2,0,0,3,3,3,3,2,3,3,3,3,2,3,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,2,3,3,0,2,1,0,3,2,3,2,3,0,0,1,2,0,0,1,0,1,2,1,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,3,0,2,3,3,3,3,2,3,3,3,3,1,2,2,0,0,2,3,2,2,2,3,2,3,2,2,3,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,2,3,2,3,0,1,2,3,3,2,0,2,3,0,0,2,3,2,2,0,1,3,1,3,2,2,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,0,2,3,3,3,3,3,3,3,3,2,1,3,2,0,0,2,2,3,3,3,2,3,3,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,3,3,0,0,1,1,1,1,1,2,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,3,3,3,3,3,0,3,2,3,3,2,3,2,0,2,1,0,1,1,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,2,2,2,3,1,3,2,3,1,1,2,1,0,2,2,2,2,1,3,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +2,2,3,3,3,3,3,1,2,2,1,3,1,0,3,0,0,3,0,0,0,1,1,0,1,2,1,0,0,0,0,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,2,1,1,3,3,3,2,2,1,2,2,3,1,1,2,0,0,2,2,1,3,0,0,2,1,1,2,1,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,3,3,3,1,2,2,2,1,2,1,3,3,1,1,2,1,2,1,2,2,0,2,0,0,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,3,2,1,3,2,2,3,2,0,3,2,0,3,0,1,0,1,1,0,0,1,1,1,1,0,1,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,3,3,3,2,2,2,3,3,1,2,1,2,1,0,1,0,1,1,0,1,0,0,2,1,1,1,0,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,1,1,2,1,2,3,3,2,2,1,2,2,3,0,2,1,0,0,2,2,3,2,1,2,2,2,2,2,3,1,0, +0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,1,1,0,1,1,2,2,1,1,3,0,0,1,3,1,1,1,0,0,0,1,0,1,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,3,3,3,2,0,0,0,2,1,0,1,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,0,2,3,2,2,2,1,2,2,2,1,2,1,0,0,1,1,1,0,2,0,1,1,1,0,0,1,1, +1,0,0,0,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,3,0,0,0,0,1,0,0,0,0,3,0,1,2,1,0,0,0,0,0,0,0,1,1,0,0,1,1, +1,0,1,0,1,2,0,0,1,1,2,1,0,1,1,1,1,0,1,1,1,1,0,1,0,0,1,0,0,1,1,0, +2,2,3,2,2,2,3,1,2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,0,1,0,1,1,1,0,2,1, +1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,1,1,0,1,1,0, +3,3,3,2,2,2,2,3,2,2,1,1,2,2,2,2,1,1,3,1,2,1,2,0,0,1,1,0,1,0,2,1, +1,1,1,1,1,2,1,0,1,1,1,1,0,1,0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,1,1,0, +2,0,0,1,0,3,2,2,2,2,1,2,1,2,1,2,0,0,0,2,1,2,2,1,1,2,2,0,1,1,0,2, +1,1,1,1,1,0,1,1,1,2,1,1,1,2,1,0,1,2,1,1,1,1,0,1,1,1,0,0,1,0,0,1, +1,3,2,2,2,1,1,1,2,3,0,0,0,0,2,0,2,2,1,0,0,0,0,0,0,1,0,0,0,0,1,1, +1,0,1,1,0,1,0,1,1,0,1,1,0,2,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,3,2,3,2,1,2,2,2,2,1,0,0,0,2,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,2,1, +1,1,2,1,0,2,0,0,1,0,1,0,0,1,0,0,1,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0, +3,0,0,1,0,2,2,2,3,2,2,2,2,2,2,2,0,0,0,2,1,2,1,1,1,2,2,0,0,0,1,2, +1,1,1,1,1,0,1,2,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1, +2,3,2,3,3,2,0,1,1,1,0,0,1,0,2,0,1,1,3,1,0,0,0,0,0,0,0,1,0,0,2,1, +1,1,1,1,1,1,1,0,1,0,1,1,1,1,0,1,1,1,0,0,1,1,0,1,0,0,0,0,0,0,1,0, +2,3,3,3,3,1,2,2,2,2,0,1,1,0,2,1,1,1,2,1,0,1,1,0,0,1,0,1,0,0,2,0, +0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,3,3,2,0,0,1,1,2,2,1,0,0,2,0,1,1,3,0,0,1,0,0,0,0,0,1,0,1,2,1, +1,1,2,0,1,1,1,0,1,0,1,1,0,1,0,1,1,1,1,0,1,0,0,0,0,0,0,1,0,1,1,0, +1,3,2,3,2,1,0,0,2,2,2,0,1,0,2,0,1,1,1,0,1,0,0,0,3,0,1,1,0,0,2,1, +1,1,1,0,1,1,0,0,0,0,1,1,0,1,0,0,2,1,1,0,1,0,0,0,1,0,1,0,0,1,1,0, +3,1,2,1,1,2,2,2,2,2,2,1,2,2,1,1,0,0,0,2,2,2,0,0,0,1,2,1,0,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,2,1,1,1,0,1,0,1,1,0,1,1,1,0,0,1, +3,0,0,0,0,2,0,1,1,1,1,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,0,0,1,0,1, +1,1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,1,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1, +1,3,3,2,2,0,0,0,2,2,0,0,0,1,2,0,1,1,2,0,0,0,0,0,0,0,0,1,0,0,2,1, +0,1,1,0,0,1,1,0,0,0,1,1,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +2,3,2,3,2,0,0,0,0,1,1,0,0,0,2,0,2,0,2,0,0,0,0,0,1,0,0,1,0,0,1,1, +1,1,2,0,1,2,1,0,1,1,2,1,1,1,1,1,2,1,1,0,1,0,0,1,1,1,1,1,0,1,1,0, +1,3,2,2,2,1,0,0,2,2,1,0,1,2,2,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,1,1, +0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,2,3,1,2,2,2,2,2,2,1,1,0,0,0,1,0,1,0,2,1,1,1,0,0,0,0,1, +1,1,0,1,1,0,1,1,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,0,2,0,0,1,0,3,2,1,2,1,2,2,0,1,0,0,0,2,1,0,0,2,1,1,1,1,0,2,0,2, +2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,0,0,0,1,1,1,1,0,1,0,0,1, +1,2,2,2,2,1,0,0,1,0,0,0,0,0,2,0,1,1,1,1,0,0,0,0,1,0,1,2,0,0,2,0, +1,0,1,1,1,2,1,0,1,0,1,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,1,0,1,1,0, +2,1,2,2,2,0,3,0,1,1,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,0,1,1,1,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0, +1,2,2,3,2,2,0,0,1,1,2,0,1,2,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1, +0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,0,1,1,0, +2,2,1,1,2,1,2,2,2,2,2,1,2,2,0,1,0,0,0,1,2,2,2,1,2,1,1,1,1,1,2,1, +1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,0,1, +1,2,2,2,2,0,1,0,2,2,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +0,0,1,0,0,1,0,0,0,0,1,0,1,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,2,2,2,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1, +0,1,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,2,0,0,0,0,1,0,0,1,1,2,0,0,0,0,1,0,1,0,0,1,0,0,2,0,0,0,1, +0,0,1,0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0, +1,2,2,2,1,1,2,0,2,1,1,1,1,0,2,2,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,1, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,1,2,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0, +0,0,1,0,1,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +1,0,0,0,0,2,0,1,2,1,0,1,1,1,0,1,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,1, +0,0,0,0,0,1,0,0,1,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1, +2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,0,0,0,1,0,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,0,1,0,1,0,0,1,1,1,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,0,1,1,0,0,0,0,0,1,0,1,1,0,1,0,0,0, +0,1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +) + +Koi8rModel = { + 'char_to_order_map': KOI8R_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "KOI8-R", + 'language': 'Russian', +} + +Win1251CyrillicModel = { + 'char_to_order_map': win1251_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "windows-1251", + 'language': 'Russian', +} + +Latin5CyrillicModel = { + 'char_to_order_map': latin5_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-5", + 'language': 'Russian', +} + +MacCyrillicModel = { + 'char_to_order_map': macCyrillic_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "MacCyrillic", + 'language': 'Russian', +} + +Ibm866Model = { + 'char_to_order_map': IBM866_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM866", + 'language': 'Russian', +} + +Ibm855Model = { + 'char_to_order_map': IBM855_char_to_order_map, + 'precedence_matrix': RussianLangModel, + 'typical_positive_ratio': 0.976601, + 'keep_english_letter': False, + 'charset_name': "IBM855", + 'language': 'Russian', +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py new file mode 100644 index 0000000..5332221 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langgreekmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin7_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 90,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,248, 61, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +win1253_char_to_order_map = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 82,100,104, 94, 98,101,116,102,111,187,117, 92, 88,113, 85, # 40 + 79,118,105, 83, 67,114,119, 95, 99,109,188,253,253,253,253,253, # 50 +253, 72, 70, 80, 81, 60, 96, 93, 89, 68,120, 97, 77, 86, 69, 55, # 60 + 78,115, 65, 66, 58, 76,106,103, 87,107,112,253,253,253,253,253, # 70 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 80 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 90 +253,233, 61,253,253,253,253,253,253,253,253,253,253, 74,253,253, # a0 +253,253,253,253,247,253,253, 36, 46, 71, 73,253, 54,253,108,123, # b0 +110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, # c0 + 35, 48,250, 37, 33, 45, 56, 50, 84, 57,120,121, 17, 18, 22, 15, # d0 +124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, # e0 + 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27,253, # f0 +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.2851% +# first 1024 sequences:1.7001% +# rest sequences: 0.0359% +# negative sequences: 0.0148% +GreekLangModel = ( +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,2,2,3,3,3,3,3,3,3,3,1,3,3,3,0,2,2,3,3,0,3,0,3,2,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,3,0,3,2,3,3,0,3,2,3,3,3,0,0,3,0,3,0,3,3,2,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,2,3,2,2,3,3,3,3,3,3,3,3,0,3,3,3,3,0,2,3,3,0,3,3,3,3,2,3,3,3,0, +2,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,0,2,1,3,3,3,3,2,3,3,2,3,3,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,3,0,3,2,3,3,0, +2,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,3,0,0,0,0,3,3,0,3,1,3,3,3,0,3,3,0,3,3,3,3,0,0,0,0, +2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,0,3,0,3,3,3,3,3,0,3,2,2,2,3,0,2,3,3,3,3,3,2,3,3,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,2,2,2,3,3,3,3,0,3,1,3,3,3,3,2,3,3,3,3,3,3,3,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,0,0,0,3,3,2,3,3,3,3,3,0,0,3,2,3,0,2,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,0,3,3,0,2,3,0,3,0,3,3,3,0,0,3,0,3,0,2,2,3,3,0,0, +0,0,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,3,2,3,3,3,3,0,3,3,3,3,3,0,3,3,2,3,2,3,3,2,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,2,3,2,3,3,3,3,3,3,0,2,3,2,3,2,2,2,3,2,3,3,2,3,0,2,2,2,3,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,2,3,3,0,0,3,0,3,0,0,0,3,2,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,3,3,0,3,0,0,0,3,3,0,3,3,3,0,0,1,2,3,0, +3,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,2,0,0,3,2,2,3,3,0,3,3,3,3,3,2,1,3,0,3,2,3,3,2,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,3,0,2,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,3,0,3,2,3,0,0,3,3,3,0, +3,0,0,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,0,3,3,3,3,3,3,0,0,3,0,3,0,0,0,3,2,0,3,2,3,0,0,3,2,3,0, +2,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,1,2,2,3,3,3,3,3,3,0,2,3,0,3,0,0,0,3,3,0,3,0,2,0,0,2,3,1,0, +2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,3,0,3,0,3,3,2,3,0,3,3,3,3,3,3,0,3,3,3,0,2,3,0,0,3,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,3,3,0,3,0,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,0,3,3,3,3,3,3,0,0,3,0,2,0,0,0,3,3,0,3,0,3,0,0,2,0,2,0, +0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,3,0,3,0,2,0,3,2,0,3,2,3,2,3,0,0,3,2,3,2,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,3,3,0,0,0,3,0,2,1,0,0,3,2,2,2,0,3,0,0,2,2,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,2,0,3,0,3,0,3,3,0,2,1,2,3,3,0,0,3,0,3,0,3,3,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,3,0,3,3,3,3,3,3,0,2,3,0,3,0,0,0,2,1,0,2,2,3,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,3,0,0,2,3,3,3,2,3,0,0,1,3,0,2,0,0,0,0,3,0,1,0,2,0,0,1,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,3,1,0,3,0,0,0,3,2,0,3,2,3,3,3,0,0,3,0,3,2,2,2,1,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,3,3,3,0,0,3,0,0,0,0,2,0,2,3,3,2,2,2,2,3,0,2,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,3,3,3,2,0,0,0,0,0,0,2,3,0,2,0,2,3,2,0,0,3,0,3,0,3,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,2,3,3,2,2,3,0,2,0,3,0,0,0,2,0,0,0,0,1,2,0,2,0,2,0, +0,2,0,2,0,2,2,0,0,1,0,2,2,2,0,2,2,2,0,2,2,2,0,0,2,0,0,1,0,0,0,0, +0,2,0,3,3,2,0,0,0,0,0,0,1,3,0,2,0,2,2,2,0,0,2,0,3,0,0,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,3,2,0,2,2,0,2,0,2,2,0,2,0,2,2,2,0,0,0,0,0,0,2,3,0,0,0,2, +0,1,2,0,0,0,0,2,2,0,0,0,2,1,0,2,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0, +0,0,2,1,0,2,3,2,2,3,2,3,2,0,0,3,3,3,0,0,3,2,0,0,0,1,1,0,2,0,2,2, +0,2,0,2,0,2,2,0,0,2,0,2,2,2,0,2,2,2,2,0,0,2,0,0,0,2,0,1,0,0,0,0, +0,3,0,3,3,2,2,0,3,0,0,0,2,2,0,2,2,2,1,2,0,0,1,2,2,0,0,3,0,0,0,2, +0,1,2,0,0,0,1,2,0,0,0,0,0,0,0,2,2,0,1,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,3,3,2,2,0,0,0,2,0,2,3,3,0,2,0,0,0,0,0,0,2,2,2,0,2,2,0,2,0,2, +0,2,2,0,0,2,2,2,2,1,0,0,2,2,0,2,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,0,3,2,3,0,0,0,3,0,0,2,2,0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,2,2,0,0,2,2,2,0,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,3,2,0,2,2,2,2,2,0,0,0,2,0,0,0,0,2,0,1,0,0,2,0,1,0,0,0, +0,2,2,2,0,2,2,0,1,2,0,2,2,2,0,2,2,2,2,1,2,2,0,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,2,0,2,2,0,0,0,0,1,2,1,0,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,3,0,0,2,0,0,0,2,2,0,2,0,0,0,1,0,0,2,0,2,0,2,2,0,0,0,0, +0,0,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0, +0,2,2,3,2,2,0,0,0,0,0,0,1,3,0,2,0,2,2,0,0,0,1,0,2,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,0,3,2,0,2,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,1,0,0,2,1,2,0,2,2,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0, +0,3,0,2,2,2,0,0,2,0,0,0,2,0,0,0,2,3,0,2,0,0,0,0,0,0,2,2,0,0,0,2, +0,1,2,0,0,0,1,2,2,1,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,2,0,2,2,0,2,0,0,2,0,0,0,0,1,2,1,0,2,1,0,0,0,0,0,0,0,0,0,0, +0,0,2,0,0,0,3,1,2,2,0,2,0,0,0,0,2,0,0,0,2,0,0,3,0,0,0,0,2,2,2,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,1,0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,2,2,2,2,2,0,1,2,0,0,0,2,2,0,1,0,2,0,0,2,2,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,3,0,0,2,0,0,0,0,0,0,0,0,2,0,2,0,0,0,0,2, +0,1,2,0,0,0,0,2,2,1,0,1,0,1,0,2,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,1,2,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,0,0,0,0,1,0,0,0,0,0,0,2, +0,2,2,0,0,0,0,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0, +0,2,2,2,2,0,0,0,3,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,1, +0,0,2,0,0,0,0,1,2,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,2,2,2,0,0,0,2,0,0,0,0,0,0,0,0,2, +0,0,1,0,0,0,0,2,1,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,3,0,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,0,0,2,2,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,2,0,2,2,1,0,0,0,0,0,0,2,0,0,2,0,2,2,2,0,0,0,0,0,0,2,0,0,0,0,2, +0,0,2,0,0,2,0,2,2,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0, +0,0,3,0,0,0,2,2,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0, +0,2,2,2,2,2,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1, +0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,2,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,2,0,0,0,2,0,0,0,0,0,1,0,0,0,0,2,2,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,2,0,0,0, +0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,2,0,2,0,0,0, +0,0,0,0,0,0,0,0,2,1,0,0,0,0,0,0,2,0,0,0,1,2,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin7GreekModel = { + 'char_to_order_map': Latin7_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "ISO-8859-7", + 'language': 'Greek', +} + +Win1253GreekModel = { + 'char_to_order_map': win1253_char_to_order_map, + 'precedence_matrix': GreekLangModel, + 'typical_positive_ratio': 0.982851, + 'keep_english_letter': False, + 'charset_name': "windows-1253", + 'language': 'Greek', +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py new file mode 100644 index 0000000..58f4c87 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langhebrewmodel.py @@ -0,0 +1,200 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Simon Montagu +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Shoshannah Forbes - original C code (?) +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Windows-1255 language model +# Character Mapping Table: +WIN1255_CHAR_TO_ORDER_MAP = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 69, 91, 79, 80, 92, 89, 97, 90, 68,111,112, 82, 73, 95, 85, # 40 + 78,121, 86, 71, 67,102,107, 84,114,103,115,253,253,253,253,253, # 50 +253, 50, 74, 60, 61, 42, 76, 70, 64, 53,105, 93, 56, 65, 54, 49, # 60 + 66,110, 51, 43, 44, 63, 81, 77, 98, 75,108,253,253,253,253,253, # 70 +124,202,203,204,205, 40, 58,206,207,208,209,210,211,212,213,214, +215, 83, 52, 47, 46, 72, 32, 94,216,113,217,109,218,219,220,221, + 34,116,222,118,100,223,224,117,119,104,125,225,226, 87, 99,227, +106,122,123,228, 55,229,230,101,231,232,120,233, 48, 39, 57,234, + 30, 59, 41, 88, 33, 37, 36, 31, 29, 35,235, 62, 28,236,126,237, +238, 38, 45,239,240,241,242,243,127,244,245,246,247,248,249,250, + 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, + 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5,251,252,128, 96,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 98.4004% +# first 1024 sequences: 1.5981% +# rest sequences: 0.087% +# negative sequences: 0.0015% +HEBREW_LANG_MODEL = ( +0,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,3,2,1,2,0,1,0,0, +3,0,3,1,0,0,1,3,2,0,1,1,2,0,2,2,2,1,1,1,1,2,1,1,1,2,0,0,2,2,0,1, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2, +1,2,1,2,1,2,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2, +1,2,1,3,1,1,0,0,2,0,0,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,1,2,2,1,3, +1,2,1,1,2,2,0,0,2,2,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,1,0,1,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,2,2,2,3,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,2,3,2,2,3,2,2,2,1,2,2,2,2, +1,2,1,1,2,2,0,1,2,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,0,2,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,0,2,2,2, +0,2,1,2,2,2,0,0,2,1,0,0,0,0,1,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,2,1,2,3,2,2,2, +1,2,1,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,3,3,1,0,2,0,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,2,3,2,2,3,2,1,2,1,1,1, +0,1,1,1,1,1,3,0,1,0,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,0,0,1,0,0,0,0, +0,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,2,1,2,3,3,2,3,3,3,3,2,3,2,1,2,0,2,1,2, +0,2,0,2,2,2,0,0,1,2,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,1,2,2,3,3,2,3,2,3,2,2,3,1,2,2,0,2,2,2, +0,2,1,2,2,2,0,0,1,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,2,2,3,3,3,3,1,3,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,2,3,2,2,2,1,2,2,0,2,2,2,2, +0,2,0,2,2,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,1,3,2,3,3,2,3,3,2,2,1,2,2,2,2,2,2, +0,2,1,2,1,2,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,2,3,3,2,3,3,3,3,2,3,2,3,3,3,3,3,2,2,2,2,2,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,2,1,2,3,3,3,3,3,3,3,2,3,2,3,2,1,2,3,0,2,1,2,2, +0,2,1,1,2,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,2,0, +3,3,3,3,3,3,3,3,3,2,3,3,3,3,2,1,3,1,2,2,2,1,2,3,3,1,2,1,2,2,2,2, +0,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,0,2,3,3,3,1,3,3,3,1,2,2,2,2,1,1,2,2,2,2,2,2, +0,2,0,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,2,3,3,3,2,1,2,3,2,3,2,2,2,2,1,2,1,1,1,2,2, +0,2,1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +1,0,1,0,0,0,0,0,2,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,2,3,3,2,3,1,2,2,2,2,3,2,3,1,1,2,2,1,2,2,1,1,0,2,2,2,2, +0,1,0,1,2,2,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0, +3,0,0,1,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,2,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,0,1,0,1,1,0,1,1,0,0,0,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +3,2,2,1,2,2,2,2,2,2,2,1,2,2,1,2,2,1,1,1,1,1,1,1,1,2,1,1,0,3,3,3, +0,3,0,2,2,2,2,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +2,2,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,1,2,2,2,1,1,1,2,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,1,0,2,1,0, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,3,1,1,2,2,2,2,2,1,2,2,2,1,1,2,2,2,2,2,2,2,1,2,2,1,0,1,1,1,1,0, +0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,2,1,1,1,1,2,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,2,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,1,2,1,2,1,1,1,1,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,2,1,2,1,2,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,3,1,2,2,2,1,2,2,2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,2,1,1,0,1,0,1, +0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2, +0,2,0,1,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,0,1,1,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,1,1,1,0,1,0,0,0,1,1,0,1,1,0,0,0,0,0,1,1,0,0, +0,1,1,1,2,1,2,2,2,0,2,0,2,0,1,1,2,1,1,1,1,2,1,0,1,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,1,0,0,0,0,0,1,0,1,2,2,0,1,0,0,1,1,2,2,1,2,0,2,0,0,0,1,2,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,2,1,2,0,2,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,1,2,2,0,0,1,0,0,0,1,0,0,1, +1,1,2,1,0,1,1,1,0,1,0,1,1,1,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,2,2,1, +0,2,0,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,1,0,0,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,1,1,1,1,1,1,1,2,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,1,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,1,1,2,1,1,2,0,1,0,0,0,1,1,0,1, +1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,0,0,2,1,1,2,0,2,0,0,0,1,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,2,2,1,2,1,1,0,1,0,0,0,1,1,0,1, +2,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,0,1,1,0,1,0,0,1,0,0,0,0,1,0,1, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,2,0,0,0,0,2,1,1,1,0,2,1,1,0,0,0,2,1,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,0,2,1,1,0,1,0,0,0,1,1,0,1, +2,2,1,1,1,0,1,1,0,1,1,0,1,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,2,1,1,0,1,0,0,1,1,0,1,2,1,0,2,0,0,0,1,1,0,1, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0, +0,1,0,0,2,0,2,1,1,0,1,0,1,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,1,0,1,1,2,0,1,0,0,1,1,1,0,1,0,0,1,0,0,0,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,2,1,1,1,1,1,0,1,0,0,0,0,1,0,1, +0,1,1,1,2,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,1,2,1,0,0,0,0,0,1,1,1,1,1,0,1,0,0,0,1,1,0,0, +) + +Win1255HebrewModel = { + 'char_to_order_map': WIN1255_CHAR_TO_ORDER_MAP, + 'precedence_matrix': HEBREW_LANG_MODEL, + 'typical_positive_ratio': 0.984004, + 'keep_english_letter': False, + 'charset_name': "windows-1255", + 'language': 'Hebrew', +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py new file mode 100644 index 0000000..bb7c095 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langhungarianmodel.py @@ -0,0 +1,225 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin2_HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174, +175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 75,198,199,200,201,202,203,204,205, + 79,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 81,222, 78,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 69, 63,239,240,241, + 82, 14, 74,242, 70, 80,243, 72,244, 15, 83, 77, 84, 30, 76, 85, +245,246,247, 25, 73, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +win1250HungarianCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, + 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52,253,253,253,253,253, +253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, + 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11,253,253,253,253,253, +161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176, +177,178,179,180, 78,181, 69,182,183,184,185,186,187,188,189,190, +191,192,193,194,195,196,197, 76,198,199,200,201,202,203,204,205, + 81,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220, +221, 51, 83,222, 80,223,224,225,226, 44,227,228,229, 61,230,231, +232,233,234, 58,235, 66, 59,236,237,238, 60, 70, 63,239,240,241, + 84, 14, 75,242, 71, 82,243, 73,244, 15, 85, 79, 86, 30, 77, 87, +245,246,247, 25, 74, 42, 24,248,249,250, 31, 56, 29,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 94.7368% +# first 1024 sequences:5.2623% +# rest sequences: 0.8894% +# negative sequences: 0.0009% +HungarianLangModel = ( +0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,1,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, +3,3,3,3,3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,2,2,3,3,1,1,2,2,2,2,2,1,2, +3,2,2,3,3,3,3,3,2,3,3,3,3,3,3,1,2,3,3,3,3,2,3,3,1,1,3,3,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0, +3,2,1,3,3,3,3,3,2,3,3,3,3,3,1,1,2,3,3,3,3,3,3,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,2,3,3,3,1,3,3,3,3,3,1,3,3,2,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,3,3,2,3,3,2,2,3,2,3,2,0,3,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,3,3,2,3,3,3,1,2,3,2,2,3,1,2,3,3,2,2,0,3,3,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,3,2,3,3,3,3,2,3,3,3,3,0,2,3,2, +0,0,0,1,1,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,1,1,1,3,3,2,1,3,2,2,3,2,1,3,2,2,1,0,3,3,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,2,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,3,2,2,3,1,1,3,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,2,2,3,3,3,3,3,2,1,3,3,3,3,3,2,2,1,3,3,3,0,1,1,2, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,2,3,3,3,2,3,3,2,3,3,3,2,0,3,2,3, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,1,0, +3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,1,3,2,2,2,3,1,1,3,3,1,1,0,3,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,2,3,3,3,2,3,2,3,3,3,2,3,3,3,3,3,1,2,3,2,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,1,3,3,2,2,1,3,3,3,1,1,3,1,2,3,2,3,2,2,2,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,2,1,3,3,3,2,2,3,2,1,0,3,2,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,3,3,3,3,3,1,2,3,3,3,3,1,1,0,3,3,3,3,0,2,3,0,0,2,1,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,2,2,3,3,2,2,2,2,3,3,0,1,2,3,2,3,2,2,3,2,1,2,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +3,3,3,3,3,3,1,2,3,3,3,2,1,2,3,3,2,2,2,3,2,3,3,1,3,3,1,1,0,2,3,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,2,2,2,2,3,3,3,1,1,1,3,3,1,1,3,1,1,3,2,1,2,3,1,1,0,2,2,2, +0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,1,2,1,1,3,3,1,1,1,1,3,3,1,1,2,2,1,2,1,1,2,2,1,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,1,1,2,1,1,3,3,1,0,1,1,3,3,2,0,1,1,2,3,1,0,2,2,1,0,0,1,3,2, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,2,1,3,3,3,3,3,1,2,3,2,3,3,2,1,1,3,2,3,2,1,2,2,0,1,2,1,0,0,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,2,2,2,3,1,2,2,1,1,3,3,0,3,2,1,2,3,2,1,3,3,1,1,0,2,1,3, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,3,3,2,1,1,3,3,1,1,1,2,2,3,2,3,2,2,2,1,0,2,2,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +1,0,0,3,3,3,3,3,0,0,3,3,2,3,0,0,0,2,3,3,1,0,1,2,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,2,3,3,3,3,3,1,2,3,3,2,2,1,1,0,3,3,2,2,1,2,2,1,0,2,2,0,1,1,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,2,1,3,1,2,3,3,2,2,1,1,2,2,1,1,1,1,3,2,1,1,1,1,2,1,0,1,2,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +2,3,3,1,1,1,1,1,3,3,3,0,1,1,3,3,1,1,1,1,1,2,2,0,3,1,1,2,0,2,1,1, +0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0, +3,1,0,1,2,1,2,2,0,1,2,3,1,2,0,0,0,2,1,1,1,1,1,2,0,0,1,1,0,0,0,0, +1,2,1,2,2,2,1,2,1,2,0,2,0,2,2,1,1,2,1,1,2,1,1,1,0,1,0,0,0,1,1,0, +1,1,1,2,3,2,3,3,0,1,2,2,3,1,0,1,0,2,1,2,2,0,1,1,0,0,1,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,3,3,2,2,1,0,0,3,2,3,2,0,0,0,1,1,3,0,0,1,1,0,0,2,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,2,2,3,3,1,0,1,3,2,3,1,1,1,0,1,1,1,1,1,3,1,0,0,2,2,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,1,1,2,2,2,1,0,1,2,3,3,2,0,0,0,2,1,1,1,2,1,1,1,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,2,1,1,1,1,1,1,0,1,1,1,0,0,1,1, +3,2,2,1,0,0,1,1,2,2,0,3,0,1,2,1,1,0,0,1,1,1,0,1,1,1,1,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,1,1,1,1,1,2,1,1,1,2,3,1,1,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,3,3,1,0,0,1,2,2,1,0,0,0,0,2,0,0,1,1,1,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,1,0,1,1,0,1,1,1,0,1,2,1,1,0,1,1,1,1,1,1,1,0,1, +2,3,3,0,1,0,0,0,2,2,0,0,0,0,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,1,0, +2,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +3,2,2,0,1,0,1,0,2,3,2,0,0,1,2,2,1,0,0,1,1,1,0,0,2,1,0,1,2,2,1,1, +2,1,1,1,1,1,1,2,1,1,1,1,1,1,0,2,1,0,1,1,0,1,1,1,0,1,1,2,1,1,0,1, +2,2,2,0,0,1,0,0,2,2,1,1,0,0,2,1,1,0,0,0,1,2,0,0,2,1,0,0,2,1,1,1, +2,1,1,1,1,2,1,2,1,1,1,2,2,1,1,2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,0,1, +1,2,3,0,0,0,1,0,3,2,1,0,0,1,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,2,1, +1,1,0,0,0,1,0,1,1,1,1,1,2,0,0,1,0,0,0,2,0,0,1,1,1,1,1,1,1,1,0,1, +3,0,0,2,1,2,2,1,0,0,2,1,2,2,0,0,0,2,1,1,1,0,1,1,0,0,1,1,2,0,0,0, +1,2,1,2,2,1,1,2,1,2,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,0,0,1, +1,3,2,0,0,0,1,0,2,2,2,0,0,0,2,2,1,0,0,0,0,3,1,1,1,1,0,0,2,1,1,1, +2,1,0,1,1,1,0,1,1,1,1,1,1,1,0,2,1,0,0,1,0,1,1,0,1,1,1,1,1,1,0,1, +2,3,2,0,0,0,1,0,2,2,0,0,0,0,2,1,1,0,0,0,0,2,1,0,1,1,0,0,2,1,1,0, +2,1,1,1,1,2,1,2,1,2,0,1,1,1,0,2,1,1,1,2,1,1,1,1,0,1,1,1,1,1,0,1, +3,1,1,2,2,2,3,2,1,1,2,2,1,1,0,1,0,2,2,1,1,1,1,1,0,0,1,1,0,1,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,0,0,0,0,2,2,0,0,0,0,2,2,1,0,0,0,1,1,0,0,1,2,0,0,2,1,1,1, +2,2,1,1,1,2,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,1,1,0,1,2,1,1,1,0,1, +1,0,0,1,2,3,2,1,0,0,2,0,1,1,0,0,0,1,1,1,1,0,1,1,0,0,1,0,0,0,0,0, +1,2,1,2,1,2,1,1,1,2,0,2,1,1,1,0,1,2,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,3,2,0,0,0,0,0,1,1,2,1,0,0,1,1,1,0,0,0,0,2,0,0,1,1,0,0,2,1,1,1, +2,1,1,1,1,1,1,2,1,0,1,1,1,1,0,2,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,1,1,1,0,2,2,2,0,0,0,3,2,1,0,0,0,1,1,0,0,1,1,0,1,1,1,0,0, +1,1,0,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,1,1,0,0,1,1,1,0,1,0,1, +2,1,0,2,1,1,2,2,1,1,2,1,1,1,0,0,0,1,1,0,1,1,1,1,0,0,1,1,1,0,0,0, +1,2,2,2,2,2,1,1,1,2,0,2,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0, +1,2,3,0,0,0,1,0,2,2,0,0,0,0,2,2,0,0,0,0,0,1,0,0,1,0,0,0,2,0,1,0, +2,1,1,1,1,1,0,2,0,0,0,1,2,1,1,1,1,0,1,2,0,1,0,1,0,1,1,1,0,1,0,1, +2,2,2,0,0,0,1,0,2,1,2,0,0,0,1,1,2,0,0,0,0,1,0,0,1,1,0,0,2,1,0,1, +2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,1,0,2,2,2,0,0,0,1,1,0,0,0,0,0,1,1,0,2,0,0,1,1,1,0,1, +1,0,1,1,1,1,1,1,0,1,1,1,1,0,0,1,0,0,1,1,0,1,0,1,1,1,1,1,0,0,0,1, +1,0,0,1,0,1,2,1,0,0,1,1,1,2,0,0,0,1,1,0,1,0,1,1,0,0,1,0,0,0,0,0, +0,2,1,2,1,1,1,1,1,2,0,2,0,1,1,0,1,2,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,1,1,0,1,2,0,0,1,1,1,0,0,0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,2,1,0,1, +2,2,1,1,1,1,1,2,1,1,0,1,1,1,1,2,1,1,1,2,1,1,0,1,0,1,1,1,1,1,0,1, +1,2,2,0,0,0,0,0,1,1,0,0,0,0,2,1,0,0,0,0,0,2,0,0,2,2,0,0,2,0,0,1, +2,1,1,1,1,1,1,1,0,1,1,0,1,1,0,1,0,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1, +1,1,2,0,0,3,1,0,2,1,1,1,0,0,1,1,1,0,0,0,1,1,0,0,0,1,0,0,1,0,1,0, +1,2,1,0,1,1,1,2,1,1,0,1,1,1,1,1,0,0,0,1,1,1,1,1,0,1,0,0,0,1,0,0, +2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,2,0,0,0, +2,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,2,1,1,0,0,1,1,1,1,1,0,1, +2,1,1,1,2,1,1,1,0,1,1,2,1,0,0,0,0,1,1,1,1,0,1,0,0,0,0,1,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,1,1,1,1,0,0,1,1,2,1,0,0,0,1,1,0,0,0,1,1,0,0,1,0,1,0,0,0, +1,2,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,1,1,1,0,0,0,0,0,0,1,0,0, +2,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,1,2,0,0,1,0,0,1,0,1,0,0,0, +0,1,1,1,1,1,1,1,1,2,0,1,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,1,0,0,2,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,0,0,1,1,0,1,0,1,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +0,0,0,1,0,0,0,0,0,0,1,1,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,0,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0,0,0, +2,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,0,1,1,1,0,0,1,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +) + +Latin2HungarianModel = { + 'char_to_order_map': Latin2_HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-2", + 'language': 'Hungarian', +} + +Win1250HungarianModel = { + 'char_to_order_map': win1250HungarianCharToOrderMap, + 'precedence_matrix': HungarianLangModel, + 'typical_positive_ratio': 0.947368, + 'keep_english_letter': True, + 'charset_name': "windows-1250", + 'language': 'Hungarian', +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py new file mode 100644 index 0000000..15f94c2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langthaimodel.py @@ -0,0 +1,199 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# The following result for thai was collected from a limited sample (1M). + +# Character Mapping Table: +TIS620CharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,254,255,255,254,255,255, # 00 +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, # 10 +253,253,253,253,253,253,253,253,253,253,253,253,253,253,253,253, # 20 +252,252,252,252,252,252,252,252,252,252,253,253,253,253,253,253, # 30 +253,182,106,107,100,183,184,185,101, 94,186,187,108,109,110,111, # 40 +188,189,190, 89, 95,112,113,191,192,193,194,253,253,253,253,253, # 50 +253, 64, 72, 73,114, 74,115,116,102, 81,201,117, 90,103, 78, 82, # 60 + 96,202, 91, 79, 84,104,105, 97, 98, 92,203,253,253,253,253,253, # 70 +209,210,211,212,213, 88,214,215,216,217,218,219,220,118,221,222, +223,224, 99, 85, 83,225,226,227,228,229,230,231,232,233,234,235, +236, 5, 30,237, 24,238, 75, 8, 26, 52, 34, 51,119, 47, 58, 57, + 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, + 45, 9, 16, 2, 61, 15,239, 12, 42, 46, 18, 21, 76, 4, 66, 63, + 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86,240,241,242,243,244, + 11, 28, 41, 29, 33,245, 50, 37, 6, 7, 67, 77, 38, 93,246,247, + 68, 56, 59, 65, 69, 60, 70, 80, 71, 87,248,249,250,251,252,253, +) + +# Model Table: +# total sequences: 100% +# first 512 sequences: 92.6386% +# first 1024 sequences:7.3177% +# rest sequences: 1.0230% +# negative sequences: 0.0436% +ThaiLangModel = ( +0,1,3,3,3,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,0,0,3,3,3,0,3,3,3,3, +0,3,3,0,0,0,1,3,0,3,3,2,3,3,0,1,2,3,3,3,3,0,2,0,2,0,0,3,2,1,2,2, +3,0,3,3,2,3,0,0,3,3,0,3,3,0,3,3,3,3,3,3,3,3,3,0,3,2,3,0,2,2,2,3, +0,2,3,0,0,0,0,1,0,1,2,3,1,1,3,2,2,0,1,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,3,2,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,2,2,2,3,3,2,3,2,3,3,2,2,2, +3,1,2,3,0,3,3,2,2,1,2,3,3,1,2,0,1,3,0,1,0,0,1,0,0,0,0,0,0,0,1,1, +3,3,2,2,3,3,3,3,1,2,3,3,3,3,3,2,2,2,2,3,3,2,2,3,3,2,2,3,2,3,2,2, +3,3,1,2,3,1,2,2,3,3,1,0,2,1,0,0,3,1,2,1,0,0,1,0,0,0,0,0,0,1,0,1, +3,3,3,3,3,3,2,2,3,3,3,3,2,3,2,2,3,3,2,2,3,2,2,2,2,1,1,3,1,2,1,1, +3,2,1,0,2,1,0,1,0,1,1,0,1,1,0,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,2,2,3,2,3,3,2,3,1,1,2,3,2,2,2,3,2,2,2,2,2,1,2,1, +2,2,1,1,3,3,2,1,0,1,2,2,0,1,3,0,0,0,1,1,0,0,0,0,0,2,3,0,0,2,1,1, +3,3,2,3,3,2,0,0,3,3,0,3,3,0,2,2,3,1,2,2,1,1,1,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,0,0,1,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,0,0,3,3,0,2,3,0,2,1,2,2,2,2,1,2,0,0,2,2,2,0,2,2,1,1, +0,2,1,0,2,0,0,2,0,1,1,0,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,3,2,3,2,0,2,2,1,3,2,1,3,2,1,2,3,2,2,3,0,2,3,2,2,1,2,2,2,2, +1,2,2,0,0,0,0,2,0,1,2,0,1,1,1,0,1,0,3,1,1,0,0,0,0,0,0,0,0,0,1,0, +3,3,2,3,3,2,3,2,2,2,3,2,2,3,2,2,1,2,3,2,2,3,1,3,2,2,2,3,2,2,2,3, +3,2,1,3,0,1,1,1,0,2,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,2,0,0, +1,0,0,3,0,3,3,3,3,3,0,0,3,0,2,2,3,3,3,3,3,0,0,0,1,1,3,0,0,0,0,2, +0,0,1,0,0,0,0,0,0,0,2,3,0,0,0,3,0,2,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,3,3,3,3,0,0,2,3,0,0,3,0,3,3,2,3,3,3,3,3,0,0,3,3,3,0,0,0,3,3, +0,0,3,0,0,0,0,2,0,0,2,1,1,3,0,0,1,0,0,2,3,0,1,0,0,0,0,0,0,0,1,0, +3,3,3,3,2,3,3,3,3,3,3,3,1,2,1,3,3,2,2,1,2,2,2,3,1,1,2,0,2,1,2,1, +2,2,1,0,0,0,1,1,0,1,0,1,1,0,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0, +3,0,2,1,2,3,3,3,0,2,0,2,2,0,2,1,3,2,2,1,2,1,0,0,2,2,1,0,2,1,2,2, +0,1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,3,3,1,1,3,0,2,3,1,1,3,2,1,1,2,0,2,2,3,2,1,1,1,1,1,2, +3,0,0,1,3,1,2,1,2,0,3,0,0,0,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0, +3,3,1,1,3,2,3,3,3,1,3,2,1,3,2,1,3,2,2,2,2,1,3,3,1,2,1,3,1,2,3,0, +2,1,1,3,2,2,2,1,2,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2, +3,3,2,3,2,3,3,2,3,2,3,2,3,3,2,1,0,3,2,2,2,1,2,2,2,1,2,2,1,2,1,1, +2,2,2,3,0,1,3,1,1,1,1,0,1,1,0,2,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,3,2,2,1,1,3,2,3,2,3,2,0,3,2,2,1,2,0,2,2,2,1,2,2,2,2,1, +3,2,1,2,2,1,0,2,0,1,0,0,1,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,1, +3,3,3,3,3,2,3,1,2,3,3,2,2,3,0,1,1,2,0,3,3,2,2,3,0,1,1,3,0,0,0,0, +3,1,0,3,3,0,2,0,2,1,0,0,3,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,3,2,3,3,0,1,3,1,1,2,1,2,1,1,3,1,1,0,2,3,1,1,1,1,1,1,1,1, +3,1,1,2,2,2,2,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,2,2,1,1,2,1,3,3,2,3,2,2,3,2,2,3,1,2,2,1,2,0,3,2,1,2,2,2,2,2,1, +3,2,1,2,2,2,1,1,1,1,0,0,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,1,3,3,0,2,1,0,3,2,0,0,3,1,0,1,1,0,1,0,0,0,0,0,1, +1,0,0,1,0,3,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,2,2,3,0,0,1,3,0,3,2,0,3,2,2,3,3,3,3,3,1,0,2,2,2,0,2,2,1,2, +0,2,3,0,0,0,0,1,0,1,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +3,0,2,3,1,3,3,2,3,3,0,3,3,0,3,2,2,3,2,3,3,3,0,0,2,2,3,0,1,1,1,3, +0,0,3,0,0,0,2,2,0,1,3,0,1,2,2,2,3,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1, +3,2,3,3,2,0,3,3,2,2,3,1,3,2,1,3,2,0,1,2,2,0,2,3,2,1,0,3,0,0,0,0, +3,0,0,2,3,1,3,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,1,3,2,2,2,1,2,0,1,3,1,1,3,1,3,0,0,2,1,1,1,1,2,1,1,1,0,2,1,0,1, +1,2,0,0,0,3,1,1,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0,0,0,3,1,0,0,0,1,0, +3,3,3,3,2,2,2,2,2,1,3,1,1,1,2,0,1,1,2,1,2,1,3,2,0,0,3,1,1,1,1,1, +3,1,0,2,3,0,0,0,3,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,2,3,0,3,3,0,2,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,2,3,1,3,0,0,1,2,0,0,2,0,3,3,2,3,3,3,2,3,0,0,2,2,2,0,0,0,2,2, +0,0,1,0,0,0,0,3,0,0,0,0,2,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,3,0,2,0,0,0,0,0,0,0,0,0,0,1,2,3,1,3,3,0,0,1,0,3,0,0,0,0,0, +0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,2,3,1,2,3,1,0,3,0,2,2,1,0,2,1,1,2,0,1,0,0,1,1,1,1,0,1,0,0, +1,0,0,0,0,1,1,0,3,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,2,1,0,1,1,1,3,1,2,2,2,2,2,2,1,1,1,1,0,3,1,0,1,3,1,1,1,1, +1,1,0,2,0,1,3,1,1,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,1, +3,0,2,2,1,3,3,2,3,3,0,1,1,0,2,2,1,2,1,3,3,1,0,0,3,2,0,0,0,0,2,1, +0,1,0,0,0,0,1,2,0,1,1,3,1,1,2,2,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0, +0,0,3,0,0,1,0,0,0,3,0,0,3,0,3,1,0,1,1,1,3,2,0,0,0,3,0,0,0,0,2,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +3,3,1,3,2,1,3,3,1,2,2,0,1,2,1,0,1,2,0,0,0,0,0,3,0,0,0,3,0,0,0,0, +3,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,2,0,3,3,3,2,2,0,1,1,0,1,3,0,0,0,2,2,0,0,0,0,3,1,0,1,0,0,0, +0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,2,3,1,2,0,0,2,1,0,3,1,0,1,2,0,1,1,1,1,3,0,0,3,1,1,0,2,2,1,1, +0,2,0,0,0,0,0,1,0,1,0,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,3,1,2,0,0,2,2,0,1,2,0,1,0,1,3,1,2,1,0,0,0,2,0,3,0,0,0,1,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,1,1,2,2,0,0,0,2,0,2,1,0,1,1,0,1,1,1,2,1,0,0,1,1,1,0,2,1,1,1, +0,1,1,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,1, +0,0,0,2,0,1,3,1,1,1,1,0,0,0,0,3,2,0,1,0,0,0,1,2,0,0,0,1,0,0,0,0, +0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,3,3,3,3,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,0,2,3,2,2,0,0,0,1,0,0,0,0,2,3,2,1,2,2,3,0,0,0,2,3,1,0,0,0,1,1, +0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0, +3,3,2,2,0,1,0,0,0,0,2,0,2,0,1,0,0,0,1,1,0,0,0,2,1,0,1,0,1,1,0,0, +0,1,0,2,0,0,1,0,3,0,1,0,0,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,1,0,0,1,0,0,0,0,0,1,1,2,0,0,0,0,1,0,0,1,3,1,0,0,0,0,1,1,0,0, +0,1,0,0,0,0,3,0,0,0,0,0,0,3,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0, +3,3,1,1,1,1,2,3,0,0,2,1,1,1,1,1,0,2,1,1,0,0,0,2,1,0,1,2,1,1,0,1, +2,1,0,3,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,3,1,0,0,0,0,0,0,0,3,0,0,0,3,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1, +0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,0,0,0,0,1,2,1,0,1,1,0,2,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,2,0,0,0,1,3,0,1,0,0,0,2,0,0,0,0,0,0,0,1,2,0,0,0,0,0, +3,3,0,0,1,1,2,0,0,1,2,1,0,1,1,1,0,1,1,0,0,2,1,1,0,1,0,0,1,1,1,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,1,0,0,0,0,1,0,0,0,0,3,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,3,0,0,1,1,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +1,1,0,1,2,0,1,2,0,0,1,1,0,2,0,1,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0, +1,0,0,1,0,1,1,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,1,0,0,0,0,0,0,0,1,1,0,1,1,0,2,1,3,0,0,0,0,1,1,0,0,0,0,0,0,0,3, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,1,0,1,0,0,2,0,0,2,0,0,1,1,2,0,0,1,1,0,0,0,1,0,0,0,1,1,0,0,0, +1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0, +1,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,1,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,2,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,3,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,1,0,0,0,0, +1,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,1,0,0,2,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +TIS620ThaiModel = { + 'char_to_order_map': TIS620CharToOrderMap, + 'precedence_matrix': ThaiLangModel, + 'typical_positive_ratio': 0.926386, + 'keep_english_letter': False, + 'charset_name': "TIS-620", + 'language': 'Thai', +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py new file mode 100644 index 0000000..a427a45 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/langturkishmodel.py @@ -0,0 +1,193 @@ +# -*- coding: utf-8 -*- +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Communicator client code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Özgür Baskın - Turkish Language Model +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +# 255: Control characters that usually does not exist in any text +# 254: Carriage/Return +# 253: symbol (punctuation) that does not belong to word +# 252: 0 - 9 + +# Character Mapping Table: +Latin5_TurkishCharToOrderMap = ( +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +255, 23, 37, 47, 39, 29, 52, 36, 45, 53, 60, 16, 49, 20, 46, 42, + 48, 69, 44, 35, 31, 51, 38, 62, 65, 43, 56,255,255,255,255,255, +255, 1, 21, 28, 12, 2, 18, 27, 25, 3, 24, 10, 5, 13, 4, 15, + 26, 64, 7, 8, 9, 14, 32, 57, 58, 11, 22,255,255,255,255,255, +180,179,178,177,176,175,174,173,172,171,170,169,168,167,166,165, +164,163,162,161,160,159,101,158,157,156,155,154,153,152,151,106, +150,149,148,147,146,145,144,100,143,142,141,140,139,138,137,136, + 94, 80, 93,135,105,134,133, 63,132,131,130,129,128,127,126,125, +124,104, 73, 99, 79, 85,123, 54,122, 98, 92,121,120, 91,103,119, + 68,118,117, 97,116,115, 50, 90,114,113,112,111, 55, 41, 40, 86, + 89, 70, 59, 78, 71, 82, 88, 33, 77, 66, 84, 83,110, 75, 61, 96, + 30, 67,109, 74, 87,102, 34, 95, 81,108, 76, 72, 17, 6, 19,107, +) + +TurkishLangModel = ( +3,2,3,3,3,1,3,3,3,3,3,3,3,3,2,1,1,3,3,1,3,3,0,3,3,3,3,3,0,3,1,3, +3,2,1,0,0,1,1,0,0,0,1,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,3,1,0,3,3,1,3,3,0,3,3,3,3,3,0,3,0,3, +3,1,1,0,1,0,1,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,2,2,0,0,0,1,0,1, +3,3,2,3,3,0,3,3,3,3,3,3,3,2,3,1,1,3,3,0,3,3,1,2,3,3,3,3,0,3,0,3, +3,1,1,0,0,0,1,0,0,0,0,1,1,0,1,2,1,0,0,0,1,0,0,0,0,2,0,0,0,0,0,1, +3,3,3,3,3,3,2,3,3,3,3,3,3,3,3,1,3,3,2,0,3,2,1,2,2,1,3,3,0,0,0,2, +2,2,0,1,0,0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,1,0,0,1, +3,3,3,2,3,3,1,2,3,3,3,3,3,3,3,1,3,2,1,0,3,2,0,1,2,3,3,2,1,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,2,0,2,0,0,0, +1,0,1,3,3,1,3,3,3,3,3,3,3,1,2,0,0,2,3,0,2,3,0,0,2,2,2,3,0,3,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,0,3,3,3,0,3,2,0,2,3,2,3,3,1,0,0,2, +3,2,0,0,1,0,0,0,0,0,0,2,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,0,2,0,0,1, +3,3,3,2,3,3,2,3,3,3,3,2,3,3,3,0,3,3,0,0,2,1,0,0,2,3,2,2,0,0,0,2, +2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,0,2,0,0,1, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,0,1,3,2,1,1,3,2,3,2,1,0,0,2, +2,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, +3,3,3,2,3,3,3,3,3,3,3,2,3,3,3,0,3,2,2,0,2,3,0,0,2,2,2,2,0,0,0,2, +3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,3,3,3,3,2,2,2,2,3,2,3,3,0,3,3,1,1,2,2,0,0,2,2,3,2,0,0,1,3, +0,3,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,1, +3,3,3,2,3,3,3,2,1,2,2,3,2,3,3,0,3,2,0,0,1,1,0,1,1,2,1,2,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0, +3,3,3,2,3,3,2,3,2,2,2,3,3,3,3,1,3,1,1,0,3,2,1,1,3,3,2,3,1,0,0,1, +1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,0,0,1, +3,2,2,3,3,0,3,3,3,3,3,3,3,2,2,1,0,3,3,1,3,3,0,1,3,3,2,3,0,3,0,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +2,2,2,3,3,0,3,3,3,3,3,3,3,3,3,0,0,3,2,0,3,3,0,3,2,3,3,3,0,3,1,3, +2,0,0,0,0,0,0,0,0,0,0,1,0,1,2,0,1,0,0,0,0,0,0,0,2,2,0,0,1,0,0,1, +3,3,3,1,2,3,3,1,0,0,1,0,0,3,3,2,3,0,0,2,0,0,2,0,2,0,0,0,2,0,2,0, +0,3,1,0,1,0,0,0,2,2,1,0,1,1,2,1,2,2,2,0,2,1,1,0,0,0,2,0,0,0,0,0, +1,2,1,3,3,0,3,3,3,3,3,2,3,0,0,0,0,2,3,0,2,3,1,0,2,3,1,3,0,3,0,2, +3,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,3,2,2,3,2,2,0,1,2,3,0,1,2,1,0,1,0,0,0,1,0,2,2,0,0,0,1, +1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0, +3,3,3,1,3,3,1,1,3,3,1,1,3,3,1,0,2,1,2,0,2,1,0,0,1,1,2,1,0,0,0,2, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,0,2,1,3,0,0,2,0,0,3,3,0,3,0,0,1,0,1,2,0,0,1,1,2,2,0,1,0, +0,1,2,1,1,0,1,0,1,1,1,1,1,0,1,1,1,2,2,1,2,0,1,0,0,0,0,0,0,1,0,0, +3,3,3,2,3,2,3,3,0,2,2,2,3,3,3,0,3,0,0,0,2,2,0,1,2,1,1,1,0,0,0,1, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +3,3,3,3,3,3,2,1,2,2,3,3,3,3,2,0,2,0,0,0,2,2,0,0,2,1,3,3,0,0,1,1, +1,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0, +1,1,2,3,3,0,3,3,3,3,3,3,2,2,0,2,0,2,3,2,3,2,2,2,2,2,2,2,1,3,2,3, +2,0,2,1,2,2,2,2,1,1,2,2,1,2,2,1,2,0,0,2,1,1,0,2,1,0,0,1,0,0,0,1, +2,3,3,1,1,1,0,1,1,1,2,3,2,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0, +0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,2,2,3,2,3,2,2,1,3,3,3,0,2,1,2,0,2,1,0,0,1,1,1,1,1,0,0,1, +2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,2,0,1,0,0,0, +3,3,3,2,3,3,3,3,3,2,3,1,2,3,3,1,2,0,0,0,0,0,0,0,3,2,1,1,0,0,0,0, +2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +3,3,3,2,2,3,3,2,1,1,1,1,1,3,3,0,3,1,0,0,1,1,0,0,3,1,2,1,0,0,0,0, +0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0, +3,3,3,2,2,3,2,2,2,3,2,1,1,3,3,0,3,0,0,0,0,1,0,0,3,1,1,2,0,0,0,1, +1,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, +1,1,1,3,3,0,3,3,3,3,3,2,2,2,1,2,0,2,1,2,2,1,1,0,1,2,2,2,2,2,2,2, +0,0,2,1,2,1,2,1,0,1,1,3,1,2,1,1,2,0,0,2,0,1,0,1,0,1,0,0,0,1,0,1, +3,3,3,1,3,3,3,0,1,1,0,2,2,3,1,0,3,0,0,0,1,0,0,0,1,0,0,1,0,1,0,0, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,2,2,1,0,0,1,0,0,3,3,1,3,0,0,1,1,0,2,0,3,0,0,0,2,0,1,1, +0,1,2,0,1,2,2,0,2,2,2,2,1,0,2,1,1,0,2,0,2,1,2,0,0,0,0,0,0,0,0,0, +3,3,3,1,3,2,3,2,0,2,2,2,1,3,2,0,2,1,2,0,1,2,0,0,1,0,2,2,0,0,0,2, +1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,0,0,0, +3,3,3,0,3,3,1,1,2,3,1,0,3,2,3,0,3,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0, +1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,3,3,2,3,3,2,2,0,0,0,0,1,2,0,1,3,0,0,0,3,1,1,0,3,0,2, +2,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,1,2,2,1,0,3,1,1,1,1,3,3,2,3,0,0,1,0,1,2,0,2,2,0,2,2,0,2,1, +0,2,2,1,1,1,1,0,2,1,1,0,1,1,1,1,2,1,2,1,2,0,1,0,1,0,0,0,0,0,0,0, +3,3,3,0,1,1,3,0,0,1,1,0,0,2,2,0,3,0,0,1,1,0,1,0,0,0,0,0,2,0,0,0, +0,3,1,0,1,0,1,0,2,0,0,1,0,1,0,1,1,1,2,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,0,2,0,1,1,1,0,0,3,3,0,2,0,0,1,0,0,2,1,1,0,1,0,1,0,1,0, +0,2,0,1,2,0,2,0,2,1,1,0,1,0,2,1,1,0,2,1,1,0,1,0,0,0,1,1,0,0,0,0, +3,2,3,0,1,0,0,0,0,0,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,0,2,0,0,0, +0,0,1,1,0,0,1,0,1,0,0,1,0,0,0,2,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,0,2,3,0,0,1,0,1,0,2,3,2,3,0,0,1,3,0,2,1,0,0,0,0,2,0,1,0, +0,2,1,0,0,1,1,0,2,1,0,0,1,0,0,1,1,0,1,1,2,0,1,0,0,0,0,1,0,0,0,0, +3,2,2,0,0,1,1,0,0,0,0,0,0,3,1,1,1,0,0,0,0,0,1,0,0,0,0,0,2,0,1,0, +0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,3,0,2,3,2,2,1,2,2,1,1,2,0,1,3,2,2,2,0,0,2,2,0,0,0,1,2,1, +3,0,2,1,1,0,1,1,1,0,1,2,2,2,1,1,2,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0, +0,1,1,2,3,0,3,3,3,2,2,2,2,1,0,1,0,1,0,1,2,2,0,0,2,2,1,3,1,1,2,1, +0,0,1,1,2,0,1,1,0,0,1,2,0,2,1,1,2,0,0,1,0,0,0,1,0,1,0,1,0,0,0,0, +3,3,2,0,0,3,1,0,0,0,0,0,0,3,2,1,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,2,1,1,0,0,1,0,1,2,0,0,1,1,0,0,2,1,1,1,1,0,2,0,0,0,0,0,0,0,0,0, +3,3,2,0,0,1,0,0,0,0,1,0,0,3,3,2,2,0,0,1,0,0,2,0,1,0,0,0,2,0,1,0, +0,0,1,1,0,0,2,0,2,1,0,0,1,1,2,1,2,0,2,1,2,1,1,1,0,0,1,1,0,0,0,0, +3,3,2,0,0,2,2,0,0,0,1,1,0,2,2,1,3,1,0,1,0,1,2,0,0,0,0,0,1,0,1,0, +0,1,1,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,2,0,0,0,1,0,0,1,0,0,2,3,1,2,0,0,1,0,0,2,0,0,0,1,0,2,0,2,0, +0,1,1,2,2,1,2,0,2,1,1,0,0,1,1,0,1,1,1,1,2,1,1,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,1,0,0,1,1,0,3,3,1,2,0,0,1,0,0,2,0,2,0,1,1,2,0,0,0, +0,0,1,1,1,1,2,0,1,1,0,1,1,1,1,0,0,0,1,1,1,0,1,0,0,0,1,0,0,0,0,0, +3,3,3,0,2,2,3,2,0,0,1,0,0,2,3,1,0,0,0,0,0,0,2,0,2,0,0,0,2,0,0,0, +0,1,1,0,0,0,1,0,0,1,0,1,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0, +3,2,3,0,0,0,0,0,0,0,1,0,0,2,2,2,2,0,0,1,0,0,2,0,0,0,0,0,2,0,1,0, +0,0,2,1,1,0,1,0,2,1,1,0,0,1,1,2,1,0,2,0,2,0,1,0,0,0,2,0,0,0,0,0, +0,0,0,2,2,0,2,1,1,1,1,2,2,0,0,1,0,1,0,0,1,3,0,0,0,0,1,0,0,2,1,0, +0,0,1,0,1,0,0,0,0,0,2,1,0,1,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0, +2,0,0,2,3,0,2,3,1,2,2,0,2,0,0,2,0,2,1,1,1,2,1,0,0,1,2,1,1,2,1,0, +1,0,2,0,1,0,1,1,0,0,2,2,1,2,1,1,2,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0, +3,3,3,0,2,1,2,0,0,0,1,0,0,3,2,0,1,0,0,1,0,0,2,0,0,0,1,2,1,0,1,0, +0,0,0,0,1,0,1,0,0,1,0,0,0,0,1,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,2,2,0,2,2,1,1,0,1,1,1,1,1,0,0,1,2,1,1,1,0,1,0,0,0,1,1,1,1, +0,0,2,1,0,1,1,1,0,1,1,2,1,2,1,1,2,0,1,1,2,1,0,2,0,0,0,0,0,0,0,0, +3,2,2,0,0,2,0,0,0,0,0,0,0,2,2,0,2,0,0,1,0,0,2,0,0,0,0,0,2,0,0,0, +0,2,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,3,2,0,2,2,0,1,1,0,1,0,0,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0, +2,0,1,0,1,0,1,1,0,0,1,2,0,1,0,1,1,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0, +2,2,2,0,1,1,0,0,0,1,0,0,0,1,2,0,1,0,0,1,0,0,1,0,0,0,0,1,2,0,1,0, +0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,2,1,0,1,1,1,0,0,0,0,1,2,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0, +1,1,2,0,1,0,0,0,1,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,1, +0,0,1,2,2,0,2,1,2,1,1,2,2,0,0,0,0,1,0,0,1,1,0,0,2,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0, +2,2,2,0,0,0,1,0,0,0,0,0,0,2,2,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, +0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,1,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +2,2,2,0,1,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,1,0,0,0,0,0,0,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +) + +Latin5TurkishModel = { + 'char_to_order_map': Latin5_TurkishCharToOrderMap, + 'precedence_matrix': TurkishLangModel, + 'typical_positive_ratio': 0.970290, + 'keep_english_letter': True, + 'charset_name': "ISO-8859-9", + 'language': 'Turkish', +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py new file mode 100644 index 0000000..7d1e8c2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/latin1prober.py @@ -0,0 +1,145 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState + +FREQ_CAT_NUM = 4 + +UDF = 0 # undefined +OTH = 1 # other +ASC = 2 # ascii capital letter +ASS = 3 # ascii small letter +ACV = 4 # accent capital vowel +ACO = 5 # accent capital other +ASV = 6 # accent small vowel +ASO = 7 # accent small other +CLASS_NUM = 8 # total classes + +Latin1_CharToClass = ( + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 00 - 07 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 08 - 0F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 10 - 17 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 18 - 1F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 20 - 27 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 28 - 2F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 30 - 37 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 38 - 3F + OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 40 - 47 + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 48 - 4F + ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, # 50 - 57 + ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, # 58 - 5F + OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 60 - 67 + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 68 - 6F + ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, # 70 - 77 + ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, # 78 - 7F + OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, # 80 - 87 + OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, # 88 - 8F + UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # 90 - 97 + OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, # 98 - 9F + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A0 - A7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # A8 - AF + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B0 - B7 + OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, # B8 - BF + ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, # C0 - C7 + ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, # C8 - CF + ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, # D0 - D7 + ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, # D8 - DF + ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, # E0 - E7 + ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, # E8 - EF + ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, # F0 - F7 + ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, # F8 - FF +) + +# 0 : illegal +# 1 : very unlikely +# 2 : normal +# 3 : very likely +Latin1ClassModel = ( +# UDF OTH ASC ASS ACV ACO ASV ASO + 0, 0, 0, 0, 0, 0, 0, 0, # UDF + 0, 3, 3, 3, 3, 3, 3, 3, # OTH + 0, 3, 3, 3, 3, 3, 3, 3, # ASC + 0, 3, 3, 3, 1, 1, 3, 3, # ASS + 0, 3, 3, 3, 1, 2, 1, 2, # ACV + 0, 3, 3, 3, 3, 3, 3, 3, # ACO + 0, 3, 1, 3, 1, 1, 1, 3, # ASV + 0, 3, 1, 3, 1, 1, 3, 3, # ASO +) + + +class Latin1Prober(CharSetProber): + def __init__(self): + super(Latin1Prober, self).__init__() + self._last_char_class = None + self._freq_counter = None + self.reset() + + def reset(self): + self._last_char_class = OTH + self._freq_counter = [0] * FREQ_CAT_NUM + CharSetProber.reset(self) + + @property + def charset_name(self): + return "ISO-8859-1" + + @property + def language(self): + return "" + + def feed(self, byte_str): + byte_str = self.filter_with_english_letters(byte_str) + for c in byte_str: + char_class = Latin1_CharToClass[c] + freq = Latin1ClassModel[(self._last_char_class * CLASS_NUM) + + char_class] + if freq == 0: + self._state = ProbingState.NOT_ME + break + self._freq_counter[freq] += 1 + self._last_char_class = char_class + + return self.state + + def get_confidence(self): + if self.state == ProbingState.NOT_ME: + return 0.01 + + total = sum(self._freq_counter) + if total < 0.01: + confidence = 0.0 + else: + confidence = ((self._freq_counter[3] - self._freq_counter[1] * 20.0) + / total) + if confidence < 0.0: + confidence = 0.0 + # lower the confidence of latin1 so that other more accurate + # detector can take priority. + confidence = confidence * 0.73 + return confidence diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py new file mode 100644 index 0000000..6256ecf --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcharsetprober.py @@ -0,0 +1,91 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState + + +class MultiByteCharSetProber(CharSetProber): + """ + MultiByteCharSetProber + """ + + def __init__(self, lang_filter=None): + super(MultiByteCharSetProber, self).__init__(lang_filter=lang_filter) + self.distribution_analyzer = None + self.coding_sm = None + self._last_char = [0, 0] + + def reset(self): + super(MultiByteCharSetProber, self).reset() + if self.coding_sm: + self.coding_sm.reset() + if self.distribution_analyzer: + self.distribution_analyzer.reset() + self._last_char = [0, 0] + + @property + def charset_name(self): + raise NotImplementedError + + @property + def language(self): + raise NotImplementedError + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.distribution_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + return self.distribution_analyzer.get_confidence() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py new file mode 100644 index 0000000..530abe7 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcsgroupprober.py @@ -0,0 +1,54 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# Proofpoint, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .utf8prober import UTF8Prober +from .sjisprober import SJISProber +from .eucjpprober import EUCJPProber +from .gb2312prober import GB2312Prober +from .euckrprober import EUCKRProber +from .cp949prober import CP949Prober +from .big5prober import Big5Prober +from .euctwprober import EUCTWProber + + +class MBCSGroupProber(CharSetGroupProber): + def __init__(self, lang_filter=None): + super(MBCSGroupProber, self).__init__(lang_filter=lang_filter) + self.probers = [ + UTF8Prober(), + SJISProber(), + EUCJPProber(), + GB2312Prober(), + EUCKRProber(), + CP949Prober(), + Big5Prober(), + EUCTWProber() + ] + self.reset() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py new file mode 100644 index 0000000..8360d0f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/mbcssm.py @@ -0,0 +1,572 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .enums import MachineState + +# BIG5 + +BIG5_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 4,4,4,4,4,4,4,4, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 4,3,3,3,3,3,3,3, # a0 - a7 + 3,3,3,3,3,3,3,3, # a8 - af + 3,3,3,3,3,3,3,3, # b0 - b7 + 3,3,3,3,3,3,3,3, # b8 - bf + 3,3,3,3,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +BIG5_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,#08-0f + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START#10-17 +) + +BIG5_CHAR_LEN_TABLE = (0, 1, 1, 2, 0) + +BIG5_SM_MODEL = {'class_table': BIG5_CLS, + 'class_factor': 5, + 'state_table': BIG5_ST, + 'char_len_table': BIG5_CHAR_LEN_TABLE, + 'name': 'Big5'} + +# CP949 + +CP949_CLS = ( + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,0,0, # 00 - 0f + 1,1,1,1,1,1,1,1, 1,1,1,0,1,1,1,1, # 10 - 1f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 20 - 2f + 1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1, # 30 - 3f + 1,4,4,4,4,4,4,4, 4,4,4,4,4,4,4,4, # 40 - 4f + 4,4,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 50 - 5f + 1,5,5,5,5,5,5,5, 5,5,5,5,5,5,5,5, # 60 - 6f + 5,5,5,5,5,5,5,5, 5,5,5,1,1,1,1,1, # 70 - 7f + 0,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 80 - 8f + 6,6,6,6,6,6,6,6, 6,6,6,6,6,6,6,6, # 90 - 9f + 6,7,7,7,7,7,7,7, 7,7,7,7,7,8,8,8, # a0 - af + 7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7, # b0 - bf + 7,7,7,7,7,7,9,2, 2,3,2,2,2,2,2,2, # c0 - cf + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # d0 - df + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2, # e0 - ef + 2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,0, # f0 - ff +) + +CP949_ST = ( +#cls= 0 1 2 3 4 5 6 7 8 9 # previous state = + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.START,MachineState.START, 4, 5,MachineState.ERROR, 6, # MachineState.START + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, # MachineState.ERROR + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME, # MachineState.ITS_ME + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 3 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 4 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, # 5 + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START, # 6 +) + +CP949_CHAR_LEN_TABLE = (0, 1, 2, 0, 1, 1, 2, 2, 0, 2) + +CP949_SM_MODEL = {'class_table': CP949_CLS, + 'class_factor': 10, + 'state_table': CP949_ST, + 'char_len_table': CP949_CHAR_LEN_TABLE, + 'name': 'CP949'} + +# EUC-JP + +EUCJP_CLS = ( + 4,4,4,4,4,4,4,4, # 00 - 07 + 4,4,4,4,4,4,5,5, # 08 - 0f + 4,4,4,4,4,4,4,4, # 10 - 17 + 4,4,4,5,4,4,4,4, # 18 - 1f + 4,4,4,4,4,4,4,4, # 20 - 27 + 4,4,4,4,4,4,4,4, # 28 - 2f + 4,4,4,4,4,4,4,4, # 30 - 37 + 4,4,4,4,4,4,4,4, # 38 - 3f + 4,4,4,4,4,4,4,4, # 40 - 47 + 4,4,4,4,4,4,4,4, # 48 - 4f + 4,4,4,4,4,4,4,4, # 50 - 57 + 4,4,4,4,4,4,4,4, # 58 - 5f + 4,4,4,4,4,4,4,4, # 60 - 67 + 4,4,4,4,4,4,4,4, # 68 - 6f + 4,4,4,4,4,4,4,4, # 70 - 77 + 4,4,4,4,4,4,4,4, # 78 - 7f + 5,5,5,5,5,5,5,5, # 80 - 87 + 5,5,5,5,5,5,1,3, # 88 - 8f + 5,5,5,5,5,5,5,5, # 90 - 97 + 5,5,5,5,5,5,5,5, # 98 - 9f + 5,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,0,5 # f8 - ff +) + +EUCJP_ST = ( + 3, 4, 3, 5,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 3,MachineState.ERROR,#18-1f + 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START#20-27 +) + +EUCJP_CHAR_LEN_TABLE = (2, 2, 2, 3, 1, 0) + +EUCJP_SM_MODEL = {'class_table': EUCJP_CLS, + 'class_factor': 6, + 'state_table': EUCJP_ST, + 'char_len_table': EUCJP_CHAR_LEN_TABLE, + 'name': 'EUC-JP'} + +# EUC-KR + +EUCKR_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,3,3,3, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,3,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 2,2,2,2,2,2,2,2, # e0 - e7 + 2,2,2,2,2,2,2,2, # e8 - ef + 2,2,2,2,2,2,2,2, # f0 - f7 + 2,2,2,2,2,2,2,0 # f8 - ff +) + +EUCKR_ST = ( + MachineState.ERROR,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #08-0f +) + +EUCKR_CHAR_LEN_TABLE = (0, 1, 2, 0) + +EUCKR_SM_MODEL = {'class_table': EUCKR_CLS, + 'class_factor': 4, + 'state_table': EUCKR_ST, + 'char_len_table': EUCKR_CHAR_LEN_TABLE, + 'name': 'EUC-KR'} + +# EUC-TW + +EUCTW_CLS = ( + 2,2,2,2,2,2,2,2, # 00 - 07 + 2,2,2,2,2,2,0,0, # 08 - 0f + 2,2,2,2,2,2,2,2, # 10 - 17 + 2,2,2,0,2,2,2,2, # 18 - 1f + 2,2,2,2,2,2,2,2, # 20 - 27 + 2,2,2,2,2,2,2,2, # 28 - 2f + 2,2,2,2,2,2,2,2, # 30 - 37 + 2,2,2,2,2,2,2,2, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,2, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,6,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,3,4,4,4,4,4,4, # a0 - a7 + 5,5,1,1,1,1,1,1, # a8 - af + 1,1,1,1,1,1,1,1, # b0 - b7 + 1,1,1,1,1,1,1,1, # b8 - bf + 1,1,3,1,3,3,3,3, # c0 - c7 + 3,3,3,3,3,3,3,3, # c8 - cf + 3,3,3,3,3,3,3,3, # d0 - d7 + 3,3,3,3,3,3,3,3, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,3,3,3, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,3,3,0 # f8 - ff +) + +EUCTW_ST = ( + MachineState.ERROR,MachineState.ERROR,MachineState.START, 3, 3, 3, 4,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.START,MachineState.ERROR,#10-17 + MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,#20-27 + MachineState.START,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +EUCTW_CHAR_LEN_TABLE = (0, 0, 1, 2, 2, 2, 3) + +EUCTW_SM_MODEL = {'class_table': EUCTW_CLS, + 'class_factor': 7, + 'state_table': EUCTW_ST, + 'char_len_table': EUCTW_CHAR_LEN_TABLE, + 'name': 'x-euc-tw'} + +# GB2312 + +GB2312_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 3,3,3,3,3,3,3,3, # 30 - 37 + 3,3,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,4, # 78 - 7f + 5,6,6,6,6,6,6,6, # 80 - 87 + 6,6,6,6,6,6,6,6, # 88 - 8f + 6,6,6,6,6,6,6,6, # 90 - 97 + 6,6,6,6,6,6,6,6, # 98 - 9f + 6,6,6,6,6,6,6,6, # a0 - a7 + 6,6,6,6,6,6,6,6, # a8 - af + 6,6,6,6,6,6,6,6, # b0 - b7 + 6,6,6,6,6,6,6,6, # b8 - bf + 6,6,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 6,6,6,6,6,6,6,6, # e0 - e7 + 6,6,6,6,6,6,6,6, # e8 - ef + 6,6,6,6,6,6,6,6, # f0 - f7 + 6,6,6,6,6,6,6,0 # f8 - ff +) + +GB2312_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START, 3,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,#10-17 + 4,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ERROR,MachineState.ERROR, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#20-27 + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.START #28-2f +) + +# To be accurate, the length of class 6 can be either 2 or 4. +# But it is not necessary to discriminate between the two since +# it is used for frequency analysis only, and we are validating +# each code range there as well. So it is safe to set it to be +# 2 here. +GB2312_CHAR_LEN_TABLE = (0, 1, 1, 1, 1, 1, 2) + +GB2312_SM_MODEL = {'class_table': GB2312_CLS, + 'class_factor': 7, + 'state_table': GB2312_ST, + 'char_len_table': GB2312_CHAR_LEN_TABLE, + 'name': 'GB2312'} + +# Shift_JIS + +SJIS_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 2,2,2,2,2,2,2,2, # 40 - 47 + 2,2,2,2,2,2,2,2, # 48 - 4f + 2,2,2,2,2,2,2,2, # 50 - 57 + 2,2,2,2,2,2,2,2, # 58 - 5f + 2,2,2,2,2,2,2,2, # 60 - 67 + 2,2,2,2,2,2,2,2, # 68 - 6f + 2,2,2,2,2,2,2,2, # 70 - 77 + 2,2,2,2,2,2,2,1, # 78 - 7f + 3,3,3,3,3,2,2,3, # 80 - 87 + 3,3,3,3,3,3,3,3, # 88 - 8f + 3,3,3,3,3,3,3,3, # 90 - 97 + 3,3,3,3,3,3,3,3, # 98 - 9f + #0xa0 is illegal in sjis encoding, but some pages does + #contain such byte. We need to be more error forgiven. + 2,2,2,2,2,2,2,2, # a0 - a7 + 2,2,2,2,2,2,2,2, # a8 - af + 2,2,2,2,2,2,2,2, # b0 - b7 + 2,2,2,2,2,2,2,2, # b8 - bf + 2,2,2,2,2,2,2,2, # c0 - c7 + 2,2,2,2,2,2,2,2, # c8 - cf + 2,2,2,2,2,2,2,2, # d0 - d7 + 2,2,2,2,2,2,2,2, # d8 - df + 3,3,3,3,3,3,3,3, # e0 - e7 + 3,3,3,3,3,4,4,4, # e8 - ef + 3,3,3,3,3,3,3,3, # f0 - f7 + 3,3,3,3,3,0,0,0) # f8 - ff + + +SJIS_ST = ( + MachineState.ERROR,MachineState.START,MachineState.START, 3,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START #10-17 +) + +SJIS_CHAR_LEN_TABLE = (0, 1, 1, 2, 0, 0) + +SJIS_SM_MODEL = {'class_table': SJIS_CLS, + 'class_factor': 6, + 'state_table': SJIS_ST, + 'char_len_table': SJIS_CHAR_LEN_TABLE, + 'name': 'Shift_JIS'} + +# UCS2-BE + +UCS2BE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2BE_ST = ( + 5, 7, 7,MachineState.ERROR, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,#10-17 + 6, 6, 6, 6, 6,MachineState.ITS_ME, 6, 6,#18-1f + 6, 6, 6, 6, 5, 7, 7,MachineState.ERROR,#20-27 + 5, 8, 6, 6,MachineState.ERROR, 6, 6, 6,#28-2f + 6, 6, 6, 6,MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2BE_CHAR_LEN_TABLE = (2, 2, 2, 0, 2, 2) + +UCS2BE_SM_MODEL = {'class_table': UCS2BE_CLS, + 'class_factor': 6, + 'state_table': UCS2BE_ST, + 'char_len_table': UCS2BE_CHAR_LEN_TABLE, + 'name': 'UTF-16BE'} + +# UCS2-LE + +UCS2LE_CLS = ( + 0,0,0,0,0,0,0,0, # 00 - 07 + 0,0,1,0,0,2,0,0, # 08 - 0f + 0,0,0,0,0,0,0,0, # 10 - 17 + 0,0,0,3,0,0,0,0, # 18 - 1f + 0,0,0,0,0,0,0,0, # 20 - 27 + 0,3,3,3,3,3,0,0, # 28 - 2f + 0,0,0,0,0,0,0,0, # 30 - 37 + 0,0,0,0,0,0,0,0, # 38 - 3f + 0,0,0,0,0,0,0,0, # 40 - 47 + 0,0,0,0,0,0,0,0, # 48 - 4f + 0,0,0,0,0,0,0,0, # 50 - 57 + 0,0,0,0,0,0,0,0, # 58 - 5f + 0,0,0,0,0,0,0,0, # 60 - 67 + 0,0,0,0,0,0,0,0, # 68 - 6f + 0,0,0,0,0,0,0,0, # 70 - 77 + 0,0,0,0,0,0,0,0, # 78 - 7f + 0,0,0,0,0,0,0,0, # 80 - 87 + 0,0,0,0,0,0,0,0, # 88 - 8f + 0,0,0,0,0,0,0,0, # 90 - 97 + 0,0,0,0,0,0,0,0, # 98 - 9f + 0,0,0,0,0,0,0,0, # a0 - a7 + 0,0,0,0,0,0,0,0, # a8 - af + 0,0,0,0,0,0,0,0, # b0 - b7 + 0,0,0,0,0,0,0,0, # b8 - bf + 0,0,0,0,0,0,0,0, # c0 - c7 + 0,0,0,0,0,0,0,0, # c8 - cf + 0,0,0,0,0,0,0,0, # d0 - d7 + 0,0,0,0,0,0,0,0, # d8 - df + 0,0,0,0,0,0,0,0, # e0 - e7 + 0,0,0,0,0,0,0,0, # e8 - ef + 0,0,0,0,0,0,0,0, # f0 - f7 + 0,0,0,0,0,0,4,5 # f8 - ff +) + +UCS2LE_ST = ( + 6, 6, 7, 6, 4, 3,MachineState.ERROR,MachineState.ERROR,#00-07 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#08-0f + MachineState.ITS_ME,MachineState.ITS_ME, 5, 5, 5,MachineState.ERROR,MachineState.ITS_ME,MachineState.ERROR,#10-17 + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR, 6, 6,#18-1f + 7, 6, 8, 8, 5, 5, 5,MachineState.ERROR,#20-27 + 5, 5, 5,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5,#28-2f + 5, 5, 5,MachineState.ERROR, 5,MachineState.ERROR,MachineState.START,MachineState.START #30-37 +) + +UCS2LE_CHAR_LEN_TABLE = (2, 2, 2, 2, 2, 2) + +UCS2LE_SM_MODEL = {'class_table': UCS2LE_CLS, + 'class_factor': 6, + 'state_table': UCS2LE_ST, + 'char_len_table': UCS2LE_CHAR_LEN_TABLE, + 'name': 'UTF-16LE'} + +# UTF-8 + +UTF8_CLS = ( + 1,1,1,1,1,1,1,1, # 00 - 07 #allow 0x00 as a legal value + 1,1,1,1,1,1,0,0, # 08 - 0f + 1,1,1,1,1,1,1,1, # 10 - 17 + 1,1,1,0,1,1,1,1, # 18 - 1f + 1,1,1,1,1,1,1,1, # 20 - 27 + 1,1,1,1,1,1,1,1, # 28 - 2f + 1,1,1,1,1,1,1,1, # 30 - 37 + 1,1,1,1,1,1,1,1, # 38 - 3f + 1,1,1,1,1,1,1,1, # 40 - 47 + 1,1,1,1,1,1,1,1, # 48 - 4f + 1,1,1,1,1,1,1,1, # 50 - 57 + 1,1,1,1,1,1,1,1, # 58 - 5f + 1,1,1,1,1,1,1,1, # 60 - 67 + 1,1,1,1,1,1,1,1, # 68 - 6f + 1,1,1,1,1,1,1,1, # 70 - 77 + 1,1,1,1,1,1,1,1, # 78 - 7f + 2,2,2,2,3,3,3,3, # 80 - 87 + 4,4,4,4,4,4,4,4, # 88 - 8f + 4,4,4,4,4,4,4,4, # 90 - 97 + 4,4,4,4,4,4,4,4, # 98 - 9f + 5,5,5,5,5,5,5,5, # a0 - a7 + 5,5,5,5,5,5,5,5, # a8 - af + 5,5,5,5,5,5,5,5, # b0 - b7 + 5,5,5,5,5,5,5,5, # b8 - bf + 0,0,6,6,6,6,6,6, # c0 - c7 + 6,6,6,6,6,6,6,6, # c8 - cf + 6,6,6,6,6,6,6,6, # d0 - d7 + 6,6,6,6,6,6,6,6, # d8 - df + 7,8,8,8,8,8,8,8, # e0 - e7 + 8,8,8,8,8,9,8,8, # e8 - ef + 10,11,11,11,11,11,11,11, # f0 - f7 + 12,13,13,13,14,15,0,0 # f8 - ff +) + +UTF8_ST = ( + MachineState.ERROR,MachineState.START,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12, 10,#00-07 + 9, 11, 8, 7, 6, 5, 4, 3,#08-0f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#10-17 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#18-1f + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#20-27 + MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,MachineState.ITS_ME,#28-2f + MachineState.ERROR,MachineState.ERROR, 5, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#30-37 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#38-3f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 5, 5, 5,MachineState.ERROR,MachineState.ERROR,#40-47 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#48-4f + MachineState.ERROR,MachineState.ERROR, 7, 7, 7, 7,MachineState.ERROR,MachineState.ERROR,#50-57 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#58-5f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 7, 7,MachineState.ERROR,MachineState.ERROR,#60-67 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#68-6f + MachineState.ERROR,MachineState.ERROR, 9, 9, 9, 9,MachineState.ERROR,MachineState.ERROR,#70-77 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#78-7f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 9,MachineState.ERROR,MachineState.ERROR,#80-87 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#88-8f + MachineState.ERROR,MachineState.ERROR, 12, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,#90-97 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#98-9f + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR, 12,MachineState.ERROR,MachineState.ERROR,#a0-a7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#a8-af + MachineState.ERROR,MachineState.ERROR, 12, 12, 12,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b0-b7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,#b8-bf + MachineState.ERROR,MachineState.ERROR,MachineState.START,MachineState.START,MachineState.START,MachineState.START,MachineState.ERROR,MachineState.ERROR,#c0-c7 + MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR,MachineState.ERROR #c8-cf +) + +UTF8_CHAR_LEN_TABLE = (0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6) + +UTF8_SM_MODEL = {'class_table': UTF8_CLS, + 'class_factor': 16, + 'state_table': UTF8_ST, + 'char_len_table': UTF8_CHAR_LEN_TABLE, + 'name': 'UTF-8'} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py new file mode 100644 index 0000000..0adb51d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/sbcharsetprober.py @@ -0,0 +1,132 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import CharacterCategory, ProbingState, SequenceLikelihood + + +class SingleByteCharSetProber(CharSetProber): + SAMPLE_SIZE = 64 + SB_ENOUGH_REL_THRESHOLD = 1024 # 0.25 * SAMPLE_SIZE^2 + POSITIVE_SHORTCUT_THRESHOLD = 0.95 + NEGATIVE_SHORTCUT_THRESHOLD = 0.05 + + def __init__(self, model, reversed=False, name_prober=None): + super(SingleByteCharSetProber, self).__init__() + self._model = model + # TRUE if we need to reverse every pair in the model lookup + self._reversed = reversed + # Optional auxiliary prober for name decision + self._name_prober = name_prober + self._last_order = None + self._seq_counters = None + self._total_seqs = None + self._total_char = None + self._freq_char = None + self.reset() + + def reset(self): + super(SingleByteCharSetProber, self).reset() + # char order of last character + self._last_order = 255 + self._seq_counters = [0] * SequenceLikelihood.get_num_categories() + self._total_seqs = 0 + self._total_char = 0 + # characters that fall in our sampling range + self._freq_char = 0 + + @property + def charset_name(self): + if self._name_prober: + return self._name_prober.charset_name + else: + return self._model['charset_name'] + + @property + def language(self): + if self._name_prober: + return self._name_prober.language + else: + return self._model.get('language') + + def feed(self, byte_str): + if not self._model['keep_english_letter']: + byte_str = self.filter_international_words(byte_str) + if not byte_str: + return self.state + char_to_order_map = self._model['char_to_order_map'] + for i, c in enumerate(byte_str): + # XXX: Order is in range 1-64, so one would think we want 0-63 here, + # but that leads to 27 more test failures than before. + order = char_to_order_map[c] + # XXX: This was SYMBOL_CAT_ORDER before, with a value of 250, but + # CharacterCategory.SYMBOL is actually 253, so we use CONTROL + # to make it closer to the original intent. The only difference + # is whether or not we count digits and control characters for + # _total_char purposes. + if order < CharacterCategory.CONTROL: + self._total_char += 1 + if order < self.SAMPLE_SIZE: + self._freq_char += 1 + if self._last_order < self.SAMPLE_SIZE: + self._total_seqs += 1 + if not self._reversed: + i = (self._last_order * self.SAMPLE_SIZE) + order + model = self._model['precedence_matrix'][i] + else: # reverse the order of the letters in the lookup + i = (order * self.SAMPLE_SIZE) + self._last_order + model = self._model['precedence_matrix'][i] + self._seq_counters[model] += 1 + self._last_order = order + + charset_name = self._model['charset_name'] + if self.state == ProbingState.DETECTING: + if self._total_seqs > self.SB_ENOUGH_REL_THRESHOLD: + confidence = self.get_confidence() + if confidence > self.POSITIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, we have a winner', + charset_name, confidence) + self._state = ProbingState.FOUND_IT + elif confidence < self.NEGATIVE_SHORTCUT_THRESHOLD: + self.logger.debug('%s confidence = %s, below negative ' + 'shortcut threshhold %s', charset_name, + confidence, + self.NEGATIVE_SHORTCUT_THRESHOLD) + self._state = ProbingState.NOT_ME + + return self.state + + def get_confidence(self): + r = 0.01 + if self._total_seqs > 0: + r = ((1.0 * self._seq_counters[SequenceLikelihood.POSITIVE]) / + self._total_seqs / self._model['typical_positive_ratio']) + r = r * self._freq_char / self._total_char + if r >= 1.0: + r = 0.99 + return r diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py new file mode 100644 index 0000000..98e95dc --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/sbcsgroupprober.py @@ -0,0 +1,73 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetgroupprober import CharSetGroupProber +from .sbcharsetprober import SingleByteCharSetProber +from .langcyrillicmodel import (Win1251CyrillicModel, Koi8rModel, + Latin5CyrillicModel, MacCyrillicModel, + Ibm866Model, Ibm855Model) +from .langgreekmodel import Latin7GreekModel, Win1253GreekModel +from .langbulgarianmodel import Latin5BulgarianModel, Win1251BulgarianModel +# from .langhungarianmodel import Latin2HungarianModel, Win1250HungarianModel +from .langthaimodel import TIS620ThaiModel +from .langhebrewmodel import Win1255HebrewModel +from .hebrewprober import HebrewProber +from .langturkishmodel import Latin5TurkishModel + + +class SBCSGroupProber(CharSetGroupProber): + def __init__(self): + super(SBCSGroupProber, self).__init__() + self.probers = [ + SingleByteCharSetProber(Win1251CyrillicModel), + SingleByteCharSetProber(Koi8rModel), + SingleByteCharSetProber(Latin5CyrillicModel), + SingleByteCharSetProber(MacCyrillicModel), + SingleByteCharSetProber(Ibm866Model), + SingleByteCharSetProber(Ibm855Model), + SingleByteCharSetProber(Latin7GreekModel), + SingleByteCharSetProber(Win1253GreekModel), + SingleByteCharSetProber(Latin5BulgarianModel), + SingleByteCharSetProber(Win1251BulgarianModel), + # TODO: Restore Hungarian encodings (iso-8859-2 and windows-1250) + # after we retrain model. + # SingleByteCharSetProber(Latin2HungarianModel), + # SingleByteCharSetProber(Win1250HungarianModel), + SingleByteCharSetProber(TIS620ThaiModel), + SingleByteCharSetProber(Latin5TurkishModel), + ] + hebrew_prober = HebrewProber() + logical_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, + False, hebrew_prober) + visual_hebrew_prober = SingleByteCharSetProber(Win1255HebrewModel, True, + hebrew_prober) + hebrew_prober.set_model_probers(logical_hebrew_prober, visual_hebrew_prober) + self.probers.extend([hebrew_prober, logical_hebrew_prober, + visual_hebrew_prober]) + + self.reset() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py new file mode 100644 index 0000000..9e29623 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/sjisprober.py @@ -0,0 +1,92 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .mbcharsetprober import MultiByteCharSetProber +from .codingstatemachine import CodingStateMachine +from .chardistribution import SJISDistributionAnalysis +from .jpcntx import SJISContextAnalysis +from .mbcssm import SJIS_SM_MODEL +from .enums import ProbingState, MachineState + + +class SJISProber(MultiByteCharSetProber): + def __init__(self): + super(SJISProber, self).__init__() + self.coding_sm = CodingStateMachine(SJIS_SM_MODEL) + self.distribution_analyzer = SJISDistributionAnalysis() + self.context_analyzer = SJISContextAnalysis() + self.reset() + + def reset(self): + super(SJISProber, self).reset() + self.context_analyzer.reset() + + @property + def charset_name(self): + return self.context_analyzer.charset_name + + @property + def language(self): + return "Japanese" + + def feed(self, byte_str): + for i in range(len(byte_str)): + coding_state = self.coding_sm.next_state(byte_str[i]) + if coding_state == MachineState.ERROR: + self.logger.debug('%s %s prober hit error at byte %s', + self.charset_name, self.language, i) + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + char_len = self.coding_sm.get_current_charlen() + if i == 0: + self._last_char[1] = byte_str[0] + self.context_analyzer.feed(self._last_char[2 - char_len:], + char_len) + self.distribution_analyzer.feed(self._last_char, char_len) + else: + self.context_analyzer.feed(byte_str[i + 1 - char_len:i + 3 + - char_len], char_len) + self.distribution_analyzer.feed(byte_str[i - 1:i + 1], + char_len) + + self._last_char[0] = byte_str[-1] + + if self.state == ProbingState.DETECTING: + if (self.context_analyzer.got_enough_data() and + (self.get_confidence() > self.SHORTCUT_THRESHOLD)): + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + context_conf = self.context_analyzer.get_confidence() + distrib_conf = self.distribution_analyzer.get_confidence() + return max(context_conf, distrib_conf) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py new file mode 100644 index 0000000..7b4e92d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/universaldetector.py @@ -0,0 +1,286 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is Mozilla Universal charset detector code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 2001 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# Shy Shalom - original C code +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### +""" +Module containing the UniversalDetector detector class, which is the primary +class a user of ``chardet`` should use. + +:author: Mark Pilgrim (initial port to Python) +:author: Shy Shalom (original C code) +:author: Dan Blanchard (major refactoring for 3.0) +:author: Ian Cordasco +""" + + +import codecs +import logging +import re + +from .charsetgroupprober import CharSetGroupProber +from .enums import InputState, LanguageFilter, ProbingState +from .escprober import EscCharSetProber +from .latin1prober import Latin1Prober +from .mbcsgroupprober import MBCSGroupProber +from .sbcsgroupprober import SBCSGroupProber + + +class UniversalDetector(object): + """ + The ``UniversalDetector`` class underlies the ``chardet.detect`` function + and coordinates all of the different charset probers. + + To get a ``dict`` containing an encoding and its confidence, you can simply + run: + + .. code:: + + u = UniversalDetector() + u.feed(some_bytes) + u.close() + detected = u.result + + """ + + MINIMUM_THRESHOLD = 0.20 + HIGH_BYTE_DETECTOR = re.compile(b'[\x80-\xFF]') + ESC_DETECTOR = re.compile(b'(\033|~{)') + WIN_BYTE_DETECTOR = re.compile(b'[\x80-\x9F]') + ISO_WIN_MAP = {'iso-8859-1': 'Windows-1252', + 'iso-8859-2': 'Windows-1250', + 'iso-8859-5': 'Windows-1251', + 'iso-8859-6': 'Windows-1256', + 'iso-8859-7': 'Windows-1253', + 'iso-8859-8': 'Windows-1255', + 'iso-8859-9': 'Windows-1254', + 'iso-8859-13': 'Windows-1257'} + + def __init__(self, lang_filter=LanguageFilter.ALL): + self._esc_charset_prober = None + self._charset_probers = [] + self.result = None + self.done = None + self._got_data = None + self._input_state = None + self._last_char = None + self.lang_filter = lang_filter + self.logger = logging.getLogger(__name__) + self._has_win_bytes = None + self.reset() + + def reset(self): + """ + Reset the UniversalDetector and all of its probers back to their + initial states. This is called by ``__init__``, so you only need to + call this directly in between analyses of different documents. + """ + self.result = {'encoding': None, 'confidence': 0.0, 'language': None} + self.done = False + self._got_data = False + self._has_win_bytes = False + self._input_state = InputState.PURE_ASCII + self._last_char = b'' + if self._esc_charset_prober: + self._esc_charset_prober.reset() + for prober in self._charset_probers: + prober.reset() + + def feed(self, byte_str): + """ + Takes a chunk of a document and feeds it through all of the relevant + charset probers. + + After calling ``feed``, you can check the value of the ``done`` + attribute to see if you need to continue feeding the + ``UniversalDetector`` more data, or if it has made a prediction + (in the ``result`` attribute). + + .. note:: + You should always call ``close`` when you're done feeding in your + document if ``done`` is not already ``True``. + """ + if self.done: + return + + if not len(byte_str): + return + + if not isinstance(byte_str, bytearray): + byte_str = bytearray(byte_str) + + # First check for known BOMs, since these are guaranteed to be correct + if not self._got_data: + # If the data starts with BOM, we know it is UTF + if byte_str.startswith(codecs.BOM_UTF8): + # EF BB BF UTF-8 with BOM + self.result = {'encoding': "UTF-8-SIG", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_UTF32_LE, + codecs.BOM_UTF32_BE)): + # FF FE 00 00 UTF-32, little-endian BOM + # 00 00 FE FF UTF-32, big-endian BOM + self.result = {'encoding': "UTF-32", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\xFE\xFF\x00\x00'): + # FE FF 00 00 UCS-4, unusual octet order BOM (3412) + self.result = {'encoding': "X-ISO-10646-UCS-4-3412", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith(b'\x00\x00\xFF\xFE'): + # 00 00 FF FE UCS-4, unusual octet order BOM (2143) + self.result = {'encoding': "X-ISO-10646-UCS-4-2143", + 'confidence': 1.0, + 'language': ''} + elif byte_str.startswith((codecs.BOM_LE, codecs.BOM_BE)): + # FF FE UTF-16, little endian BOM + # FE FF UTF-16, big endian BOM + self.result = {'encoding': "UTF-16", + 'confidence': 1.0, + 'language': ''} + + self._got_data = True + if self.result['encoding'] is not None: + self.done = True + return + + # If none of those matched and we've only see ASCII so far, check + # for high bytes and escape sequences + if self._input_state == InputState.PURE_ASCII: + if self.HIGH_BYTE_DETECTOR.search(byte_str): + self._input_state = InputState.HIGH_BYTE + elif self._input_state == InputState.PURE_ASCII and \ + self.ESC_DETECTOR.search(self._last_char + byte_str): + self._input_state = InputState.ESC_ASCII + + self._last_char = byte_str[-1:] + + # If we've seen escape sequences, use the EscCharSetProber, which + # uses a simple state machine to check for known escape sequences in + # HZ and ISO-2022 encodings, since those are the only encodings that + # use such sequences. + if self._input_state == InputState.ESC_ASCII: + if not self._esc_charset_prober: + self._esc_charset_prober = EscCharSetProber(self.lang_filter) + if self._esc_charset_prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': + self._esc_charset_prober.charset_name, + 'confidence': + self._esc_charset_prober.get_confidence(), + 'language': + self._esc_charset_prober.language} + self.done = True + # If we've seen high bytes (i.e., those with values greater than 127), + # we need to do more complicated checks using all our multi-byte and + # single-byte probers that are left. The single-byte probers + # use character bigram distributions to determine the encoding, whereas + # the multi-byte probers use a combination of character unigram and + # bigram distributions. + elif self._input_state == InputState.HIGH_BYTE: + if not self._charset_probers: + self._charset_probers = [MBCSGroupProber(self.lang_filter)] + # If we're checking non-CJK encodings, use single-byte prober + if self.lang_filter & LanguageFilter.NON_CJK: + self._charset_probers.append(SBCSGroupProber()) + self._charset_probers.append(Latin1Prober()) + for prober in self._charset_probers: + if prober.feed(byte_str) == ProbingState.FOUND_IT: + self.result = {'encoding': prober.charset_name, + 'confidence': prober.get_confidence(), + 'language': prober.language} + self.done = True + break + if self.WIN_BYTE_DETECTOR.search(byte_str): + self._has_win_bytes = True + + def close(self): + """ + Stop analyzing the current document and come up with a final + prediction. + + :returns: The ``result`` attribute, a ``dict`` with the keys + `encoding`, `confidence`, and `language`. + """ + # Don't bother with checks if we're already done + if self.done: + return self.result + self.done = True + + if not self._got_data: + self.logger.debug('no data received!') + + # Default to ASCII if it is all we've seen so far + elif self._input_state == InputState.PURE_ASCII: + self.result = {'encoding': 'ascii', + 'confidence': 1.0, + 'language': ''} + + # If we have seen non-ASCII, return the best that met MINIMUM_THRESHOLD + elif self._input_state == InputState.HIGH_BYTE: + prober_confidence = None + max_prober_confidence = 0.0 + max_prober = None + for prober in self._charset_probers: + if not prober: + continue + prober_confidence = prober.get_confidence() + if prober_confidence > max_prober_confidence: + max_prober_confidence = prober_confidence + max_prober = prober + if max_prober and (max_prober_confidence > self.MINIMUM_THRESHOLD): + charset_name = max_prober.charset_name + lower_charset_name = max_prober.charset_name.lower() + confidence = max_prober.get_confidence() + # Use Windows encoding name instead of ISO-8859 if we saw any + # extra Windows-specific bytes + if lower_charset_name.startswith('iso-8859'): + if self._has_win_bytes: + charset_name = self.ISO_WIN_MAP.get(lower_charset_name, + charset_name) + self.result = {'encoding': charset_name, + 'confidence': confidence, + 'language': max_prober.language} + + # Log all prober confidences if none met MINIMUM_THRESHOLD + if self.logger.getEffectiveLevel() == logging.DEBUG: + if self.result['encoding'] is None: + self.logger.debug('no probers hit minimum threshold') + for group_prober in self._charset_probers: + if not group_prober: + continue + if isinstance(group_prober, CharSetGroupProber): + for prober in group_prober.probers: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + else: + self.logger.debug('%s %s confidence = %s', + prober.charset_name, + prober.language, + prober.get_confidence()) + return self.result diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py new file mode 100644 index 0000000..6c3196c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/utf8prober.py @@ -0,0 +1,82 @@ +######################## BEGIN LICENSE BLOCK ######################## +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Netscape Communications Corporation. +# Portions created by the Initial Developer are Copyright (C) 1998 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Mark Pilgrim - port to Python +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +# 02110-1301 USA +######################### END LICENSE BLOCK ######################### + +from .charsetprober import CharSetProber +from .enums import ProbingState, MachineState +from .codingstatemachine import CodingStateMachine +from .mbcssm import UTF8_SM_MODEL + + + +class UTF8Prober(CharSetProber): + ONE_CHAR_PROB = 0.5 + + def __init__(self): + super(UTF8Prober, self).__init__() + self.coding_sm = CodingStateMachine(UTF8_SM_MODEL) + self._num_mb_chars = None + self.reset() + + def reset(self): + super(UTF8Prober, self).reset() + self.coding_sm.reset() + self._num_mb_chars = 0 + + @property + def charset_name(self): + return "utf-8" + + @property + def language(self): + return "" + + def feed(self, byte_str): + for c in byte_str: + coding_state = self.coding_sm.next_state(c) + if coding_state == MachineState.ERROR: + self._state = ProbingState.NOT_ME + break + elif coding_state == MachineState.ITS_ME: + self._state = ProbingState.FOUND_IT + break + elif coding_state == MachineState.START: + if self.coding_sm.get_current_charlen() >= 2: + self._num_mb_chars += 1 + + if self.state == ProbingState.DETECTING: + if self.get_confidence() > self.SHORTCUT_THRESHOLD: + self._state = ProbingState.FOUND_IT + + return self.state + + def get_confidence(self): + unlike = 0.99 + if self._num_mb_chars < 6: + unlike *= self.ONE_CHAR_PROB ** self._num_mb_chars + return 1.0 - unlike + else: + return unlike diff --git a/env/lib/python3.7/site-packages/pip/_vendor/chardet/version.py b/env/lib/python3.7/site-packages/pip/_vendor/chardet/version.py new file mode 100644 index 0000000..bb2a34a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/chardet/version.py @@ -0,0 +1,9 @@ +""" +This module exists only to simplify retrieving the version number of chardet +from within setup.py and from chardet subpackages. + +:author: Dan Blanchard (dan.blanchard@gmail.com) +""" + +__version__ = "3.0.4" +VERSION = __version__.split('.') diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py new file mode 100644 index 0000000..f4d9ce2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/colorama/__init__.py @@ -0,0 +1,7 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from .initialise import init, deinit, reinit, colorama_text +from .ansi import Fore, Back, Style, Cursor +from .ansitowin32 import AnsiToWin32 + +__version__ = '0.3.9' + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..36b53e1960009bc51d0089aca8aadb2d78b3dfec GIT binary patch literal 400 zcmXw#PfNov6u_G{?Yecv>pp?d!&-4(1Q|NTqn8On5JFjlMDwR6nR9*_&wiy`J$du& z$-IpP-tYZ?yq85;j-v3$=keoj(BI%3UL1_eAoeDpi#jACi3pN0iDg0(i3vs!k3}jo zlF0!X$eiSINQS$3B1W<xMX)g$cj+>!vL6&iRoG*$xbs=Z_S)=qxza+LR<_i!cL!y+ z+Axn7?drv+OScuwXV+_EwW*LVu9W5X`hlz2=|_4}&+7BLs`Mim$y>oKGjM@P02q)4 zc-)3IlYu_~<bWY$3dlIUfq@3T#TS&mF=M$_lzv6#2ucBe^Tx@(>3Kip%DPsF>1y+& qp55yi1a}fTRi{mJxT&EOHlwuew?4m+x?2l2hYc+(GeHwHj{gBxf@#12 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..82d49ae5893cf1326427b1b50862e660c9998ad4 GIT binary patch literal 3298 zcmcguTXWk)6xK@eO}@l&(u9_qp-^g|HZXlknNDoSP0~6}v6Bf^TZHhciCV{YS4uCL zbcUJqe*lmCr5)aQ(qHHk=UeCEq+w`YkY+#W?2*pdbNN=PWwVw>hyB}?2Y;nB?QaN& zhe<c{G=kp=xMpjd*^KM9&JEk(CXc<=Y?H@%g03<C9#3)WHM8UVB2V)S-6a+^p5?jM z8qayjeZx+XJi+rM=ap=cJjn|r7rYed(<D#vX_BXvoFVxFpCNfh$yqPGuh}^-Lpb4O z3G<#sILT)_TItg6uh!a@9~8F-e5dCXH@&_m+|Ub()mCS@*xho4+YLQY><&0hhJ)fz z`2EoDZ_-R}Ak-A;xBb4`3(8i<^X7_MVK|(tRJ?xqx&Oo;dfa!*1F>0wRDoT`3%c&m zb70ik)!)BQ<KY{Y=rYO~4qOcybs9mQAk;#(r|q*@O6ROb3)fqcZI^Uu)H}=42trX} z(uBP~H4-pp0P?O|o;53l+CAar}ZYu)FY{m0?c>zGu-dFJ)`KvYyD?zUTT`+;8` zzLZ%Qa>9Xw_=5}<p%Z9KBneNf67yrL#On66Sz7JEDtGnoZeW?Kow_t?jV3KK7W!e& zQ>z?7f^5iC;DwITOpti!556P#IN|iaQ**nd3p^#zjz|sF_br#1ZqIXt6Lf{=^$Yai zp;u)5oDT1tbSMzS=@6}vzn<UsE{u7D=Pr$-1M$w&2&M@<jp(BheTYOv8G{>CeN(2Y zRI54#6&x)T@uKu~ygEnl;(AEM*k=pc!>g~@9{Zhf_6G~BP~X$`*uMTs4-MRf=AORK z_6?>zwKj;e2kqsQV$$HgkQVii2!rQ-xFr*tUg(CQkO`_6Zd6N@3~2^l?~ye7?zSgm z&)nY5Tj@?Zj^Fn~$GL<BqLVZ;$1FN`3rEqE4<Bk#kn{%ZIgYd(XT(st&p6K09k(~q zh!4ojSfY^tfrb)O1Q%(jq9&P=Pox?7n#Th-369d7<+M}LK4kEm+N~JvRugK!Vzgi7 zd6K8pel^K0p2mK~GnB7_v{VQ?A{dAW^zEXGIB<n4RhA<zvr}BIp6DN4VC9na$0AcK z(bw;OPMU*8-OV05EwA4_r_0(IF2!ZCe%h(Iu)5LuV$AKtm|N)1>A3!`juW?5+Z)yP zLTSwRs8v*+%LnRnx?gx#_hzkHzw_0Y@A0^y>!PkWaK)(82+)ygza~<R_G{X^NA=d# zu4uI0up5#somhu)Q1Ta&y*yn2<L+wb8ceI6V!OGq{FACxV&W50pMBAlZuCG>d`QoU zj{qM7J_B3<Tm^gyr~nj?jzKZ1ND90V;On1cmOeTK=DReG4)p&#jo>c95wpN4o!Dd$ zk4*aF$A~*|JINDviYIN0r|dMh><mxaS)Q?TJZn$zoSo+r^sUa@1wLs{@d9yeN+uEi zt%2|&L=qvAs0ct7qE7*r0a$DVzC`HW$Oha8JODfd`~+|SKLcEXR%!ZFnq;ijq;gB6 z-B^&Z#df37lJR?uW^;8znziP7Lnc<Li;dP=RhspC)s~EHEG@4!WUSrjG}dIcxxBcv zrc5}EA7xsJWD3Gar%Xc3Dc#64<jldV>kUW~N;+_LtcFWSBU{QfiD#DZ8;b8+8Ud1& zWajD9I5{Km{QqCtn%jL6p&=tMKSEbV;9>MN08EI=0CZ}Ea3T)y0FMBhfGvOzcno+# z@OEiMjiv>7D;59^z%9TcU<t4cxDB`iXaZIMEx;-OjV^uwv;oJ&QFn?x9a6yNyQUt` zpPhPaF#pafVn}@Sd(a7A(tj2>A+iL~41fluA#u9H<Fz)LR2mD*D>B|%ZLd_DGNt<0 zsWzKuMudEWMCx09*h~Vm*pcA!@KTTo$Kivn<Ba~wQlt|WAPK-<p2!36FC^oGUmkni zP<^r0=AznAAR)@SG{Jph9<_;#sVHT<u09E8ty3nyAN@PrjFE+)NMP!!&y6IVmSLIs ObUvG(p)($5IR61cz<5;v literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/ansitowin32.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..835ef58b5586a471573c7e4957a651cfb4e03e45 GIT binary patch literal 7011 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 S39-SPiKkq8j<Q^9Zt*YBWN;Y( literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/initialise.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8d6c12e722e26ad7330296a05235ebf447c4abeb GIT binary patch literal 1619 zcma)6OK&4Z5bo}Ic>K(RB|sE}mBUJwSR%2A17gtvA_oq>VC^DnC981{&Sb|krn<c* zE9XLT-~xYv<j7x|E2sSnocOA}c9IoH%&4lnx~sdZzxt}bYPTB#-|&z7&(3Q?{Kdxl z3(<KDu@1@zBXcoawQ?xEt%k}d6Xd}(9EK7eI)cQI8YD5HuA9ijmtxp3yCyO9OF3+s zhG}A?mCDn$X_@w=xRAq+>6k5yZkcVfgLd1<??msdS2$VpUrFemteRgIHXD>rv*O{$ z$77yae+r$iA@*G;hajKV>7El#UdStTEfAW(cCz0KD1b-REGe6etTW}@Rdq^j>P9-x z{}dEs+N-}GAGzu5XqL?$WQBE@eK1~3ic|N~Cp_q7^dc=xNk`){FG)}JQC4Iw(|Kmo zk7j2SVXs|?Wh8}6q#qfKy@?TS`8*%_ujniTyYIwOEag&7f(uFeP8!_d7wOb#phM_L z$K1ya6Z+H$T`Trn;zC}5b-_gx3a3VauCcH8dIqn$_ln=}igevI?4@g7wOspJ0wtvz z9;u-J^1}t`*`s5f+q63_iy!lB>}+?Dxs$Fg&bp;LNvW%8@@PQwbkOTm0fwu_6P?e~ zZ-`2&0()kwcm*=?UA>VK-N4UAhYy;iW}S{E+b}5A(>s%XrFQAhnH!n1NUL~dR0*Y% z%sR|7;=Qn{>$xj^R;wCff02@_BJ7yWs*rcT$ufcTq6#^0@1SS*p@iC%NfgUiHDny@ zNw0$tEit|Rop@c$ye3|Ui8oS?lT@bz7r+YF1dKcq#8pR4R&7=-RvYTAdOot)q#WBr z%-aNtSrjvq-a~&A3Dck5ONc#$T9N2?r1T{c`UC~=6eWOiK=1oaF(`i@zg16FA(DxF zJzsEpD;OU~drk2X@OPi_IX)afq+~<U0Y*0Apf5HR*@f}{fa$>V7BJgv{x>k>f$^nt z2blM<Y|K31k0ISu*nJqwkPg=swhWB?Ej*8w(UrUwbhwO8)j6sUFNNZl;%)fT9;<s$ zo2SE`l=Iw-m`6-#rfDyx57_VS3Svf8wH3YT4Mb@RlixxtUs1>qf6FJ=&-B9Met*#0 zA$~uq21v}f=h+V)psK0y61sB1FQI?YR;=<|@-TYvcCgl$#7&;7&g-qFy3i9;3@45l sGk@%@AUzv>?vu}_rJ3jH7o1be3lapHs1|A>R9=E4Y8)iBPCcpp15+|jIsgCw literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/win32.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b583af5d8f10dac7ec4f7f6f9a9a702aa5060ec5 GIT binary patch literal 3834 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 UO%s`Gx{hm>3$9g~b4zaNzZQmO&;S4c literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/colorama/__pycache__/winterm.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aa14dc98333ce2617aff6676ca148fbb54b9b907 GIT binary patch literal 4523 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py b/env/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py new file mode 100644 index 0000000..7877658 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/colorama/ansi.py @@ -0,0 +1,102 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +''' +This module generates ANSI character codes to printing colors to terminals. +See: http://en.wikipedia.org/wiki/ANSI_escape_code +''' + +CSI = '\033[' +OSC = '\033]' +BEL = '\007' + + +def code_to_chars(code): + return CSI + str(code) + 'm' + +def set_title(title): + return OSC + '2;' + title + BEL + +def clear_screen(mode=2): + return CSI + str(mode) + 'J' + +def clear_line(mode=2): + return CSI + str(mode) + 'K' + + +class AnsiCodes(object): + def __init__(self): + # the subclasses declare class attributes which are numbers. + # Upon instantiation we define instance attributes, which are the same + # as the class attributes but wrapped with the ANSI escape sequence + for name in dir(self): + if not name.startswith('_'): + value = getattr(self, name) + setattr(self, name, code_to_chars(value)) + + +class AnsiCursor(object): + def UP(self, n=1): + return CSI + str(n) + 'A' + def DOWN(self, n=1): + return CSI + str(n) + 'B' + def FORWARD(self, n=1): + return CSI + str(n) + 'C' + def BACK(self, n=1): + return CSI + str(n) + 'D' + def POS(self, x=1, y=1): + return CSI + str(y) + ';' + str(x) + 'H' + + +class AnsiFore(AnsiCodes): + BLACK = 30 + RED = 31 + GREEN = 32 + YELLOW = 33 + BLUE = 34 + MAGENTA = 35 + CYAN = 36 + WHITE = 37 + RESET = 39 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 90 + LIGHTRED_EX = 91 + LIGHTGREEN_EX = 92 + LIGHTYELLOW_EX = 93 + LIGHTBLUE_EX = 94 + LIGHTMAGENTA_EX = 95 + LIGHTCYAN_EX = 96 + LIGHTWHITE_EX = 97 + + +class AnsiBack(AnsiCodes): + BLACK = 40 + RED = 41 + GREEN = 42 + YELLOW = 43 + BLUE = 44 + MAGENTA = 45 + CYAN = 46 + WHITE = 47 + RESET = 49 + + # These are fairly well supported, but not part of the standard. + LIGHTBLACK_EX = 100 + LIGHTRED_EX = 101 + LIGHTGREEN_EX = 102 + LIGHTYELLOW_EX = 103 + LIGHTBLUE_EX = 104 + LIGHTMAGENTA_EX = 105 + LIGHTCYAN_EX = 106 + LIGHTWHITE_EX = 107 + + +class AnsiStyle(AnsiCodes): + BRIGHT = 1 + DIM = 2 + NORMAL = 22 + RESET_ALL = 0 + +Fore = AnsiFore() +Back = AnsiBack() +Style = AnsiStyle() +Cursor = AnsiCursor() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py b/env/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py new file mode 100644 index 0000000..1d6e605 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/colorama/ansitowin32.py @@ -0,0 +1,236 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import re +import sys +import os + +from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style +from .winterm import WinTerm, WinColor, WinStyle +from .win32 import windll, winapi_test + + +winterm = None +if windll is not None: + winterm = WinTerm() + + +def is_stream_closed(stream): + return not hasattr(stream, 'closed') or stream.closed + + +def is_a_tty(stream): + return hasattr(stream, 'isatty') and stream.isatty() + + +class StreamWrapper(object): + ''' + Wraps a stream (such as stdout), acting as a transparent proxy for all + attribute access apart from method 'write()', which is delegated to our + Converter instance. + ''' + def __init__(self, wrapped, converter): + # double-underscore everything to prevent clashes with names of + # attributes on the wrapped stream object. + self.__wrapped = wrapped + self.__convertor = converter + + def __getattr__(self, name): + return getattr(self.__wrapped, name) + + def write(self, text): + self.__convertor.write(text) + + +class AnsiToWin32(object): + ''' + Implements a 'write()' method which, on Windows, will strip ANSI character + sequences from the text, and if outputting to a tty, will convert them into + win32 function calls. + ''' + ANSI_CSI_RE = re.compile('\001?\033\\[((?:\\d|;)*)([a-zA-Z])\002?') # Control Sequence Introducer + ANSI_OSC_RE = re.compile('\001?\033\\]((?:.|;)*?)(\x07)\002?') # Operating System Command + + def __init__(self, wrapped, convert=None, strip=None, autoreset=False): + # The wrapped stream (normally sys.stdout or sys.stderr) + self.wrapped = wrapped + + # should we reset colors to defaults after every .write() + self.autoreset = autoreset + + # create the proxy wrapping our output stream + self.stream = StreamWrapper(wrapped, self) + + on_windows = os.name == 'nt' + # We test if the WinAPI works, because even if we are on Windows + # we may be using a terminal that doesn't support the WinAPI + # (e.g. Cygwin Terminal). In this case it's up to the terminal + # to support the ANSI codes. + conversion_supported = on_windows and winapi_test() + + # should we strip ANSI sequences from our output? + if strip is None: + strip = conversion_supported or (not is_stream_closed(wrapped) and not is_a_tty(wrapped)) + self.strip = strip + + # should we should convert ANSI sequences into win32 calls? + if convert is None: + convert = conversion_supported and not is_stream_closed(wrapped) and is_a_tty(wrapped) + self.convert = convert + + # dict of ansi codes to win32 functions and parameters + self.win32_calls = self.get_win32_calls() + + # are we wrapping stderr? + self.on_stderr = self.wrapped is sys.stderr + + def should_wrap(self): + ''' + True if this class is actually needed. If false, then the output + stream will not be affected, nor will win32 calls be issued, so + wrapping stdout is not actually required. This will generally be + False on non-Windows platforms, unless optional functionality like + autoreset has been requested using kwargs to init() + ''' + return self.convert or self.strip or self.autoreset + + def get_win32_calls(self): + if self.convert and winterm: + return { + AnsiStyle.RESET_ALL: (winterm.reset_all, ), + AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT), + AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL), + AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL), + AnsiFore.BLACK: (winterm.fore, WinColor.BLACK), + AnsiFore.RED: (winterm.fore, WinColor.RED), + AnsiFore.GREEN: (winterm.fore, WinColor.GREEN), + AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW), + AnsiFore.BLUE: (winterm.fore, WinColor.BLUE), + AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA), + AnsiFore.CYAN: (winterm.fore, WinColor.CYAN), + AnsiFore.WHITE: (winterm.fore, WinColor.GREY), + AnsiFore.RESET: (winterm.fore, ), + AnsiFore.LIGHTBLACK_EX: (winterm.fore, WinColor.BLACK, True), + AnsiFore.LIGHTRED_EX: (winterm.fore, WinColor.RED, True), + AnsiFore.LIGHTGREEN_EX: (winterm.fore, WinColor.GREEN, True), + AnsiFore.LIGHTYELLOW_EX: (winterm.fore, WinColor.YELLOW, True), + AnsiFore.LIGHTBLUE_EX: (winterm.fore, WinColor.BLUE, True), + AnsiFore.LIGHTMAGENTA_EX: (winterm.fore, WinColor.MAGENTA, True), + AnsiFore.LIGHTCYAN_EX: (winterm.fore, WinColor.CYAN, True), + AnsiFore.LIGHTWHITE_EX: (winterm.fore, WinColor.GREY, True), + AnsiBack.BLACK: (winterm.back, WinColor.BLACK), + AnsiBack.RED: (winterm.back, WinColor.RED), + AnsiBack.GREEN: (winterm.back, WinColor.GREEN), + AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW), + AnsiBack.BLUE: (winterm.back, WinColor.BLUE), + AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA), + AnsiBack.CYAN: (winterm.back, WinColor.CYAN), + AnsiBack.WHITE: (winterm.back, WinColor.GREY), + AnsiBack.RESET: (winterm.back, ), + AnsiBack.LIGHTBLACK_EX: (winterm.back, WinColor.BLACK, True), + AnsiBack.LIGHTRED_EX: (winterm.back, WinColor.RED, True), + AnsiBack.LIGHTGREEN_EX: (winterm.back, WinColor.GREEN, True), + AnsiBack.LIGHTYELLOW_EX: (winterm.back, WinColor.YELLOW, True), + AnsiBack.LIGHTBLUE_EX: (winterm.back, WinColor.BLUE, True), + AnsiBack.LIGHTMAGENTA_EX: (winterm.back, WinColor.MAGENTA, True), + AnsiBack.LIGHTCYAN_EX: (winterm.back, WinColor.CYAN, True), + AnsiBack.LIGHTWHITE_EX: (winterm.back, WinColor.GREY, True), + } + return dict() + + def write(self, text): + if self.strip or self.convert: + self.write_and_convert(text) + else: + self.wrapped.write(text) + self.wrapped.flush() + if self.autoreset: + self.reset_all() + + + def reset_all(self): + if self.convert: + self.call_win32('m', (0,)) + elif not self.strip and not is_stream_closed(self.wrapped): + self.wrapped.write(Style.RESET_ALL) + + + def write_and_convert(self, text): + ''' + Write the given text to our wrapped stream, stripping any ANSI + sequences from the text, and optionally converting them into win32 + calls. + ''' + cursor = 0 + text = self.convert_osc(text) + for match in self.ANSI_CSI_RE.finditer(text): + start, end = match.span() + self.write_plain_text(text, cursor, start) + self.convert_ansi(*match.groups()) + cursor = end + self.write_plain_text(text, cursor, len(text)) + + + def write_plain_text(self, text, start, end): + if start < end: + self.wrapped.write(text[start:end]) + self.wrapped.flush() + + + def convert_ansi(self, paramstring, command): + if self.convert: + params = self.extract_params(command, paramstring) + self.call_win32(command, params) + + + def extract_params(self, command, paramstring): + if command in 'Hf': + params = tuple(int(p) if len(p) != 0 else 1 for p in paramstring.split(';')) + while len(params) < 2: + # defaults: + params = params + (1,) + else: + params = tuple(int(p) for p in paramstring.split(';') if len(p) != 0) + if len(params) == 0: + # defaults: + if command in 'JKm': + params = (0,) + elif command in 'ABCD': + params = (1,) + + return params + + + def call_win32(self, command, params): + if command == 'm': + for param in params: + if param in self.win32_calls: + func_args = self.win32_calls[param] + func = func_args[0] + args = func_args[1:] + kwargs = dict(on_stderr=self.on_stderr) + func(*args, **kwargs) + elif command in 'J': + winterm.erase_screen(params[0], on_stderr=self.on_stderr) + elif command in 'K': + winterm.erase_line(params[0], on_stderr=self.on_stderr) + elif command in 'Hf': # cursor position - absolute + winterm.set_cursor_position(params, on_stderr=self.on_stderr) + elif command in 'ABCD': # cursor position - relative + n = params[0] + # A - up, B - down, C - forward, D - back + x, y = {'A': (0, -n), 'B': (0, n), 'C': (n, 0), 'D': (-n, 0)}[command] + winterm.cursor_adjust(x, y, on_stderr=self.on_stderr) + + + def convert_osc(self, text): + for match in self.ANSI_OSC_RE.finditer(text): + start, end = match.span() + text = text[:start] + text[end:] + paramstring, command = match.groups() + if command in '\x07': # \x07 = BEL + params = paramstring.split(";") + # 0 - change title and icon (we will only change title) + # 1 - change icon (we don't support this) + # 2 - change title + if params[0] in '02': + winterm.set_title(params[1]) + return text diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py b/env/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py new file mode 100644 index 0000000..834962a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/colorama/initialise.py @@ -0,0 +1,82 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +import atexit +import contextlib +import sys + +from .ansitowin32 import AnsiToWin32 + + +orig_stdout = None +orig_stderr = None + +wrapped_stdout = None +wrapped_stderr = None + +atexit_done = False + + +def reset_all(): + if AnsiToWin32 is not None: # Issue #74: objects might become None at exit + AnsiToWin32(orig_stdout).reset_all() + + +def init(autoreset=False, convert=None, strip=None, wrap=True): + + if not wrap and any([autoreset, convert, strip]): + raise ValueError('wrap=False conflicts with any other arg=True') + + global wrapped_stdout, wrapped_stderr + global orig_stdout, orig_stderr + + orig_stdout = sys.stdout + orig_stderr = sys.stderr + + if sys.stdout is None: + wrapped_stdout = None + else: + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + if sys.stderr is None: + wrapped_stderr = None + else: + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + + global atexit_done + if not atexit_done: + atexit.register(reset_all) + atexit_done = True + + +def deinit(): + if orig_stdout is not None: + sys.stdout = orig_stdout + if orig_stderr is not None: + sys.stderr = orig_stderr + + +@contextlib.contextmanager +def colorama_text(*args, **kwargs): + init(*args, **kwargs) + try: + yield + finally: + deinit() + + +def reinit(): + if wrapped_stdout is not None: + sys.stdout = wrapped_stdout + if wrapped_stderr is not None: + sys.stderr = wrapped_stderr + + +def wrap_stream(stream, convert, strip, autoreset, wrap): + if wrap: + wrapper = AnsiToWin32(stream, + convert=convert, strip=strip, autoreset=autoreset) + if wrapper.should_wrap(): + stream = wrapper.stream + return stream + + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py b/env/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py new file mode 100644 index 0000000..8262e35 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/colorama/win32.py @@ -0,0 +1,156 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. + +# from winbase.h +STDOUT = -11 +STDERR = -12 + +try: + import ctypes + from ctypes import LibraryLoader + windll = LibraryLoader(ctypes.WinDLL) + from ctypes import wintypes +except (AttributeError, ImportError): + windll = None + SetConsoleTextAttribute = lambda *_: None + winapi_test = lambda *_: None +else: + from ctypes import byref, Structure, c_char, POINTER + + COORD = wintypes._COORD + + class CONSOLE_SCREEN_BUFFER_INFO(Structure): + """struct in wincon.h.""" + _fields_ = [ + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", wintypes.WORD), + ("srWindow", wintypes.SMALL_RECT), + ("dwMaximumWindowSize", COORD), + ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) + + _GetStdHandle = windll.kernel32.GetStdHandle + _GetStdHandle.argtypes = [ + wintypes.DWORD, + ] + _GetStdHandle.restype = wintypes.HANDLE + + _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo + _GetConsoleScreenBufferInfo.argtypes = [ + wintypes.HANDLE, + POINTER(CONSOLE_SCREEN_BUFFER_INFO), + ] + _GetConsoleScreenBufferInfo.restype = wintypes.BOOL + + _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute + _SetConsoleTextAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + ] + _SetConsoleTextAttribute.restype = wintypes.BOOL + + _SetConsoleCursorPosition = windll.kernel32.SetConsoleCursorPosition + _SetConsoleCursorPosition.argtypes = [ + wintypes.HANDLE, + COORD, + ] + _SetConsoleCursorPosition.restype = wintypes.BOOL + + _FillConsoleOutputCharacterA = windll.kernel32.FillConsoleOutputCharacterA + _FillConsoleOutputCharacterA.argtypes = [ + wintypes.HANDLE, + c_char, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputCharacterA.restype = wintypes.BOOL + + _FillConsoleOutputAttribute = windll.kernel32.FillConsoleOutputAttribute + _FillConsoleOutputAttribute.argtypes = [ + wintypes.HANDLE, + wintypes.WORD, + wintypes.DWORD, + COORD, + POINTER(wintypes.DWORD), + ] + _FillConsoleOutputAttribute.restype = wintypes.BOOL + + _SetConsoleTitleW = windll.kernel32.SetConsoleTitleW + _SetConsoleTitleW.argtypes = [ + wintypes.LPCWSTR + ] + _SetConsoleTitleW.restype = wintypes.BOOL + + handles = { + STDOUT: _GetStdHandle(STDOUT), + STDERR: _GetStdHandle(STDERR), + } + + def _winapi_test(handle): + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return bool(success) + + def winapi_test(): + return any(_winapi_test(h) for h in handles.values()) + + def GetConsoleScreenBufferInfo(stream_id=STDOUT): + handle = handles[stream_id] + csbi = CONSOLE_SCREEN_BUFFER_INFO() + success = _GetConsoleScreenBufferInfo( + handle, byref(csbi)) + return csbi + + def SetConsoleTextAttribute(stream_id, attrs): + handle = handles[stream_id] + return _SetConsoleTextAttribute(handle, attrs) + + def SetConsoleCursorPosition(stream_id, position, adjust=True): + position = COORD(*position) + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + if adjust: + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = handles[stream_id] + return _SetConsoleCursorPosition(handle, adjusted_position) + + def FillConsoleOutputCharacter(stream_id, char, length, start): + handle = handles[stream_id] + char = c_char(char.encode()) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = _FillConsoleOutputCharacterA( + handle, char, length, start, byref(num_written)) + return num_written.value + + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = handles[stream_id] + attribute = wintypes.WORD(attr) + length = wintypes.DWORD(length) + num_written = wintypes.DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + return _FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + + def SetConsoleTitle(title): + return _SetConsoleTitleW(title) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py b/env/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py new file mode 100644 index 0000000..60309d3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/colorama/winterm.py @@ -0,0 +1,162 @@ +# Copyright Jonathan Hartley 2013. BSD 3-Clause license, see LICENSE file. +from . import win32 + + +# from wincon.h +class WinColor(object): + BLACK = 0 + BLUE = 1 + GREEN = 2 + CYAN = 3 + RED = 4 + MAGENTA = 5 + YELLOW = 6 + GREY = 7 + +# from wincon.h +class WinStyle(object): + NORMAL = 0x00 # dim text, dim background + BRIGHT = 0x08 # bright text, dim background + BRIGHT_BACKGROUND = 0x80 # dim text, bright background + +class WinTerm(object): + + def __init__(self): + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self.set_attrs(self._default) + self._default_fore = self._fore + self._default_back = self._back + self._default_style = self._style + # In order to emulate LIGHT_EX in windows, we borrow the BRIGHT style. + # So that LIGHT_EX colors and BRIGHT style do not clobber each other, + # we track them separately, since LIGHT_EX is overwritten by Fore/Back + # and BRIGHT is overwritten by Style codes. + self._light = 0 + + def get_attrs(self): + return self._fore + self._back * 16 + (self._style | self._light) + + def set_attrs(self, value): + self._fore = value & 7 + self._back = (value >> 4) & 7 + self._style = value & (WinStyle.BRIGHT | WinStyle.BRIGHT_BACKGROUND) + + def reset_all(self, on_stderr=None): + self.set_attrs(self._default) + self.set_console(attrs=self._default) + + def fore(self, fore=None, light=False, on_stderr=False): + if fore is None: + fore = self._default_fore + self._fore = fore + # Emulate LIGHT_EX with BRIGHT Style + if light: + self._light |= WinStyle.BRIGHT + else: + self._light &= ~WinStyle.BRIGHT + self.set_console(on_stderr=on_stderr) + + def back(self, back=None, light=False, on_stderr=False): + if back is None: + back = self._default_back + self._back = back + # Emulate LIGHT_EX with BRIGHT_BACKGROUND Style + if light: + self._light |= WinStyle.BRIGHT_BACKGROUND + else: + self._light &= ~WinStyle.BRIGHT_BACKGROUND + self.set_console(on_stderr=on_stderr) + + def style(self, style=None, on_stderr=False): + if style is None: + style = self._default_style + self._style = style + self.set_console(on_stderr=on_stderr) + + def set_console(self, attrs=None, on_stderr=False): + if attrs is None: + attrs = self.get_attrs() + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleTextAttribute(handle, attrs) + + def get_position(self, handle): + position = win32.GetConsoleScreenBufferInfo(handle).dwCursorPosition + # Because Windows coordinates are 0-based, + # and win32.SetConsoleCursorPosition expects 1-based. + position.X += 1 + position.Y += 1 + return position + + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + # I'm not currently tracking the position, so there is no default. + # position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def cursor_adjust(self, x, y, on_stderr=False): + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + position = self.get_position(handle) + adjusted_position = (position.Y + y, position.X + x) + win32.SetConsoleCursorPosition(handle, adjusted_position, adjust=False) + + def erase_screen(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen, and move cursor to (1,1) + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + cells_in_screen = csbi.dwSize.X * csbi.dwSize.Y + # get number of character cells before current cursor position + cells_before_cursor = csbi.dwSize.X * csbi.dwCursorPosition.Y + csbi.dwCursorPosition.X + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = cells_in_screen - cells_before_cursor + if mode == 1: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_before_cursor + elif mode == 2: + from_coord = win32.COORD(0, 0) + cells_to_erase = cells_in_screen + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + if mode == 2: + # put the cursor where needed + win32.SetConsoleCursorPosition(handle, (1, 1)) + + def erase_line(self, mode=0, on_stderr=False): + # 0 should clear from the cursor to the end of the line. + # 1 should clear from the cursor to the beginning of the line. + # 2 should clear the entire line. + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + csbi = win32.GetConsoleScreenBufferInfo(handle) + if mode == 0: + from_coord = csbi.dwCursorPosition + cells_to_erase = csbi.dwSize.X - csbi.dwCursorPosition.X + if mode == 1: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwCursorPosition.X + elif mode == 2: + from_coord = win32.COORD(0, csbi.dwCursorPosition.Y) + cells_to_erase = csbi.dwSize.X + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ' ', cells_to_erase, from_coord) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), cells_to_erase, from_coord) + + def set_title(self, title): + win32.SetConsoleTitle(title) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py new file mode 100644 index 0000000..d4aab45 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import logging + +__version__ = '0.2.7' + +class DistlibException(Exception): + pass + +try: + from logging import NullHandler +except ImportError: # pragma: no cover + class NullHandler(logging.Handler): + def handle(self, record): pass + def emit(self, record): pass + def createLock(self): self.lock = None + +logger = logging.getLogger(__name__) +logger.addHandler(NullHandler()) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8111b5810910b2178465a302fabeaf606fa6880c GIT binary patch literal 998 zcma)4&2G~`5T3QyKXKa16ohyHRLO@X2qAF+6af_=RXM-`u#i^4y9BozJ6$_KD{k$3 z&>nfEy>j9eI5D$snt(Vk){JL&zWLpGyt$bGQvPk{-JS>VgAPlIQ5hjO6$%NGX~;o( zIeP}um;4MQSKg_g`^PC-0}V5ta|W-W+Toyr!^FH~Kp)~m86iGWa1f#ge+!lO1{9n} zD!yQOPxa0d#ZTdaG0gJ{viK+Fgz-smXK;6Lzo5gC7%C&=W&?$SoJq(%=j7S+Y1y>8 ze82alQ1iB|t8wPrScqyeQ$pB8h*>Qcn)D4JjusQ$S-yh_F`5&<9uC{td^j)XyJgk1 z6RmfP&(rFlJ-SDij>RWc$=VEMmu@ITS(U92gZZ(+F+!i}BPC|;oH5%UFSLF>siaos zkA4U?BK&O>tA3<+2D#r2I_ENwA)W&n(QphsO+k)C^rxXbL2ft-2?%0i*G=YG-YEUS zhDH^&k*hvUgisrPbR}(*FEX5Luhlu|jQ^X-^e}*-h59=SSF^Icj)pErx}Jkf1=UYP zf9l8eLXjkV1+nZ1$H;YE9A>Obb@gUlFG*q4q*eQfxPh)+uAA$*R)BF98XrN124(^h z^k{~b%50HX1$P=v%gy~7Dh*x5j6Qdl^=+i<>9nk-wl8oyOoPjZTh_bUM7IYHZ2K=} z^V+m~#?;0}mpfs5Q`PQc3}swlHl%>c*kmH*CFWl>+4w=X(~qdaCZ)nW?xnuRQntlz H1qu5Nz!J{3 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b98327a2cf2bccb932908c4e262fda06b4e7a193 GIT binary patch literal 32008 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 E2d{AwzyJUM literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/database.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..86d3794eb6be3730732f0e5a46daec52ef0a252c GIT binary patch literal 42481 zcmeHw3ve9gec$cg6Nd*u5Ck8Rs1qL|0g;d`Q?x=;iYPuT$`Zto&?9Hdhr{gxIPh=> ze!C!n%fU`f#ZjEtQe3BxOq+mBn`zRtNi%6C(}$DHIBq(VxUJhH%{Fa3(@ZDMw4O9+ z+C)j}{(k>&_uIY0k)oAkrtK7%+uPgy_S^6A|Np=L`+H`1xR}CU`3E2V$WMJSmHJQo z5&h+H@-#l)TUILNq{=DBa_ok+VwY`;=jleeoR;rQIV0cMa#p@`<(z!y%X#@Olne4b zP#%!)V!0^agXKXd<768{E5qgCm67rY>diR0#*UTI@~E8W8#`CV%3~|L%Dd!up)tO) zyS#g4qCBy(r@Tk54K((y>?`kE*<aqja$otrmHW&0uRKtGVC6vhz{-Q=2T`Wz3_3&3 zursolEtlN<)<f>W+gACIv!i_287&`icDfVJn6t|ncMm(e7xLwYor&_%52l<w&feEk z&R+M}t#o-3zxO#K_&p-Or|^5fQ^fD0{C)(#?{fz6d(eFZ<&Wd{{mu}654p$j`viVJ z;0)vUu>78OPm~{Zr_1lb^#jg>xc;Ej^Im7tdB{2Vx>bJ6IpiFEJym|6bHsTV-zS}; z&M|yH?xe4#Ca2naE?>A@df)p`mFg?24R^(D`c=Q)YEFNZ6F6xFqifB2t>w6tM%{N+ zwc*Wt6%(17w1d&}b<c0q=P#_++*Ljk3@F!Yt*M&p;laXHU)7t7mtI8C;-c$UyxJ1# z5B9v&^ww5aTgrExmtE!I!3#>Y)MPp+yx{s(r|MUOoiALNJ$wG_?Agl2OV3}JIs3we zV9zVhUbyglW!sI(e6Vx1syw%%-0N#~C4C5X)T(%$Q(0B5Raf~N!Gtc;tgg6~YSXFQ z(60`Llv{Nw?m8Rf1;aNLx@mq6oV)t+72J1Kz|&WFQw2lpxT?>uNvHQcQ}x_SP0z13 z8m`lIYj^+4yDls)UTQA1y2{FEMwMQ!`b+Iys~ZkpbRulq^s?7#w#UPZwbsfCy5Y&y zVBpfs)!DPpKY!s$kh^l>+>2Mv2Lo3we9KE0uFhVN)2lDObmiQIt3mGSvuCedINvT# zOVxF>qQ;4i{%o8)jgNN>2RBu=fU&k?0Yhyk4XDWw)9{^ja!wxKIi~<98VGWga~$vX z^TiVW&XzoZrjkrTX{EZl3P>n%?7b3NU5ejcT18jAlHV$^K~eubsisCi;~&4-vUB)& z6FAgUom531Eyu#S?bv8Xx?PqB*@jEax?it0>Yj@?mg=0JX3d>0%`UmhE!DkJv!zxr zWgDed(=9EuRLMmTO369lEKHjUFU|l$Gwef<VWWeAMYjoz02l+>GoIU6_>q)4h}OOR z<fHz|>Z7am)f4jGM&m^7=3;Z%zkZSz<pcO@IxY1mdkq|Vlu$npK$>3N2nv--9j&ia z-oyUpa7blxR?ceg(4#yZ-S0m@2T;C~T25_Qw=r@!v-Oz_6edyz>YVA<xrSR+C4b4) zvvs`WxxUZos{5Rly6<81WGqV<L*MNhk&NQof^3bIs0VSbN;phf>LH$UH1y#R&yL{m z1U_M(idNBT4~2b_8fu(n{_#75kIeXEIO$l+(y42CHQm9C;}@=+;WcZ^#(8=%b=%&` zbgbJJXtjk-+U+^h$+M1As&;`G`(`>F_vtjqM0G_<o+hkpd#36*ap{@KtnRdoLJ=e9 zxC_;_h99J_xf?+afRAaOv}H7cjDUFem;`B5_%u4G$0R#s4O#7CI3~C?1M&uV5VBPX zij~Sr%UNr<l}a#Fsa#*HHo`mkO2ui_Diw7Yb;&@hDW1h|lQWry2XNy!Us=GRkj_{I z{3%|o;bZ>NIC~l&?{yryXu<tL1uRelO$D+}!5JVmaPw}~&E2xGQe(Bml>x4p_%1pl z&JKJJx<k&Wv-9=TEvr1t)e_f6oN;G2zIR|{n{f7E%^G#~I{R>CC)Tw6&V9HtCSd!Z z+JmOFUy^CP;;v%3!FmOfLYOVJ7P=;jU>g!;pg779X-miajn#Th@ZQ_-rg?2r&*#j= z8hgw?e%tt*!^b<1LkCpmT0xEYfVNGG@K*sBL%P%9G3{q=0TL_O@H;2>@_xZd-(p$t zD}cvLbqj>dfaEzWJbo8(DlMqiO4!ijrIxIz($adf)>w0hlMQ#VTH7ccBP3z@X?TyC z`Y;4*tA4A6YXWCnpWMmrA&DV3gmd;^!?}zOaAM7KkC&<(Q_#+EP?cNrTdMAQ)1^xb zAe?^5TXk#og}Un;H}5CWHGk3AlF*{Y1j>Xj)?LC%ySR9omCmX)yw_hs`G{7RZq^%( zQlr(nCghpxhC&}zGaQBfZw{Mah5+mZI^&gYx~L4_{!$A|0!ghyun4)IcwlB`gM5g@ zlf@v7jtGVa!=TBW1-HVgfql_W^gwV2YoIK5KvMZ;*MgDgyjh(Gcc91(2l<c{noMgd zNwQfUOx71;?IGL~oSwmnH-<xMpn$bN{_TRr^Y*^;Xi~IxUdEL6Um>`R3P^KFAqfRg zS~H;4kK=cLk{ygy$hw6c(w&$`X^-fUvf78Xzj<5vE~0MGiV}k$5`==Tc7((-d!yP| za})H7BZ1}s%)6W8;`&{hv#ospMRPBk(|6I7l_UmpSuP1iU?Q5}2AkD}UN{pVgo%A0 z>eFQSB+l+IxP!9j>FzAE8(i{I8LW!;ZyVP{QPYEAlpe&VhL1Oc>Ge~$Qk&LW*80<2 z7tg2OvR*s6Y5Vq8x?|tAHq#wQTA*W7*GD_)t&GEKnNCKHb~4LZ@9FEKehz2$Eo(Eo z{&pvOKK0t~ZRS|AlM72;#(mJgYdO`tei`q`zh$XnC%0Ab2X5oNs^}N}!9{yBzdqH; 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 J3i}KD{x`4CS2zFw literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/index.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bc86c72c52c60ab59942a1ecdb6bec5952263997 GIT binary patch literal 17294 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/locators.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1aa00836108065a1284ae83eb32e82e13c98dc5b GIT binary patch literal 38601 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 OghvB=-pCq-)c*nnwS<KL literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/manifest.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d0ffb1ab51eccfb35d54aee5745e79ff02b5c078 GIT binary patch literal 10246 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 E52{9#y#N3J literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a8401a85338542fd9a5099a8e3f864e154f5dbe GIT binary patch literal 4432 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 Z)GV7o6+gbj+T7-Dt-a#@#AY1){{R}q0lfeK literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/metadata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d5ec318ea314745cdcdbcf5b0cdd43e16b25a65 GIT binary patch literal 27641 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/resources.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc3d40b677983aa86b2ea0c8d6b3ba35bd2319d6 GIT binary patch literal 10842 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/scripts.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8b6c47d185a2b8074d666c0b2f51fd69881a5a44 GIT binary patch literal 11018 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..01e28db3c1a65db9ef1d0c007a55b2c17e9afd82 GIT binary patch literal 47839 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 O4c|AsVfcN+WB(u3&3#Y+ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e02d0f94525aa46e76ea15478ebb32d58bee2efd GIT binary patch literal 20382 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/__pycache__/wheel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2cf888fbc8eb9421c15cf6bc12d3c20a0fe2c64 GIT binary patch literal 25032 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 N`<F_di91f@{{Sy~j;#Oy literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py new file mode 100644 index 0000000..f7dbf4c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__init__.py @@ -0,0 +1,6 @@ +"""Modules copied from Python 3 standard libraries, for internal use only. + +Individual classes and functions are found in d2._backport.misc. Intended +usage is to always import things missing from 3.1 from that module: the +built-in/stdlib objects will be used if found. +""" diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9b52fe63b13e4f8036c7992a507e561168b460d GIT binary patch literal 440 zcmX|8!A`?449#|csc09zz$c_h&<e&0A%wV~9Y9FjCZs4$(#<1HN}O)$*Kp>ScI7WP z;jRKpwrt1Ges&(F(@d}|KhNGyM?!q}!Jlv}?pbNV#)zdbqgOE-s}p{B3Z`|IK!*mc zfhvX?Ub?gn9_Bzvd848Mhh<a|EuBLZBA`z;dgY)c3&FcC&$5L#xJA=)Ry#$+JsAvD z>vh85If|CSE$7gKxyog!^m`Lx%4;N@11z|!H`Zh=sg(sJNCA}Fsg3~az7o<J{fdAA z#LmEWo?i}5TB`*0VV@hWv{~7rOBd)1N`^OpP;RVF1UqyNO53w%GS$E;&z@(a{jroL zXeqx$9P_ab=I60UbyGCha4$ZIa~FEI@|*N=-6sz!w@f|6!XPCcRs1hkNQoYklzG$b OC$|H=yQBU$Sj8{VOpA>G literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/misc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16a493d2eaaaaa331e3e2f786884b46e8ec08d63 GIT binary patch literal 1037 zcmZ8fOK%e~5cYU?lg;L#R^o9eLMtQ?k!W+_SRrV|0SV<oC18cL+SpFmc3;>|X{x}1 z_J7b`kdXK%`~zP(@fSETc2e>1YG%jdnejK@c(31&2(IMwy*J-ILVnoI)e6ygjH14w z;v^v)I4vLn_ooTv9`|`L^Ac~dfxcGZmq8K$c}c3<J`t^>NInN*Ki=aZ_s$^+UXzNx zB8yP8lQzcP$G8yVKCa_{cZyCKB@yOC+&?Etdz}#pIP4}}%(;a*J<R#C>?1<GQOj zPG68=|8%sMv7@GzTE){^#(Bl_<DAd4B4$OVlu&V2@pw9~n9l1;?fk?R$=GbNjJ*}< zRMusx>bYdXge)tHY*L^#Ria`w7ekN~!w;C%b|G`b+WRQ#8mcA8kV6x3`hhOVlHMeU z${QPC2I{Y9ChcaCPIIgpa50(Bj3-XCY-6fZzxGGEY(`DqZ0D8Ih+vz&pH+wY-9zhi zk{*kS*K)*jrHgzrN+;`<M`f<qPP1?zH!UO|6@eZM!G!zkb{JSEF8j9)IPms0XtE?4 z&Mc8I9#RwK%7LhukX<~-DqcM~{DW57ENN?Op(w`+{8QfoaP@c5xT-G)OQgl^=oyvw zmgK_I{zY&}E&=^54!XT0XK)zaK>Z20C6SI#x5P;!n2sk4jdR55DlH$xRjuQ@YS@uI zyut+T(0F)cTC1tyW}(dWnb4MZw6!SRNnXuN=U~x@r&89^_!><UrfHRxB26u4Ho@-x zZ`rnW2SwRC2}Izd45*Jp9}N4Zou<5IX=-S#q#cCyApPj^^0IOBG2LgSeW&hj$D!$r z@v0S;E~|?Id$n)WaWCzaX7EI7nNQ|=74{b__k!#=Ot@Rtd|rr0E!?RXl}|$mY2;DZ SfB|d-6hi#>=)k8IHv9&{a`zYj literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/shutil.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..29b1fe0dc780ceb45dfcdce2e9c65ee3695eedbe GIT binary patch literal 21353 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 QqBO~T-f7g5yrAO$1_rweTmS$7 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/sysconfig.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..938f077710ae5b3f31ebcc00becd8186a97d3dbe GIT binary patch literal 15818 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/__pycache__/tarfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dd9bc35504abe2fff5f3389d7ad118918f92fb4a GIT binary patch literal 62683 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py new file mode 100644 index 0000000..cfb318d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/misc.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Backports for individual classes and functions.""" + +import os +import sys + +__all__ = ['cache_from_source', 'callable', 'fsencode'] + + +try: + from imp import cache_from_source +except ImportError: + def cache_from_source(py_file, debug=__debug__): + ext = debug and 'c' or 'o' + return py_file + ext + + +try: + callable = callable +except NameError: + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode +except AttributeError: + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, str): + return filename.encode(sys.getfilesystemencoding()) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py new file mode 100644 index 0000000..159e49e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/shutil.py @@ -0,0 +1,761 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Utility functions for copying and archiving files and directory trees. + +XXX The functions here don't copy the resource fork or other metadata on Mac. + +""" + +import os +import sys +import stat +from os.path import abspath +import fnmatch +import collections +import errno +from . import tarfile + +try: + import bz2 + _BZ2_SUPPORTED = True +except ImportError: + _BZ2_SUPPORTED = False + +try: + from pwd import getpwnam +except ImportError: + getpwnam = None + +try: + from grp import getgrnam +except ImportError: + getgrnam = None + +__all__ = ["copyfileobj", "copyfile", "copymode", "copystat", "copy", "copy2", + "copytree", "move", "rmtree", "Error", "SpecialFileError", + "ExecError", "make_archive", "get_archive_formats", + "register_archive_format", "unregister_archive_format", + "get_unpack_formats", "register_unpack_format", + "unregister_unpack_format", "unpack_archive", "ignore_patterns"] + +class Error(EnvironmentError): + pass + +class SpecialFileError(EnvironmentError): + """Raised when trying to do a kind of operation (e.g. copying) which is + not supported on a special file (e.g. a named pipe)""" + +class ExecError(EnvironmentError): + """Raised when a command could not be executed""" + +class ReadError(EnvironmentError): + """Raised when an archive cannot be read""" + +class RegistryError(Exception): + """Raised when a registry operation with the archiving + and unpacking registries fails""" + + +try: + WindowsError +except NameError: + WindowsError = None + +def copyfileobj(fsrc, fdst, length=16*1024): + """copy data from file-like object fsrc to file-like object fdst""" + while 1: + buf = fsrc.read(length) + if not buf: + break + fdst.write(buf) + +def _samefile(src, dst): + # Macintosh, Unix. + if hasattr(os.path, 'samefile'): + try: + return os.path.samefile(src, dst) + except OSError: + return False + + # All other platforms: check for same pathname. + return (os.path.normcase(os.path.abspath(src)) == + os.path.normcase(os.path.abspath(dst))) + +def copyfile(src, dst): + """Copy data from src to dst""" + if _samefile(src, dst): + raise Error("`%s` and `%s` are the same file" % (src, dst)) + + for fn in [src, dst]: + try: + st = os.stat(fn) + except OSError: + # File most likely does not exist + pass + else: + # XXX What about other special files? (sockets, devices...) + if stat.S_ISFIFO(st.st_mode): + raise SpecialFileError("`%s` is a named pipe" % fn) + + with open(src, 'rb') as fsrc: + with open(dst, 'wb') as fdst: + copyfileobj(fsrc, fdst) + +def copymode(src, dst): + """Copy mode bits from src to dst""" + if hasattr(os, 'chmod'): + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + os.chmod(dst, mode) + +def copystat(src, dst): + """Copy all stat info (mode bits, atime, mtime, flags) from src to dst""" + st = os.stat(src) + mode = stat.S_IMODE(st.st_mode) + if hasattr(os, 'utime'): + os.utime(dst, (st.st_atime, st.st_mtime)) + if hasattr(os, 'chmod'): + os.chmod(dst, mode) + if hasattr(os, 'chflags') and hasattr(st, 'st_flags'): + try: + os.chflags(dst, st.st_flags) + except OSError as why: + if (not hasattr(errno, 'EOPNOTSUPP') or + why.errno != errno.EOPNOTSUPP): + raise + +def copy(src, dst): + """Copy data and mode bits ("cp src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copymode(src, dst) + +def copy2(src, dst): + """Copy data and all stat info ("cp -p src dst"). + + The destination may be a directory. + + """ + if os.path.isdir(dst): + dst = os.path.join(dst, os.path.basename(src)) + copyfile(src, dst) + copystat(src, dst) + +def ignore_patterns(*patterns): + """Function that can be used as copytree() ignore parameter. + + Patterns is a sequence of glob-style patterns + that are used to exclude files""" + def _ignore_patterns(path, names): + ignored_names = [] + for pattern in patterns: + ignored_names.extend(fnmatch.filter(names, pattern)) + return set(ignored_names) + return _ignore_patterns + +def copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks=False): + """Recursively copy a directory tree. + + The destination directory must not already exist. + If exception(s) occur, an Error is raised with a list of reasons. + + If the optional symlinks flag is true, symbolic links in the + source tree result in symbolic links in the destination tree; if + it is false, the contents of the files pointed to by symbolic + links are copied. If the file pointed by the symlink doesn't + exist, an exception will be added in the list of errors raised in + an Error exception at the end of the copy process. + + You can set the optional ignore_dangling_symlinks flag to true if you + want to silence this exception. Notice that this has no effect on + platforms that don't support os.symlink. + + The optional ignore argument is a callable. If given, it + is called with the `src` parameter, which is the directory + being visited by copytree(), and `names` which is the list of + `src` contents, as returned by os.listdir(): + + callable(src, names) -> ignored_names + + Since copytree() is called recursively, the callable will be + called once for each directory that is copied. It returns a + list of names relative to the `src` directory that should + not be copied. + + The optional copy_function argument is a callable that will be used + to copy each file. It will be called with the source path and the + destination path as arguments. By default, copy2() is used, but any + function that supports the same signature (like copy()) can be used. + + """ + names = os.listdir(src) + if ignore is not None: + ignored_names = ignore(src, names) + else: + ignored_names = set() + + os.makedirs(dst) + errors = [] + for name in names: + if name in ignored_names: + continue + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.islink(srcname): + linkto = os.readlink(srcname) + if symlinks: + os.symlink(linkto, dstname) + else: + # ignore dangling symlink if the flag is on + if not os.path.exists(linkto) and ignore_dangling_symlinks: + continue + # otherwise let the copy occurs. copy2 will raise an error + copy_function(srcname, dstname) + elif os.path.isdir(srcname): + copytree(srcname, dstname, symlinks, ignore, copy_function) + else: + # Will raise a SpecialFileError for unsupported file types + copy_function(srcname, dstname) + # catch the Error from the recursive copytree so that we can + # continue with other files + except Error as err: + errors.extend(err.args[0]) + except EnvironmentError as why: + errors.append((srcname, dstname, str(why))) + try: + copystat(src, dst) + except OSError as why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise Error(errors) + +def rmtree(path, ignore_errors=False, onerror=None): + """Recursively delete a directory tree. + + If ignore_errors is set, errors are ignored; otherwise, if onerror + is set, it is called to handle the error with arguments (func, + path, exc_info) where func is os.listdir, os.remove, or os.rmdir; + path is the argument to that function that caused it to fail; and + exc_info is a tuple returned by sys.exc_info(). If ignore_errors + is false and onerror is None, an exception is raised. + + """ + if ignore_errors: + def onerror(*args): + pass + elif onerror is None: + def onerror(*args): + raise + try: + if os.path.islink(path): + # symlinks to directories are forbidden, see bug #1669 + raise OSError("Cannot call rmtree on a symbolic link") + except OSError: + onerror(os.path.islink, path, sys.exc_info()) + # can't continue even if onerror hook returns + return + names = [] + try: + names = os.listdir(path) + except os.error: + onerror(os.listdir, path, sys.exc_info()) + for name in names: + fullname = os.path.join(path, name) + try: + mode = os.lstat(fullname).st_mode + except os.error: + mode = 0 + if stat.S_ISDIR(mode): + rmtree(fullname, ignore_errors, onerror) + else: + try: + os.remove(fullname) + except os.error: + onerror(os.remove, fullname, sys.exc_info()) + try: + os.rmdir(path) + except os.error: + onerror(os.rmdir, path, sys.exc_info()) + + +def _basename(path): + # A basename() variant which first strips the trailing slash, if present. + # Thus we always get the last component of the path, even for directories. + return os.path.basename(path.rstrip(os.path.sep)) + +def move(src, dst): + """Recursively move a file or directory to another location. This is + similar to the Unix "mv" command. + + If the destination is a directory or a symlink to a directory, the source + is moved inside the directory. The destination path must not already + exist. + + If the destination already exists but is not a directory, it may be + overwritten depending on os.rename() semantics. + + If the destination is on our current filesystem, then rename() is used. + Otherwise, src is copied to the destination and then removed. + A lot more could be done here... A look at a mv.c shows a lot of + the issues this implementation glosses over. + + """ + real_dst = dst + if os.path.isdir(dst): + if _samefile(src, dst): + # We might be on a case insensitive filesystem, + # perform the rename anyway. + os.rename(src, dst) + return + + real_dst = os.path.join(dst, _basename(src)) + if os.path.exists(real_dst): + raise Error("Destination path '%s' already exists" % real_dst) + try: + os.rename(src, real_dst) + except OSError: + if os.path.isdir(src): + if _destinsrc(src, dst): + raise Error("Cannot move a directory '%s' into itself '%s'." % (src, dst)) + copytree(src, real_dst, symlinks=True) + rmtree(src) + else: + copy2(src, real_dst) + os.unlink(src) + +def _destinsrc(src, dst): + src = abspath(src) + dst = abspath(dst) + if not src.endswith(os.path.sep): + src += os.path.sep + if not dst.endswith(os.path.sep): + dst += os.path.sep + return dst.startswith(src) + +def _get_gid(name): + """Returns a gid, given a group name.""" + if getgrnam is None or name is None: + return None + try: + result = getgrnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _get_uid(name): + """Returns an uid, given a user name.""" + if getpwnam is None or name is None: + return None + try: + result = getpwnam(name) + except KeyError: + result = None + if result is not None: + return result[2] + return None + +def _make_tarball(base_name, base_dir, compress="gzip", verbose=0, dry_run=0, + owner=None, group=None, logger=None): + """Create a (possibly compressed) tar file from all the files under + 'base_dir'. + + 'compress' must be "gzip" (the default), "bzip2", or None. + + 'owner' and 'group' can be used to define an owner and a group for the + archive that is being built. If not provided, the current owner and group + will be used. + + The output tar file will be named 'base_name' + ".tar", possibly plus + the appropriate compression extension (".gz", or ".bz2"). + + Returns the output filename. + """ + tar_compression = {'gzip': 'gz', None: ''} + compress_ext = {'gzip': '.gz'} + + if _BZ2_SUPPORTED: + tar_compression['bzip2'] = 'bz2' + compress_ext['bzip2'] = '.bz2' + + # flags for compression program, each element of list will be an argument + if compress is not None and compress not in compress_ext: + raise ValueError("bad value for 'compress', or compression format not " + "supported : {0}".format(compress)) + + archive_name = base_name + '.tar' + compress_ext.get(compress, '') + archive_dir = os.path.dirname(archive_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # creating the tarball + if logger is not None: + logger.info('Creating tar archive') + + uid = _get_uid(owner) + gid = _get_gid(group) + + def _set_uid_gid(tarinfo): + if gid is not None: + tarinfo.gid = gid + tarinfo.gname = group + if uid is not None: + tarinfo.uid = uid + tarinfo.uname = owner + return tarinfo + + if not dry_run: + tar = tarfile.open(archive_name, 'w|%s' % tar_compression[compress]) + try: + tar.add(base_dir, filter=_set_uid_gid) + finally: + tar.close() + + return archive_name + +def _call_external_zip(base_dir, zip_filename, verbose=False, dry_run=False): + # XXX see if we want to keep an external call here + if verbose: + zipoptions = "-r" + else: + zipoptions = "-rq" + from distutils.errors import DistutilsExecError + from distutils.spawn import spawn + try: + spawn(["zip", zipoptions, zip_filename, base_dir], dry_run=dry_run) + except DistutilsExecError: + # XXX really should distinguish between "couldn't find + # external 'zip' command" and "zip failed". + raise ExecError("unable to create zip file '%s': " + "could neither import the 'zipfile' module nor " + "find a standalone zip utility") % zip_filename + +def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None): + """Create a zip file from all the files under 'base_dir'. + + The output zip file will be named 'base_name' + ".zip". Uses either the + "zipfile" Python module (if available) or the InfoZIP "zip" utility + (if installed and found on the default search path). If neither tool is + available, raises ExecError. Returns the name of the output zip + file. + """ + zip_filename = base_name + ".zip" + archive_dir = os.path.dirname(base_name) + + if not os.path.exists(archive_dir): + if logger is not None: + logger.info("creating %s", archive_dir) + if not dry_run: + os.makedirs(archive_dir) + + # If zipfile module is not available, try spawning an external 'zip' + # command. + try: + import zipfile + except ImportError: + zipfile = None + + if zipfile is None: + _call_external_zip(base_dir, zip_filename, verbose, dry_run) + else: + if logger is not None: + logger.info("creating '%s' and adding '%s' to it", + zip_filename, base_dir) + + if not dry_run: + zip = zipfile.ZipFile(zip_filename, "w", + compression=zipfile.ZIP_DEFLATED) + + for dirpath, dirnames, filenames in os.walk(base_dir): + for name in filenames: + path = os.path.normpath(os.path.join(dirpath, name)) + if os.path.isfile(path): + zip.write(path, path) + if logger is not None: + logger.info("adding '%s'", path) + zip.close() + + return zip_filename + +_ARCHIVE_FORMATS = { + 'gztar': (_make_tarball, [('compress', 'gzip')], "gzip'ed tar-file"), + 'bztar': (_make_tarball, [('compress', 'bzip2')], "bzip2'ed tar-file"), + 'tar': (_make_tarball, [('compress', None)], "uncompressed tar file"), + 'zip': (_make_zipfile, [], "ZIP file"), + } + +if _BZ2_SUPPORTED: + _ARCHIVE_FORMATS['bztar'] = (_make_tarball, [('compress', 'bzip2')], + "bzip2'ed tar-file") + +def get_archive_formats(): + """Returns a list of supported formats for archiving and unarchiving. + + Each element of the returned sequence is a tuple (name, description) + """ + formats = [(name, registry[2]) for name, registry in + _ARCHIVE_FORMATS.items()] + formats.sort() + return formats + +def register_archive_format(name, function, extra_args=None, description=''): + """Registers an archive format. + + name is the name of the format. function is the callable that will be + used to create archives. If provided, extra_args is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_archive_formats() function. + """ + if extra_args is None: + extra_args = [] + if not isinstance(function, collections.Callable): + raise TypeError('The %s object is not callable' % function) + if not isinstance(extra_args, (tuple, list)): + raise TypeError('extra_args needs to be a sequence') + for element in extra_args: + if not isinstance(element, (tuple, list)) or len(element) !=2: + raise TypeError('extra_args elements are : (arg_name, value)') + + _ARCHIVE_FORMATS[name] = (function, extra_args, description) + +def unregister_archive_format(name): + del _ARCHIVE_FORMATS[name] + +def make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, + dry_run=0, owner=None, group=None, logger=None): + """Create an archive file (eg. zip or tar). + + 'base_name' is the name of the file to create, minus any format-specific + extension; 'format' is the archive format: one of "zip", "tar", "bztar" + or "gztar". + + 'root_dir' is a directory that will be the root directory of the + archive; ie. we typically chdir into 'root_dir' before creating the + archive. 'base_dir' is the directory where we start archiving from; + ie. 'base_dir' will be the common prefix of all files and + directories in the archive. 'root_dir' and 'base_dir' both default + to the current directory. Returns the name of the archive file. + + 'owner' and 'group' are used when creating a tar archive. By default, + uses the current owner and group. + """ + save_cwd = os.getcwd() + if root_dir is not None: + if logger is not None: + logger.debug("changing into '%s'", root_dir) + base_name = os.path.abspath(base_name) + if not dry_run: + os.chdir(root_dir) + + if base_dir is None: + base_dir = os.curdir + + kwargs = {'dry_run': dry_run, 'logger': logger} + + try: + format_info = _ARCHIVE_FORMATS[format] + except KeyError: + raise ValueError("unknown archive format '%s'" % format) + + func = format_info[0] + for arg, val in format_info[1]: + kwargs[arg] = val + + if format != 'zip': + kwargs['owner'] = owner + kwargs['group'] = group + + try: + filename = func(base_name, base_dir, **kwargs) + finally: + if root_dir is not None: + if logger is not None: + logger.debug("changing back to '%s'", save_cwd) + os.chdir(save_cwd) + + return filename + + +def get_unpack_formats(): + """Returns a list of supported formats for unpacking. + + Each element of the returned sequence is a tuple + (name, extensions, description) + """ + formats = [(name, info[0], info[3]) for name, info in + _UNPACK_FORMATS.items()] + formats.sort() + return formats + +def _check_unpack_options(extensions, function, extra_args): + """Checks what gets registered as an unpacker.""" + # first make sure no other unpacker is registered for this extension + existing_extensions = {} + for name, info in _UNPACK_FORMATS.items(): + for ext in info[0]: + existing_extensions[ext] = name + + for extension in extensions: + if extension in existing_extensions: + msg = '%s is already registered for "%s"' + raise RegistryError(msg % (extension, + existing_extensions[extension])) + + if not isinstance(function, collections.Callable): + raise TypeError('The registered function must be a callable') + + +def register_unpack_format(name, extensions, function, extra_args=None, + description=''): + """Registers an unpack format. + + `name` is the name of the format. `extensions` is a list of extensions + corresponding to the format. + + `function` is the callable that will be + used to unpack archives. The callable will receive archives to unpack. + If it's unable to handle an archive, it needs to raise a ReadError + exception. + + If provided, `extra_args` is a sequence of + (name, value) tuples that will be passed as arguments to the callable. + description can be provided to describe the format, and will be returned + by the get_unpack_formats() function. + """ + if extra_args is None: + extra_args = [] + _check_unpack_options(extensions, function, extra_args) + _UNPACK_FORMATS[name] = extensions, function, extra_args, description + +def unregister_unpack_format(name): + """Removes the pack format from the registry.""" + del _UNPACK_FORMATS[name] + +def _ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + if not os.path.isdir(dirname): + os.makedirs(dirname) + +def _unpack_zipfile(filename, extract_dir): + """Unpack zip `filename` to `extract_dir` + """ + try: + import zipfile + except ImportError: + raise ReadError('zlib not supported, cannot unpack this archive.') + + if not zipfile.is_zipfile(filename): + raise ReadError("%s is not a zip file" % filename) + + zip = zipfile.ZipFile(filename) + try: + for info in zip.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name: + continue + + target = os.path.join(extract_dir, *name.split('/')) + if not target: + continue + + _ensure_directory(target) + if not name.endswith('/'): + # file + data = zip.read(info.filename) + f = open(target, 'wb') + try: + f.write(data) + finally: + f.close() + del data + finally: + zip.close() + +def _unpack_tarfile(filename, extract_dir): + """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + """ + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise ReadError( + "%s is not a compressed or uncompressed tar file" % filename) + try: + tarobj.extractall(extract_dir) + finally: + tarobj.close() + +_UNPACK_FORMATS = { + 'gztar': (['.tar.gz', '.tgz'], _unpack_tarfile, [], "gzip'ed tar-file"), + 'tar': (['.tar'], _unpack_tarfile, [], "uncompressed tar file"), + 'zip': (['.zip'], _unpack_zipfile, [], "ZIP file") + } + +if _BZ2_SUPPORTED: + _UNPACK_FORMATS['bztar'] = (['.bz2'], _unpack_tarfile, [], + "bzip2'ed tar-file") + +def _find_unpack_format(filename): + for name, info in _UNPACK_FORMATS.items(): + for extension in info[0]: + if filename.endswith(extension): + return name + return None + +def unpack_archive(filename, extract_dir=None, format=None): + """Unpack an archive. + + `filename` is the name of the archive. + + `extract_dir` is the name of the target directory, where the archive + is unpacked. If not provided, the current working directory is used. + + `format` is the archive format: one of "zip", "tar", or "gztar". Or any + other registered format. If not provided, unpack_archive will use the + filename extension and see if an unpacker was registered for that + extension. + + In case none is found, a ValueError is raised. + """ + if extract_dir is None: + extract_dir = os.getcwd() + + if format is not None: + try: + format_info = _UNPACK_FORMATS[format] + except KeyError: + raise ValueError("Unknown unpack format '{0}'".format(format)) + + func = format_info[1] + func(filename, extract_dir, **dict(format_info[2])) + else: + # we need to look at the registered unpackers supported extensions + format = _find_unpack_format(filename) + if format is None: + raise ReadError("Unknown archive format '{0}'".format(filename)) + + func = _UNPACK_FORMATS[format][1] + kwargs = dict(_UNPACK_FORMATS[format][2]) + func(filename, extract_dir, **kwargs) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg new file mode 100644 index 0000000..1746bd0 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.cfg @@ -0,0 +1,84 @@ +[posix_prefix] +# Configuration directories. Some of these come straight out of the +# configure script. They are for implementing the other variables, not to +# be used directly in [resource_locations]. +confdir = /etc +datadir = /usr/share +libdir = /usr/lib +statedir = /var +# User resource directory +local = ~/.local/{distribution.name} + +stdlib = {base}/lib/python{py_version_short} +platstdlib = {platbase}/lib/python{py_version_short} +purelib = {base}/lib/python{py_version_short}/site-packages +platlib = {platbase}/lib/python{py_version_short}/site-packages +include = {base}/include/python{py_version_short}{abiflags} +platinclude = {platbase}/include/python{py_version_short}{abiflags} +data = {base} + +[posix_home] +stdlib = {base}/lib/python +platstdlib = {base}/lib/python +purelib = {base}/lib/python +platlib = {base}/lib/python +include = {base}/include/python +platinclude = {base}/include/python +scripts = {base}/bin +data = {base} + +[nt] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2] +stdlib = {base}/Lib +platstdlib = {base}/Lib +purelib = {base}/Lib/site-packages +platlib = {base}/Lib/site-packages +include = {base}/Include +platinclude = {base}/Include +scripts = {base}/Scripts +data = {base} + +[os2_home] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[nt_user] +stdlib = {userbase}/Python{py_version_nodot} +platstdlib = {userbase}/Python{py_version_nodot} +purelib = {userbase}/Python{py_version_nodot}/site-packages +platlib = {userbase}/Python{py_version_nodot}/site-packages +include = {userbase}/Python{py_version_nodot}/Include +scripts = {userbase}/Scripts +data = {userbase} + +[posix_user] +stdlib = {userbase}/lib/python{py_version_short} +platstdlib = {userbase}/lib/python{py_version_short} +purelib = {userbase}/lib/python{py_version_short}/site-packages +platlib = {userbase}/lib/python{py_version_short}/site-packages +include = {userbase}/include/python{py_version_short} +scripts = {userbase}/bin +data = {userbase} + +[osx_framework_user] +stdlib = {userbase}/lib/python +platstdlib = {userbase}/lib/python +purelib = {userbase}/lib/python/site-packages +platlib = {userbase}/lib/python/site-packages +include = {userbase}/include +scripts = {userbase}/bin +data = {userbase} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py new file mode 100644 index 0000000..1df3aba --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/sysconfig.py @@ -0,0 +1,788 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Access to Python's configuration information.""" + +import codecs +import os +import re +import sys +from os.path import pardir, realpath +try: + import configparser +except ImportError: + import ConfigParser as configparser + + +__all__ = [ + 'get_config_h_filename', + 'get_config_var', + 'get_config_vars', + 'get_makefile_filename', + 'get_path', + 'get_path_names', + 'get_paths', + 'get_platform', + 'get_python_version', + 'get_scheme_names', + 'parse_config_h', +] + + +def _safe_realpath(path): + try: + return realpath(path) + except OSError: + return path + + +if sys.executable: + _PROJECT_BASE = os.path.dirname(_safe_realpath(sys.executable)) +else: + # sys.executable can be empty if argv[0] has been changed and Python is + # unable to retrieve the real program name + _PROJECT_BASE = _safe_realpath(os.getcwd()) + +if os.name == "nt" and "pcbuild" in _PROJECT_BASE[-8:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir)) +# PC/VS7.1 +if os.name == "nt" and "\\pc\\v" in _PROJECT_BASE[-10:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) +# PC/AMD64 +if os.name == "nt" and "\\pcbuild\\amd64" in _PROJECT_BASE[-14:].lower(): + _PROJECT_BASE = _safe_realpath(os.path.join(_PROJECT_BASE, pardir, pardir)) + + +def is_python_build(): + for fn in ("Setup.dist", "Setup.local"): + if os.path.isfile(os.path.join(_PROJECT_BASE, "Modules", fn)): + return True + return False + +_PYTHON_BUILD = is_python_build() + +_cfg_read = False + +def _ensure_cfg_read(): + global _cfg_read + if not _cfg_read: + from ..resources import finder + backport_package = __name__.rsplit('.', 1)[0] + _finder = finder(backport_package) + _cfgfile = _finder.find('sysconfig.cfg') + assert _cfgfile, 'sysconfig.cfg exists' + with _cfgfile.as_stream() as s: + _SCHEMES.readfp(s) + if _PYTHON_BUILD: + for scheme in ('posix_prefix', 'posix_home'): + _SCHEMES.set(scheme, 'include', '{srcdir}/Include') + _SCHEMES.set(scheme, 'platinclude', '{projectbase}/.') + + _cfg_read = True + + +_SCHEMES = configparser.RawConfigParser() +_VAR_REPL = re.compile(r'\{([^{]*?)\}') + +def _expand_globals(config): + _ensure_cfg_read() + if config.has_section('globals'): + globals = config.items('globals') + else: + globals = tuple() + + sections = config.sections() + for section in sections: + if section == 'globals': + continue + for option, value in globals: + if config.has_option(section, option): + continue + config.set(section, option, value) + config.remove_section('globals') + + # now expanding local variables defined in the cfg file + # + for section in config.sections(): + variables = dict(config.items(section)) + + def _replacer(matchobj): + name = matchobj.group(1) + if name in variables: + return variables[name] + return matchobj.group(0) + + for option, value in config.items(section): + config.set(section, option, _VAR_REPL.sub(_replacer, value)) + +#_expand_globals(_SCHEMES) + + # FIXME don't rely on sys.version here, its format is an implementation detail + # of CPython, use sys.version_info or sys.hexversion +_PY_VERSION = sys.version.split()[0] +_PY_VERSION_SHORT = sys.version[:3] +_PY_VERSION_SHORT_NO_DOT = _PY_VERSION[0] + _PY_VERSION[2] +_PREFIX = os.path.normpath(sys.prefix) +_EXEC_PREFIX = os.path.normpath(sys.exec_prefix) +_CONFIG_VARS = None +_USER_BASE = None + + +def _subst_vars(path, local_vars): + """In the string `path`, replace tokens like {some.thing} with the + corresponding value from the map `local_vars`. + + If there is no corresponding value, leave the token unchanged. + """ + def _replacer(matchobj): + name = matchobj.group(1) + if name in local_vars: + return local_vars[name] + elif name in os.environ: + return os.environ[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, path) + + +def _extend_dict(target_dict, other_dict): + target_keys = target_dict.keys() + for key, value in other_dict.items(): + if key in target_keys: + continue + target_dict[key] = value + + +def _expand_vars(scheme, vars): + res = {} + if vars is None: + vars = {} + _extend_dict(vars, get_config_vars()) + + for key, value in _SCHEMES.items(scheme): + if os.name in ('posix', 'nt'): + value = os.path.expanduser(value) + res[key] = os.path.normpath(_subst_vars(value, vars)) + return res + + +def format_value(value, vars): + def _replacer(matchobj): + name = matchobj.group(1) + if name in vars: + return vars[name] + return matchobj.group(0) + return _VAR_REPL.sub(_replacer, value) + + +def _get_default_scheme(): + if os.name == 'posix': + # the default scheme for posix is posix_prefix + return 'posix_prefix' + return os.name + + +def _getuserbase(): + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + # what about 'os2emx', 'riscos' ? + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + if env_base: + return env_base + else: + return joinuser(base, "Python") + + if sys.platform == "darwin": + framework = get_config_var("PYTHONFRAMEWORK") + if framework: + if env_base: + return env_base + else: + return joinuser("~", "Library", framework, "%d.%d" % + sys.version_info[:2]) + + if env_base: + return env_base + else: + return joinuser("~", ".local") + + +def _parse_makefile(filename, vars=None): + """Parse a Makefile-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + # Regexes needed for parsing Makefile (and similar syntaxes, + # like old-style Setup files). + _variable_rx = re.compile(r"([a-zA-Z][a-zA-Z0-9_]+)\s*=\s*(.*)") + _findvar1_rx = re.compile(r"\$\(([A-Za-z][A-Za-z0-9_]*)\)") + _findvar2_rx = re.compile(r"\${([A-Za-z][A-Za-z0-9_]*)}") + + if vars is None: + vars = {} + done = {} + notdone = {} + + with codecs.open(filename, encoding='utf-8', errors="surrogateescape") as f: + lines = f.readlines() + + for line in lines: + if line.startswith('#') or line.strip() == '': + continue + m = _variable_rx.match(line) + if m: + n, v = m.group(1, 2) + v = v.strip() + # `$$' is a literal `$' in make + tmpv = v.replace('$$', '') + + if "$" in tmpv: + notdone[n] = v + else: + try: + v = int(v) + except ValueError: + # insert literal `$' + done[n] = v.replace('$$', '$') + else: + done[n] = v + + # do variable interpolation here + variables = list(notdone.keys()) + + # Variables with a 'PY_' prefix in the makefile. These need to + # be made available without that prefix through sysconfig. + # Special care is needed to ensure that variable expansion works, even + # if the expansion uses the name without a prefix. + renamed_variables = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS') + + while len(variables) > 0: + for name in tuple(variables): + value = notdone[name] + m = _findvar1_rx.search(value) or _findvar2_rx.search(value) + if m is not None: + n = m.group(1) + found = True + if n in done: + item = str(done[n]) + elif n in notdone: + # get it on a subsequent round + found = False + elif n in os.environ: + # do it like make: fall back to environment + item = os.environ[n] + + elif n in renamed_variables: + if (name.startswith('PY_') and + name[3:] in renamed_variables): + item = "" + + elif 'PY_' + n in notdone: + found = False + + else: + item = str(done['PY_' + n]) + + else: + done[n] = item = "" + + if found: + after = value[m.end():] + value = value[:m.start()] + item + after + if "$" in after: + notdone[name] = value + else: + try: + value = int(value) + except ValueError: + done[name] = value.strip() + else: + done[name] = value + variables.remove(name) + + if (name.startswith('PY_') and + name[3:] in renamed_variables): + + name = name[3:] + if name not in done: + done[name] = value + + else: + # bogus variable reference (e.g. "prefix=$/opt/python"); + # just drop it since we can't deal + done[name] = value + variables.remove(name) + + # strip spurious spaces + for k, v in done.items(): + if isinstance(v, str): + done[k] = v.strip() + + # save the results in the global dictionary + vars.update(done) + return vars + + +def get_makefile_filename(): + """Return the path of the Makefile.""" + if _PYTHON_BUILD: + return os.path.join(_PROJECT_BASE, "Makefile") + if hasattr(sys, 'abiflags'): + config_dir_name = 'config-%s%s' % (_PY_VERSION_SHORT, sys.abiflags) + else: + config_dir_name = 'config' + return os.path.join(get_path('stdlib'), config_dir_name, 'Makefile') + + +def _init_posix(vars): + """Initialize the module as appropriate for POSIX systems.""" + # load the installed Makefile: + makefile = get_makefile_filename() + try: + _parse_makefile(makefile, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % makefile + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # load the installed pyconfig.h: + config_h = get_config_h_filename() + try: + with open(config_h) as f: + parse_config_h(f, vars) + except IOError as e: + msg = "invalid Python installation: unable to open %s" % config_h + if hasattr(e, "strerror"): + msg = msg + " (%s)" % e.strerror + raise IOError(msg) + # On AIX, there are wrong paths to the linker scripts in the Makefile + # -- these paths are relative to the Python source, but when installed + # the scripts are in another directory. + if _PYTHON_BUILD: + vars['LDSHARED'] = vars['BLDSHARED'] + + +def _init_non_posix(vars): + """Initialize the module as appropriate for NT""" + # set basic install directories + vars['LIBDEST'] = get_path('stdlib') + vars['BINLIBDEST'] = get_path('platstdlib') + vars['INCLUDEPY'] = get_path('include') + vars['SO'] = '.pyd' + vars['EXE'] = '.exe' + vars['VERSION'] = _PY_VERSION_SHORT_NO_DOT + vars['BINDIR'] = os.path.dirname(_safe_realpath(sys.executable)) + +# +# public APIs +# + + +def parse_config_h(fp, vars=None): + """Parse a config.h-style file. + + A dictionary containing name/value pairs is returned. If an + optional dictionary is passed in as the second argument, it is + used instead of a new dictionary. + """ + if vars is None: + vars = {} + define_rx = re.compile("#define ([A-Z][A-Za-z0-9_]+) (.*)\n") + undef_rx = re.compile("/[*] #undef ([A-Z][A-Za-z0-9_]+) [*]/\n") + + while True: + line = fp.readline() + if not line: + break + m = define_rx.match(line) + if m: + n, v = m.group(1, 2) + try: + v = int(v) + except ValueError: + pass + vars[n] = v + else: + m = undef_rx.match(line) + if m: + vars[m.group(1)] = 0 + return vars + + +def get_config_h_filename(): + """Return the path of pyconfig.h.""" + if _PYTHON_BUILD: + if os.name == "nt": + inc_dir = os.path.join(_PROJECT_BASE, "PC") + else: + inc_dir = _PROJECT_BASE + else: + inc_dir = get_path('platinclude') + return os.path.join(inc_dir, 'pyconfig.h') + + +def get_scheme_names(): + """Return a tuple containing the schemes names.""" + return tuple(sorted(_SCHEMES.sections())) + + +def get_path_names(): + """Return a tuple containing the paths names.""" + # xxx see if we want a static list + return _SCHEMES.options('posix_prefix') + + +def get_paths(scheme=_get_default_scheme(), vars=None, expand=True): + """Return a mapping containing an install scheme. + + ``scheme`` is the install scheme name. If not provided, it will + return the default scheme for the current platform. + """ + _ensure_cfg_read() + if expand: + return _expand_vars(scheme, vars) + else: + return dict(_SCHEMES.items(scheme)) + + +def get_path(name, scheme=_get_default_scheme(), vars=None, expand=True): + """Return a path corresponding to the scheme. + + ``scheme`` is the install scheme name. + """ + return get_paths(scheme, vars, expand)[name] + + +def get_config_vars(*args): + """With no arguments, return a dictionary of all configuration + variables relevant for the current platform. + + On Unix, this means every variable defined in Python's installed Makefile; + On Windows and Mac OS it's a much smaller set. + + With arguments, return a list of values that result from looking up + each argument in the configuration variable dictionary. + """ + global _CONFIG_VARS + if _CONFIG_VARS is None: + _CONFIG_VARS = {} + # Normalized versions of prefix and exec_prefix are handy to have; + # in fact, these are the standard versions used most places in the + # distutils2 module. + _CONFIG_VARS['prefix'] = _PREFIX + _CONFIG_VARS['exec_prefix'] = _EXEC_PREFIX + _CONFIG_VARS['py_version'] = _PY_VERSION + _CONFIG_VARS['py_version_short'] = _PY_VERSION_SHORT + _CONFIG_VARS['py_version_nodot'] = _PY_VERSION[0] + _PY_VERSION[2] + _CONFIG_VARS['base'] = _PREFIX + _CONFIG_VARS['platbase'] = _EXEC_PREFIX + _CONFIG_VARS['projectbase'] = _PROJECT_BASE + try: + _CONFIG_VARS['abiflags'] = sys.abiflags + except AttributeError: + # sys.abiflags may not be defined on all platforms. + _CONFIG_VARS['abiflags'] = '' + + if os.name in ('nt', 'os2'): + _init_non_posix(_CONFIG_VARS) + if os.name == 'posix': + _init_posix(_CONFIG_VARS) + # Setting 'userbase' is done below the call to the + # init function to enable using 'get_config_var' in + # the init-function. + if sys.version >= '2.6': + _CONFIG_VARS['userbase'] = _getuserbase() + + if 'srcdir' not in _CONFIG_VARS: + _CONFIG_VARS['srcdir'] = _PROJECT_BASE + else: + _CONFIG_VARS['srcdir'] = _safe_realpath(_CONFIG_VARS['srcdir']) + + # Convert srcdir into an absolute path if it appears necessary. + # Normally it is relative to the build directory. However, during + # testing, for example, we might be running a non-installed python + # from a different directory. + if _PYTHON_BUILD and os.name == "posix": + base = _PROJECT_BASE + try: + cwd = os.getcwd() + except OSError: + cwd = None + if (not os.path.isabs(_CONFIG_VARS['srcdir']) and + base != cwd): + # srcdir is relative and we are not in the same directory + # as the executable. Assume executable is in the build + # directory and make srcdir absolute. + srcdir = os.path.join(base, _CONFIG_VARS['srcdir']) + _CONFIG_VARS['srcdir'] = os.path.normpath(srcdir) + + if sys.platform == 'darwin': + kernel_version = os.uname()[2] # Kernel version (8.4.3) + major_version = int(kernel_version.split('.')[0]) + + if major_version < 8: + # On Mac OS X before 10.4, check if -arch and -isysroot + # are in CFLAGS or LDFLAGS and remove them if they are. + # This is needed when building extensions on a 10.3 system + # using a universal build of python. + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = re.sub('-isysroot [^ \t]*', ' ', flags) + _CONFIG_VARS[key] = flags + else: + # Allow the user to override the architecture flags using + # an environment variable. + # NOTE: This name was introduced by Apple in OSX 10.5 and + # is used by several scripting languages distributed with + # that OS release. + if 'ARCHFLAGS' in os.environ: + arch = os.environ['ARCHFLAGS'] + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-arch\s+\w+\s', ' ', flags) + flags = flags + ' ' + arch + _CONFIG_VARS[key] = flags + + # If we're on OSX 10.5 or later and the user tries to + # compiles an extension using an SDK that is not present + # on the current machine it is better to not use an SDK + # than to fail. + # + # The major usecase for this is users using a Python.org + # binary installer on OSX 10.6: that installer uses + # the 10.4u SDK, but that SDK is not installed by default + # when you install Xcode. + # + CFLAGS = _CONFIG_VARS.get('CFLAGS', '') + m = re.search(r'-isysroot\s+(\S+)', CFLAGS) + if m is not None: + sdk = m.group(1) + if not os.path.exists(sdk): + for key in ('LDFLAGS', 'BASECFLAGS', + # a number of derived variables. These need to be + # patched up as well. + 'CFLAGS', 'PY_CFLAGS', 'BLDSHARED'): + + flags = _CONFIG_VARS[key] + flags = re.sub(r'-isysroot\s+\S+(\s|$)', ' ', flags) + _CONFIG_VARS[key] = flags + + if args: + vals = [] + for name in args: + vals.append(_CONFIG_VARS.get(name)) + return vals + else: + return _CONFIG_VARS + + +def get_config_var(name): + """Return the value of a single variable using the dictionary returned by + 'get_config_vars()'. + + Equivalent to get_config_vars().get(name) + """ + return get_config_vars().get(name) + + +def get_platform(): + """Return a string that identifies the current platform. + + This is used mainly to distinguish platform-specific build directories and + platform-specific built distributions. Typically includes the OS name + and version and the architecture (as supplied by 'os.uname()'), + although the exact information included depends on the OS; eg. for IRIX + the architecture isn't particularly important (IRIX only runs on SGI + hardware), but for Linux the kernel version isn't particularly + important. + + Examples of returned values: + linux-i586 + linux-alpha (?) + solaris-2.6-sun4u + irix-5.3 + irix64-6.2 + + Windows will return one of: + win-amd64 (64bit Windows on AMD64 (aka x86_64, Intel64, EM64T, etc) + win-ia64 (64bit Windows on Itanium) + win32 (all others - specifically, sys.platform is returned) + + For other non-POSIX platforms, currently just returns 'sys.platform'. + """ + if os.name == 'nt': + # sniff sys.version for architecture. + prefix = " bit (" + i = sys.version.find(prefix) + if i == -1: + return sys.platform + j = sys.version.find(")", i) + look = sys.version[i+len(prefix):j].lower() + if look == 'amd64': + return 'win-amd64' + if look == 'itanium': + return 'win-ia64' + return sys.platform + + if os.name != "posix" or not hasattr(os, 'uname'): + # XXX what about the architecture? NT is Intel or Alpha, + # Mac OS is M68k or PPC, etc. + return sys.platform + + # Try to distinguish various flavours of Unix + osname, host, release, version, machine = os.uname() + + # Convert the OS name to lowercase, remove '/' characters + # (to accommodate BSD/OS), and translate spaces (for "Power Macintosh") + osname = osname.lower().replace('/', '') + machine = machine.replace(' ', '_') + machine = machine.replace('/', '-') + + if osname[:5] == "linux": + # At least on Linux/Intel, 'machine' is the processor -- + # i386, etc. + # XXX what about Alpha, SPARC, etc? + return "%s-%s" % (osname, machine) + elif osname[:5] == "sunos": + if release[0] >= "5": # SunOS 5 == Solaris 2 + osname = "solaris" + release = "%d.%s" % (int(release[0]) - 3, release[2:]) + # fall through to standard osname-release-machine representation + elif osname[:4] == "irix": # could be "irix64"! + return "%s-%s" % (osname, release) + elif osname[:3] == "aix": + return "%s-%s.%s" % (osname, version, release) + elif osname[:6] == "cygwin": + osname = "cygwin" + rel_re = re.compile(r'[\d.]+') + m = rel_re.match(release) + if m: + release = m.group() + elif osname[:6] == "darwin": + # + # For our purposes, we'll assume that the system version from + # distutils' perspective is what MACOSX_DEPLOYMENT_TARGET is set + # to. This makes the compatibility story a bit more sane because the + # machine is going to compile and link as if it were + # MACOSX_DEPLOYMENT_TARGET. + cfgvars = get_config_vars() + macver = cfgvars.get('MACOSX_DEPLOYMENT_TARGET') + + if True: + # Always calculate the release of the running machine, + # needed to determine if we can build fat binaries or not. + + macrelease = macver + # Get the system version. Reading this plist is a documented + # way to get the system version (see the documentation for + # the Gestalt Manager) + try: + f = open('/System/Library/CoreServices/SystemVersion.plist') + except IOError: + # We're on a plain darwin box, fall back to the default + # behaviour. + pass + else: + try: + m = re.search(r'<key>ProductUserVisibleVersion</key>\s*' + r'<string>(.*?)</string>', f.read()) + finally: + f.close() + if m is not None: + macrelease = '.'.join(m.group(1).split('.')[:2]) + # else: fall back to the default behaviour + + if not macver: + macver = macrelease + + if macver: + release = macver + osname = "macosx" + + if ((macrelease + '.') >= '10.4.' and + '-arch' in get_config_vars().get('CFLAGS', '').strip()): + # The universal build will build fat binaries, but not on + # systems before 10.4 + # + # Try to detect 4-way universal builds, those have machine-type + # 'universal' instead of 'fat'. + + machine = 'fat' + cflags = get_config_vars().get('CFLAGS') + + archs = re.findall(r'-arch\s+(\S+)', cflags) + archs = tuple(sorted(set(archs))) + + if len(archs) == 1: + machine = archs[0] + elif archs == ('i386', 'ppc'): + machine = 'fat' + elif archs == ('i386', 'x86_64'): + machine = 'intel' + elif archs == ('i386', 'ppc', 'x86_64'): + machine = 'fat3' + elif archs == ('ppc64', 'x86_64'): + machine = 'fat64' + elif archs == ('i386', 'ppc', 'ppc64', 'x86_64'): + machine = 'universal' + else: + raise ValueError( + "Don't know machine value for archs=%r" % (archs,)) + + elif machine == 'i386': + # On OSX the machine type returned by uname is always the + # 32-bit variant, even if the executable architecture is + # the 64-bit variant + if sys.maxsize >= 2**32: + machine = 'x86_64' + + elif machine in ('PowerPC', 'Power_Macintosh'): + # Pick a sane name for the PPC architecture. + # See 'i386' case + if sys.maxsize >= 2**32: + machine = 'ppc64' + else: + machine = 'ppc' + + return "%s-%s-%s" % (osname, release, machine) + + +def get_python_version(): + return _PY_VERSION_SHORT + + +def _print_dict(title, data): + for index, (key, value) in enumerate(sorted(data.items())): + if index == 0: + print('%s: ' % (title)) + print('\t%s = "%s"' % (key, value)) + + +def _main(): + """Display all information sysconfig detains.""" + print('Platform: "%s"' % get_platform()) + print('Python version: "%s"' % get_python_version()) + print('Current installation scheme: "%s"' % _get_default_scheme()) + print() + _print_dict('Paths', get_paths()) + print() + _print_dict('Variables', get_config_vars()) + + +if __name__ == '__main__': + _main() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py new file mode 100644 index 0000000..d66d856 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/_backport/tarfile.py @@ -0,0 +1,2607 @@ +#------------------------------------------------------------------- +# tarfile.py +#------------------------------------------------------------------- +# Copyright (C) 2002 Lars Gustaebel <lars@gustaebel.de> +# All rights reserved. +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +# +from __future__ import print_function + +"""Read from and write to tar format archives. +""" + +__version__ = "$Revision$" + +version = "0.9.0" +__author__ = "Lars Gust\u00e4bel (lars@gustaebel.de)" +__date__ = "$Date: 2011-02-25 17:42:01 +0200 (Fri, 25 Feb 2011) $" +__cvsid__ = "$Id: tarfile.py 88586 2011-02-25 15:42:01Z marc-andre.lemburg $" +__credits__ = "Gustavo Niemeyer, Niels Gust\u00e4bel, Richard Townsend." + +#--------- +# Imports +#--------- +import sys +import os +import stat +import errno +import time +import struct +import copy +import re + +try: + import grp, pwd +except ImportError: + grp = pwd = None + +# os.symlink on Windows prior to 6.0 raises NotImplementedError +symlink_exception = (AttributeError, NotImplementedError) +try: + # WindowsError (1314) will be raised if the caller does not hold the + # SeCreateSymbolicLinkPrivilege privilege + symlink_exception += (WindowsError,) +except NameError: + pass + +# from tarfile import * +__all__ = ["TarFile", "TarInfo", "is_tarfile", "TarError"] + +if sys.version_info[0] < 3: + import __builtin__ as builtins +else: + import builtins + +_open = builtins.open # Since 'open' is TarFile.open + +#--------------------------------------------------------- +# tar constants +#--------------------------------------------------------- +NUL = b"\0" # the null character +BLOCKSIZE = 512 # length of processing blocks +RECORDSIZE = BLOCKSIZE * 20 # length of records +GNU_MAGIC = b"ustar \0" # magic gnu tar string +POSIX_MAGIC = b"ustar\x0000" # magic posix tar string + +LENGTH_NAME = 100 # maximum length of a filename +LENGTH_LINK = 100 # maximum length of a linkname +LENGTH_PREFIX = 155 # maximum length of the prefix field + +REGTYPE = b"0" # regular file +AREGTYPE = b"\0" # regular file +LNKTYPE = b"1" # link (inside tarfile) +SYMTYPE = b"2" # symbolic link +CHRTYPE = b"3" # character special device +BLKTYPE = b"4" # block special device +DIRTYPE = b"5" # directory +FIFOTYPE = b"6" # fifo special device +CONTTYPE = b"7" # contiguous file + +GNUTYPE_LONGNAME = b"L" # GNU tar longname +GNUTYPE_LONGLINK = b"K" # GNU tar longlink +GNUTYPE_SPARSE = b"S" # GNU tar sparse file + +XHDTYPE = b"x" # POSIX.1-2001 extended header +XGLTYPE = b"g" # POSIX.1-2001 global header +SOLARIS_XHDTYPE = b"X" # Solaris extended header + +USTAR_FORMAT = 0 # POSIX.1-1988 (ustar) format +GNU_FORMAT = 1 # GNU tar format +PAX_FORMAT = 2 # POSIX.1-2001 (pax) format +DEFAULT_FORMAT = GNU_FORMAT + +#--------------------------------------------------------- +# tarfile constants +#--------------------------------------------------------- +# File types that tarfile supports: +SUPPORTED_TYPES = (REGTYPE, AREGTYPE, LNKTYPE, + SYMTYPE, DIRTYPE, FIFOTYPE, + CONTTYPE, CHRTYPE, BLKTYPE, + GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# File types that will be treated as a regular file. +REGULAR_TYPES = (REGTYPE, AREGTYPE, + CONTTYPE, GNUTYPE_SPARSE) + +# File types that are part of the GNU tar format. +GNU_TYPES = (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK, + GNUTYPE_SPARSE) + +# Fields from a pax header that override a TarInfo attribute. +PAX_FIELDS = ("path", "linkpath", "size", "mtime", + "uid", "gid", "uname", "gname") + +# Fields from a pax header that are affected by hdrcharset. +PAX_NAME_FIELDS = set(("path", "linkpath", "uname", "gname")) + +# Fields in a pax header that are numbers, all other fields +# are treated as strings. +PAX_NUMBER_FIELDS = { + "atime": float, + "ctime": float, + "mtime": float, + "uid": int, + "gid": int, + "size": int +} + +#--------------------------------------------------------- +# Bits used in the mode field, values in octal. +#--------------------------------------------------------- +S_IFLNK = 0o120000 # symbolic link +S_IFREG = 0o100000 # regular file +S_IFBLK = 0o060000 # block device +S_IFDIR = 0o040000 # directory +S_IFCHR = 0o020000 # character device +S_IFIFO = 0o010000 # fifo + +TSUID = 0o4000 # set UID on execution +TSGID = 0o2000 # set GID on execution +TSVTX = 0o1000 # reserved + +TUREAD = 0o400 # read by owner +TUWRITE = 0o200 # write by owner +TUEXEC = 0o100 # execute/search by owner +TGREAD = 0o040 # read by group +TGWRITE = 0o020 # write by group +TGEXEC = 0o010 # execute/search by group +TOREAD = 0o004 # read by other +TOWRITE = 0o002 # write by other +TOEXEC = 0o001 # execute/search by other + +#--------------------------------------------------------- +# initialization +#--------------------------------------------------------- +if os.name in ("nt", "ce"): + ENCODING = "utf-8" +else: + ENCODING = sys.getfilesystemencoding() + +#--------------------------------------------------------- +# Some useful functions +#--------------------------------------------------------- + +def stn(s, length, encoding, errors): + """Convert a string to a null-terminated bytes object. + """ + s = s.encode(encoding, errors) + return s[:length] + (length - len(s)) * NUL + +def nts(s, encoding, errors): + """Convert a null-terminated bytes object to a string. + """ + p = s.find(b"\0") + if p != -1: + s = s[:p] + return s.decode(encoding, errors) + +def nti(s): + """Convert a number field to a python number. + """ + # There are two possible encodings for a number field, see + # itn() below. + if s[0] != chr(0o200): + try: + n = int(nts(s, "ascii", "strict") or "0", 8) + except ValueError: + raise InvalidHeaderError("invalid header") + else: + n = 0 + for i in range(len(s) - 1): + n <<= 8 + n += ord(s[i + 1]) + return n + +def itn(n, digits=8, format=DEFAULT_FORMAT): + """Convert a python number to a number field. + """ + # POSIX 1003.1-1988 requires numbers to be encoded as a string of + # octal digits followed by a null-byte, this allows values up to + # (8**(digits-1))-1. GNU tar allows storing numbers greater than + # that if necessary. A leading 0o200 byte indicates this particular + # encoding, the following digits-1 bytes are a big-endian + # representation. This allows values up to (256**(digits-1))-1. + if 0 <= n < 8 ** (digits - 1): + s = ("%0*o" % (digits - 1, n)).encode("ascii") + NUL + else: + if format != GNU_FORMAT or n >= 256 ** (digits - 1): + raise ValueError("overflow in number field") + + if n < 0: + # XXX We mimic GNU tar's behaviour with negative numbers, + # this could raise OverflowError. + n = struct.unpack("L", struct.pack("l", n))[0] + + s = bytearray() + for i in range(digits - 1): + s.insert(0, n & 0o377) + n >>= 8 + s.insert(0, 0o200) + return s + +def calc_chksums(buf): + """Calculate the checksum for a member's header by summing up all + characters except for the chksum field which is treated as if + it was filled with spaces. According to the GNU tar sources, + some tars (Sun and NeXT) calculate chksum with signed char, + which will be different if there are chars in the buffer with + the high bit set. So we calculate two checksums, unsigned and + signed. + """ + unsigned_chksum = 256 + sum(struct.unpack("148B", buf[:148]) + struct.unpack("356B", buf[156:512])) + signed_chksum = 256 + sum(struct.unpack("148b", buf[:148]) + struct.unpack("356b", buf[156:512])) + return unsigned_chksum, signed_chksum + +def copyfileobj(src, dst, length=None): + """Copy length bytes from fileobj src to fileobj dst. + If length is None, copy the entire content. + """ + if length == 0: + return + if length is None: + while True: + buf = src.read(16*1024) + if not buf: + break + dst.write(buf) + return + + BUFSIZE = 16 * 1024 + blocks, remainder = divmod(length, BUFSIZE) + for b in range(blocks): + buf = src.read(BUFSIZE) + if len(buf) < BUFSIZE: + raise IOError("end of file reached") + dst.write(buf) + + if remainder != 0: + buf = src.read(remainder) + if len(buf) < remainder: + raise IOError("end of file reached") + dst.write(buf) + return + +filemode_table = ( + ((S_IFLNK, "l"), + (S_IFREG, "-"), + (S_IFBLK, "b"), + (S_IFDIR, "d"), + (S_IFCHR, "c"), + (S_IFIFO, "p")), + + ((TUREAD, "r"),), + ((TUWRITE, "w"),), + ((TUEXEC|TSUID, "s"), + (TSUID, "S"), + (TUEXEC, "x")), + + ((TGREAD, "r"),), + ((TGWRITE, "w"),), + ((TGEXEC|TSGID, "s"), + (TSGID, "S"), + (TGEXEC, "x")), + + ((TOREAD, "r"),), + ((TOWRITE, "w"),), + ((TOEXEC|TSVTX, "t"), + (TSVTX, "T"), + (TOEXEC, "x")) +) + +def filemode(mode): + """Convert a file's mode to a string of the form + -rwxrwxrwx. + Used by TarFile.list() + """ + perm = [] + for table in filemode_table: + for bit, char in table: + if mode & bit == bit: + perm.append(char) + break + else: + perm.append("-") + return "".join(perm) + +class TarError(Exception): + """Base exception.""" + pass +class ExtractError(TarError): + """General exception for extract errors.""" + pass +class ReadError(TarError): + """Exception for unreadable tar archives.""" + pass +class CompressionError(TarError): + """Exception for unavailable compression methods.""" + pass +class StreamError(TarError): + """Exception for unsupported operations on stream-like TarFiles.""" + pass +class HeaderError(TarError): + """Base exception for header errors.""" + pass +class EmptyHeaderError(HeaderError): + """Exception for empty headers.""" + pass +class TruncatedHeaderError(HeaderError): + """Exception for truncated headers.""" + pass +class EOFHeaderError(HeaderError): + """Exception for end of file headers.""" + pass +class InvalidHeaderError(HeaderError): + """Exception for invalid headers.""" + pass +class SubsequentHeaderError(HeaderError): + """Exception for missing and invalid extended headers.""" + pass + +#--------------------------- +# internal stream interface +#--------------------------- +class _LowLevelFile(object): + """Low-level file object. Supports reading and writing. + It is used instead of a regular file object for streaming + access. + """ + + def __init__(self, name, mode): + mode = { + "r": os.O_RDONLY, + "w": os.O_WRONLY | os.O_CREAT | os.O_TRUNC, + }[mode] + if hasattr(os, "O_BINARY"): + mode |= os.O_BINARY + self.fd = os.open(name, mode, 0o666) + + def close(self): + os.close(self.fd) + + def read(self, size): + return os.read(self.fd, size) + + def write(self, s): + os.write(self.fd, s) + +class _Stream(object): + """Class that serves as an adapter between TarFile and + a stream-like object. The stream-like object only + needs to have a read() or write() method and is accessed + blockwise. Use of gzip or bzip2 compression is possible. + A stream-like object could be for example: sys.stdin, + sys.stdout, a socket, a tape device etc. + + _Stream is intended to be used only internally. + """ + + def __init__(self, name, mode, comptype, fileobj, bufsize): + """Construct a _Stream object. + """ + self._extfileobj = True + if fileobj is None: + fileobj = _LowLevelFile(name, mode) + self._extfileobj = False + + if comptype == '*': + # Enable transparent compression detection for the + # stream interface + fileobj = _StreamProxy(fileobj) + comptype = fileobj.getcomptype() + + self.name = name or "" + self.mode = mode + self.comptype = comptype + self.fileobj = fileobj + self.bufsize = bufsize + self.buf = b"" + self.pos = 0 + self.closed = False + + try: + if comptype == "gz": + try: + import zlib + except ImportError: + raise CompressionError("zlib module is not available") + self.zlib = zlib + self.crc = zlib.crc32(b"") + if mode == "r": + self._init_read_gz() + else: + self._init_write_gz() + + if comptype == "bz2": + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + if mode == "r": + self.dbuf = b"" + self.cmp = bz2.BZ2Decompressor() + else: + self.cmp = bz2.BZ2Compressor() + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + def __del__(self): + if hasattr(self, "closed") and not self.closed: + self.close() + + def _init_write_gz(self): + """Initialize for writing with gzip compression. + """ + self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED, + -self.zlib.MAX_WBITS, + self.zlib.DEF_MEM_LEVEL, + 0) + timestamp = struct.pack("<L", int(time.time())) + self.__write(b"\037\213\010\010" + timestamp + b"\002\377") + if self.name.endswith(".gz"): + self.name = self.name[:-3] + # RFC1952 says we must use ISO-8859-1 for the FNAME field. + self.__write(self.name.encode("iso-8859-1", "replace") + NUL) + + def write(self, s): + """Write string s to the stream. + """ + if self.comptype == "gz": + self.crc = self.zlib.crc32(s, self.crc) + self.pos += len(s) + if self.comptype != "tar": + s = self.cmp.compress(s) + self.__write(s) + + def __write(self, s): + """Write string s to the stream if a whole new block + is ready to be written. + """ + self.buf += s + while len(self.buf) > self.bufsize: + self.fileobj.write(self.buf[:self.bufsize]) + self.buf = self.buf[self.bufsize:] + + def close(self): + """Close the _Stream object. No operation should be + done on it afterwards. + """ + if self.closed: + return + + if self.mode == "w" and self.comptype != "tar": + self.buf += self.cmp.flush() + + if self.mode == "w" and self.buf: + self.fileobj.write(self.buf) + self.buf = b"" + if self.comptype == "gz": + # The native zlib crc is an unsigned 32-bit integer, but + # the Python wrapper implicitly casts that to a signed C + # long. So, on a 32-bit box self.crc may "look negative", + # while the same crc on a 64-bit box may "look positive". + # To avoid irksome warnings from the `struct` module, force + # it to look positive on all boxes. + self.fileobj.write(struct.pack("<L", self.crc & 0xffffffff)) + self.fileobj.write(struct.pack("<L", self.pos & 0xffffFFFF)) + + if not self._extfileobj: + self.fileobj.close() + + self.closed = True + + def _init_read_gz(self): + """Initialize for reading a gzip compressed fileobj. + """ + self.cmp = self.zlib.decompressobj(-self.zlib.MAX_WBITS) + self.dbuf = b"" + + # taken from gzip.GzipFile with some alterations + if self.__read(2) != b"\037\213": + raise ReadError("not a gzip file") + if self.__read(1) != b"\010": + raise CompressionError("unsupported compression method") + + flag = ord(self.__read(1)) + self.__read(6) + + if flag & 4: + xlen = ord(self.__read(1)) + 256 * ord(self.__read(1)) + self.read(xlen) + if flag & 8: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 16: + while True: + s = self.__read(1) + if not s or s == NUL: + break + if flag & 2: + self.__read(2) + + def tell(self): + """Return the stream's file pointer position. + """ + return self.pos + + def seek(self, pos=0): + """Set the stream's file pointer to pos. Negative seeking + is forbidden. + """ + if pos - self.pos >= 0: + blocks, remainder = divmod(pos - self.pos, self.bufsize) + for i in range(blocks): + self.read(self.bufsize) + self.read(remainder) + else: + raise StreamError("seeking backwards is not allowed") + return self.pos + + def read(self, size=None): + """Return the next size number of bytes from the stream. + If size is not defined, return all bytes of the stream + up to EOF. + """ + if size is None: + t = [] + while True: + buf = self._read(self.bufsize) + if not buf: + break + t.append(buf) + buf = "".join(t) + else: + buf = self._read(size) + self.pos += len(buf) + return buf + + def _read(self, size): + """Return size bytes from the stream. + """ + if self.comptype == "tar": + return self.__read(size) + + c = len(self.dbuf) + while c < size: + buf = self.__read(self.bufsize) + if not buf: + break + try: + buf = self.cmp.decompress(buf) + except IOError: + raise ReadError("invalid compressed data") + self.dbuf += buf + c += len(buf) + buf = self.dbuf[:size] + self.dbuf = self.dbuf[size:] + return buf + + def __read(self, size): + """Return size bytes from stream. If internal buffer is empty, + read another block from the stream. + """ + c = len(self.buf) + while c < size: + buf = self.fileobj.read(self.bufsize) + if not buf: + break + self.buf += buf + c += len(buf) + buf = self.buf[:size] + self.buf = self.buf[size:] + return buf +# class _Stream + +class _StreamProxy(object): + """Small proxy class that enables transparent compression + detection for the Stream interface (mode 'r|*'). + """ + + def __init__(self, fileobj): + self.fileobj = fileobj + self.buf = self.fileobj.read(BLOCKSIZE) + + def read(self, size): + self.read = self.fileobj.read + return self.buf + + def getcomptype(self): + if self.buf.startswith(b"\037\213\010"): + return "gz" + if self.buf.startswith(b"BZh91"): + return "bz2" + return "tar" + + def close(self): + self.fileobj.close() +# class StreamProxy + +class _BZ2Proxy(object): + """Small proxy class that enables external file object + support for "r:bz2" and "w:bz2" modes. This is actually + a workaround for a limitation in bz2 module's BZ2File + class which (unlike gzip.GzipFile) has no support for + a file object argument. + """ + + blocksize = 16 * 1024 + + def __init__(self, fileobj, mode): + self.fileobj = fileobj + self.mode = mode + self.name = getattr(self.fileobj, "name", None) + self.init() + + def init(self): + import bz2 + self.pos = 0 + if self.mode == "r": + self.bz2obj = bz2.BZ2Decompressor() + self.fileobj.seek(0) + self.buf = b"" + else: + self.bz2obj = bz2.BZ2Compressor() + + def read(self, size): + x = len(self.buf) + while x < size: + raw = self.fileobj.read(self.blocksize) + if not raw: + break + data = self.bz2obj.decompress(raw) + self.buf += data + x += len(data) + + buf = self.buf[:size] + self.buf = self.buf[size:] + self.pos += len(buf) + return buf + + def seek(self, pos): + if pos < self.pos: + self.init() + self.read(pos - self.pos) + + def tell(self): + return self.pos + + def write(self, data): + self.pos += len(data) + raw = self.bz2obj.compress(data) + self.fileobj.write(raw) + + def close(self): + if self.mode == "w": + raw = self.bz2obj.flush() + self.fileobj.write(raw) +# class _BZ2Proxy + +#------------------------ +# Extraction file object +#------------------------ +class _FileInFile(object): + """A thin wrapper around an existing file object that + provides a part of its data as an individual file + object. + """ + + def __init__(self, fileobj, offset, size, blockinfo=None): + self.fileobj = fileobj + self.offset = offset + self.size = size + self.position = 0 + + if blockinfo is None: + blockinfo = [(0, size)] + + # Construct a map with data and zero blocks. + self.map_index = 0 + self.map = [] + lastpos = 0 + realpos = self.offset + for offset, size in blockinfo: + if offset > lastpos: + self.map.append((False, lastpos, offset, None)) + self.map.append((True, offset, offset + size, realpos)) + realpos += size + lastpos = offset + size + if lastpos < self.size: + self.map.append((False, lastpos, self.size, None)) + + def seekable(self): + if not hasattr(self.fileobj, "seekable"): + # XXX gzip.GzipFile and bz2.BZ2File + return True + return self.fileobj.seekable() + + def tell(self): + """Return the current file position. + """ + return self.position + + def seek(self, position): + """Seek to a position in the file. + """ + self.position = position + + def read(self, size=None): + """Read data from the file. + """ + if size is None: + size = self.size - self.position + else: + size = min(size, self.size - self.position) + + buf = b"" + while size > 0: + while True: + data, start, stop, offset = self.map[self.map_index] + if start <= self.position < stop: + break + else: + self.map_index += 1 + if self.map_index == len(self.map): + self.map_index = 0 + length = min(size, stop - self.position) + if data: + self.fileobj.seek(offset + (self.position - start)) + buf += self.fileobj.read(length) + else: + buf += NUL * length + size -= length + self.position += length + return buf +#class _FileInFile + + +class ExFileObject(object): + """File-like object for reading an archive member. + Is returned by TarFile.extractfile(). + """ + blocksize = 1024 + + def __init__(self, tarfile, tarinfo): + self.fileobj = _FileInFile(tarfile.fileobj, + tarinfo.offset_data, + tarinfo.size, + tarinfo.sparse) + self.name = tarinfo.name + self.mode = "r" + self.closed = False + self.size = tarinfo.size + + self.position = 0 + self.buffer = b"" + + def readable(self): + return True + + def writable(self): + return False + + def seekable(self): + return self.fileobj.seekable() + + def read(self, size=None): + """Read at most size bytes from the file. If size is not + present or None, read all data until EOF is reached. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + buf = b"" + if self.buffer: + if size is None: + buf = self.buffer + self.buffer = b"" + else: + buf = self.buffer[:size] + self.buffer = self.buffer[size:] + + if size is None: + buf += self.fileobj.read() + else: + buf += self.fileobj.read(size - len(buf)) + + self.position += len(buf) + return buf + + # XXX TextIOWrapper uses the read1() method. + read1 = read + + def readline(self, size=-1): + """Read one entire line from the file. If size is present + and non-negative, return a string with at most that + size, which may be an incomplete line. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + while True: + buf = self.fileobj.read(self.blocksize) + self.buffer += buf + if not buf or b"\n" in buf: + pos = self.buffer.find(b"\n") + 1 + if pos == 0: + # no newline found. + pos = len(self.buffer) + break + + if size != -1: + pos = min(size, pos) + + buf = self.buffer[:pos] + self.buffer = self.buffer[pos:] + self.position += len(buf) + return buf + + def readlines(self): + """Return a list with all remaining lines. + """ + result = [] + while True: + line = self.readline() + if not line: break + result.append(line) + return result + + def tell(self): + """Return the current file position. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + return self.position + + def seek(self, pos, whence=os.SEEK_SET): + """Seek to a position in the file. + """ + if self.closed: + raise ValueError("I/O operation on closed file") + + if whence == os.SEEK_SET: + self.position = min(max(pos, 0), self.size) + elif whence == os.SEEK_CUR: + if pos < 0: + self.position = max(self.position + pos, 0) + else: + self.position = min(self.position + pos, self.size) + elif whence == os.SEEK_END: + self.position = max(min(self.size + pos, self.size), 0) + else: + raise ValueError("Invalid argument") + + self.buffer = b"" + self.fileobj.seek(self.position) + + def close(self): + """Close the file object. + """ + self.closed = True + + def __iter__(self): + """Get an iterator over the file's lines. + """ + while True: + line = self.readline() + if not line: + break + yield line +#class ExFileObject + +#------------------ +# Exported Classes +#------------------ +class TarInfo(object): + """Informational class which holds the details about an + archive member given by a tar header block. + TarInfo objects are returned by TarFile.getmember(), + TarFile.getmembers() and TarFile.gettarinfo() and are + usually created internally. + """ + + __slots__ = ("name", "mode", "uid", "gid", "size", "mtime", + "chksum", "type", "linkname", "uname", "gname", + "devmajor", "devminor", + "offset", "offset_data", "pax_headers", "sparse", + "tarfile", "_sparse_structs", "_link_target") + + def __init__(self, name=""): + """Construct a TarInfo object. name is the optional name + of the member. + """ + self.name = name # member name + self.mode = 0o644 # file permissions + self.uid = 0 # user id + self.gid = 0 # group id + self.size = 0 # file size + self.mtime = 0 # modification time + self.chksum = 0 # header checksum + self.type = REGTYPE # member type + self.linkname = "" # link name + self.uname = "" # user name + self.gname = "" # group name + self.devmajor = 0 # device major number + self.devminor = 0 # device minor number + + self.offset = 0 # the tar header starts here + self.offset_data = 0 # the file's data starts here + + self.sparse = None # sparse member information + self.pax_headers = {} # pax header information + + # In pax headers the "name" and "linkname" field are called + # "path" and "linkpath". + def _getpath(self): + return self.name + def _setpath(self, name): + self.name = name + path = property(_getpath, _setpath) + + def _getlinkpath(self): + return self.linkname + def _setlinkpath(self, linkname): + self.linkname = linkname + linkpath = property(_getlinkpath, _setlinkpath) + + def __repr__(self): + return "<%s %r at %#x>" % (self.__class__.__name__,self.name,id(self)) + + def get_info(self): + """Return the TarInfo's attributes as a dictionary. + """ + info = { + "name": self.name, + "mode": self.mode & 0o7777, + "uid": self.uid, + "gid": self.gid, + "size": self.size, + "mtime": self.mtime, + "chksum": self.chksum, + "type": self.type, + "linkname": self.linkname, + "uname": self.uname, + "gname": self.gname, + "devmajor": self.devmajor, + "devminor": self.devminor + } + + if info["type"] == DIRTYPE and not info["name"].endswith("/"): + info["name"] += "/" + + return info + + def tobuf(self, format=DEFAULT_FORMAT, encoding=ENCODING, errors="surrogateescape"): + """Return a tar header as a string of 512 byte blocks. + """ + info = self.get_info() + + if format == USTAR_FORMAT: + return self.create_ustar_header(info, encoding, errors) + elif format == GNU_FORMAT: + return self.create_gnu_header(info, encoding, errors) + elif format == PAX_FORMAT: + return self.create_pax_header(info, encoding) + else: + raise ValueError("invalid format") + + def create_ustar_header(self, info, encoding, errors): + """Return the object as a ustar header block. + """ + info["magic"] = POSIX_MAGIC + + if len(info["linkname"]) > LENGTH_LINK: + raise ValueError("linkname is too long") + + if len(info["name"]) > LENGTH_NAME: + info["prefix"], info["name"] = self._posix_split_name(info["name"]) + + return self._create_header(info, USTAR_FORMAT, encoding, errors) + + def create_gnu_header(self, info, encoding, errors): + """Return the object as a GNU header block sequence. + """ + info["magic"] = GNU_MAGIC + + buf = b"" + if len(info["linkname"]) > LENGTH_LINK: + buf += self._create_gnu_long_header(info["linkname"], GNUTYPE_LONGLINK, encoding, errors) + + if len(info["name"]) > LENGTH_NAME: + buf += self._create_gnu_long_header(info["name"], GNUTYPE_LONGNAME, encoding, errors) + + return buf + self._create_header(info, GNU_FORMAT, encoding, errors) + + def create_pax_header(self, info, encoding): + """Return the object as a ustar header block. If it cannot be + represented this way, prepend a pax extended header sequence + with supplement information. + """ + info["magic"] = POSIX_MAGIC + pax_headers = self.pax_headers.copy() + + # Test string fields for values that exceed the field length or cannot + # be represented in ASCII encoding. + for name, hname, length in ( + ("name", "path", LENGTH_NAME), ("linkname", "linkpath", LENGTH_LINK), + ("uname", "uname", 32), ("gname", "gname", 32)): + + if hname in pax_headers: + # The pax header has priority. + continue + + # Try to encode the string as ASCII. + try: + info[name].encode("ascii", "strict") + except UnicodeEncodeError: + pax_headers[hname] = info[name] + continue + + if len(info[name]) > length: + pax_headers[hname] = info[name] + + # Test number fields for values that exceed the field limit or values + # that like to be stored as float. + for name, digits in (("uid", 8), ("gid", 8), ("size", 12), ("mtime", 12)): + if name in pax_headers: + # The pax header has priority. Avoid overflow. + info[name] = 0 + continue + + val = info[name] + if not 0 <= val < 8 ** (digits - 1) or isinstance(val, float): + pax_headers[name] = str(val) + info[name] = 0 + + # Create a pax extended header if necessary. + if pax_headers: + buf = self._create_pax_generic_header(pax_headers, XHDTYPE, encoding) + else: + buf = b"" + + return buf + self._create_header(info, USTAR_FORMAT, "ascii", "replace") + + @classmethod + def create_pax_global_header(cls, pax_headers): + """Return the object as a pax global header block sequence. + """ + return cls._create_pax_generic_header(pax_headers, XGLTYPE, "utf8") + + def _posix_split_name(self, name): + """Split a name longer than 100 chars into a prefix + and a name part. + """ + prefix = name[:LENGTH_PREFIX + 1] + while prefix and prefix[-1] != "/": + prefix = prefix[:-1] + + name = name[len(prefix):] + prefix = prefix[:-1] + + if not prefix or len(name) > LENGTH_NAME: + raise ValueError("name is too long") + return prefix, name + + @staticmethod + def _create_header(info, format, encoding, errors): + """Return a header block. info is a dictionary with file + information, format must be one of the *_FORMAT constants. + """ + parts = [ + stn(info.get("name", ""), 100, encoding, errors), + itn(info.get("mode", 0) & 0o7777, 8, format), + itn(info.get("uid", 0), 8, format), + itn(info.get("gid", 0), 8, format), + itn(info.get("size", 0), 12, format), + itn(info.get("mtime", 0), 12, format), + b" ", # checksum field + info.get("type", REGTYPE), + stn(info.get("linkname", ""), 100, encoding, errors), + info.get("magic", POSIX_MAGIC), + stn(info.get("uname", ""), 32, encoding, errors), + stn(info.get("gname", ""), 32, encoding, errors), + itn(info.get("devmajor", 0), 8, format), + itn(info.get("devminor", 0), 8, format), + stn(info.get("prefix", ""), 155, encoding, errors) + ] + + buf = struct.pack("%ds" % BLOCKSIZE, b"".join(parts)) + chksum = calc_chksums(buf[-BLOCKSIZE:])[0] + buf = buf[:-364] + ("%06o\0" % chksum).encode("ascii") + buf[-357:] + return buf + + @staticmethod + def _create_payload(payload): + """Return the string payload filled with zero bytes + up to the next 512 byte border. + """ + blocks, remainder = divmod(len(payload), BLOCKSIZE) + if remainder > 0: + payload += (BLOCKSIZE - remainder) * NUL + return payload + + @classmethod + def _create_gnu_long_header(cls, name, type, encoding, errors): + """Return a GNUTYPE_LONGNAME or GNUTYPE_LONGLINK sequence + for name. + """ + name = name.encode(encoding, errors) + NUL + + info = {} + info["name"] = "././@LongLink" + info["type"] = type + info["size"] = len(name) + info["magic"] = GNU_MAGIC + + # create extended header + name blocks. + return cls._create_header(info, USTAR_FORMAT, encoding, errors) + \ + cls._create_payload(name) + + @classmethod + def _create_pax_generic_header(cls, pax_headers, type, encoding): + """Return a POSIX.1-2008 extended or global header sequence + that contains a list of keyword, value pairs. The values + must be strings. + """ + # Check if one of the fields contains surrogate characters and thereby + # forces hdrcharset=BINARY, see _proc_pax() for more information. + binary = False + for keyword, value in pax_headers.items(): + try: + value.encode("utf8", "strict") + except UnicodeEncodeError: + binary = True + break + + records = b"" + if binary: + # Put the hdrcharset field at the beginning of the header. + records += b"21 hdrcharset=BINARY\n" + + for keyword, value in pax_headers.items(): + keyword = keyword.encode("utf8") + if binary: + # Try to restore the original byte representation of `value'. + # Needless to say, that the encoding must match the string. + value = value.encode(encoding, "surrogateescape") + else: + value = value.encode("utf8") + + l = len(keyword) + len(value) + 3 # ' ' + '=' + '\n' + n = p = 0 + while True: + n = l + len(str(p)) + if n == p: + break + p = n + records += bytes(str(p), "ascii") + b" " + keyword + b"=" + value + b"\n" + + # We use a hardcoded "././@PaxHeader" name like star does + # instead of the one that POSIX recommends. + info = {} + info["name"] = "././@PaxHeader" + info["type"] = type + info["size"] = len(records) + info["magic"] = POSIX_MAGIC + + # Create pax header + record blocks. + return cls._create_header(info, USTAR_FORMAT, "ascii", "replace") + \ + cls._create_payload(records) + + @classmethod + def frombuf(cls, buf, encoding, errors): + """Construct a TarInfo object from a 512 byte bytes object. + """ + if len(buf) == 0: + raise EmptyHeaderError("empty header") + if len(buf) != BLOCKSIZE: + raise TruncatedHeaderError("truncated header") + if buf.count(NUL) == BLOCKSIZE: + raise EOFHeaderError("end of file header") + + chksum = nti(buf[148:156]) + if chksum not in calc_chksums(buf): + raise InvalidHeaderError("bad checksum") + + obj = cls() + obj.name = nts(buf[0:100], encoding, errors) + obj.mode = nti(buf[100:108]) + obj.uid = nti(buf[108:116]) + obj.gid = nti(buf[116:124]) + obj.size = nti(buf[124:136]) + obj.mtime = nti(buf[136:148]) + obj.chksum = chksum + obj.type = buf[156:157] + obj.linkname = nts(buf[157:257], encoding, errors) + obj.uname = nts(buf[265:297], encoding, errors) + obj.gname = nts(buf[297:329], encoding, errors) + obj.devmajor = nti(buf[329:337]) + obj.devminor = nti(buf[337:345]) + prefix = nts(buf[345:500], encoding, errors) + + # Old V7 tar format represents a directory as a regular + # file with a trailing slash. + if obj.type == AREGTYPE and obj.name.endswith("/"): + obj.type = DIRTYPE + + # The old GNU sparse format occupies some of the unused + # space in the buffer for up to 4 sparse structures. + # Save the them for later processing in _proc_sparse(). + if obj.type == GNUTYPE_SPARSE: + pos = 386 + structs = [] + for i in range(4): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[482]) + origsize = nti(buf[483:495]) + obj._sparse_structs = (structs, isextended, origsize) + + # Remove redundant slashes from directories. + if obj.isdir(): + obj.name = obj.name.rstrip("/") + + # Reconstruct a ustar longname. + if prefix and obj.type not in GNU_TYPES: + obj.name = prefix + "/" + obj.name + return obj + + @classmethod + def fromtarfile(cls, tarfile): + """Return the next TarInfo object from TarFile object + tarfile. + """ + buf = tarfile.fileobj.read(BLOCKSIZE) + obj = cls.frombuf(buf, tarfile.encoding, tarfile.errors) + obj.offset = tarfile.fileobj.tell() - BLOCKSIZE + return obj._proc_member(tarfile) + + #-------------------------------------------------------------------------- + # The following are methods that are called depending on the type of a + # member. The entry point is _proc_member() which can be overridden in a + # subclass to add custom _proc_*() methods. A _proc_*() method MUST + # implement the following + # operations: + # 1. Set self.offset_data to the position where the data blocks begin, + # if there is data that follows. + # 2. Set tarfile.offset to the position where the next member's header will + # begin. + # 3. Return self or another valid TarInfo object. + def _proc_member(self, tarfile): + """Choose the right processing method depending on + the type and call it. + """ + if self.type in (GNUTYPE_LONGNAME, GNUTYPE_LONGLINK): + return self._proc_gnulong(tarfile) + elif self.type == GNUTYPE_SPARSE: + return self._proc_sparse(tarfile) + elif self.type in (XHDTYPE, XGLTYPE, SOLARIS_XHDTYPE): + return self._proc_pax(tarfile) + else: + return self._proc_builtin(tarfile) + + def _proc_builtin(self, tarfile): + """Process a builtin type or an unknown type which + will be treated as a regular file. + """ + self.offset_data = tarfile.fileobj.tell() + offset = self.offset_data + if self.isreg() or self.type not in SUPPORTED_TYPES: + # Skip the following data blocks. + offset += self._block(self.size) + tarfile.offset = offset + + # Patch the TarInfo object with saved global + # header information. + self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors) + + return self + + def _proc_gnulong(self, tarfile): + """Process the blocks that hold a GNU longname + or longlink member. + """ + buf = tarfile.fileobj.read(self._block(self.size)) + + # Fetch the next header and process it. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Patch the TarInfo object from the next header with + # the longname information. + next.offset = self.offset + if self.type == GNUTYPE_LONGNAME: + next.name = nts(buf, tarfile.encoding, tarfile.errors) + elif self.type == GNUTYPE_LONGLINK: + next.linkname = nts(buf, tarfile.encoding, tarfile.errors) + + return next + + def _proc_sparse(self, tarfile): + """Process a GNU sparse header plus extra headers. + """ + # We already collected some sparse structures in frombuf(). + structs, isextended, origsize = self._sparse_structs + del self._sparse_structs + + # Collect sparse structures from extended header blocks. + while isextended: + buf = tarfile.fileobj.read(BLOCKSIZE) + pos = 0 + for i in range(21): + try: + offset = nti(buf[pos:pos + 12]) + numbytes = nti(buf[pos + 12:pos + 24]) + except ValueError: + break + if offset and numbytes: + structs.append((offset, numbytes)) + pos += 24 + isextended = bool(buf[504]) + self.sparse = structs + + self.offset_data = tarfile.fileobj.tell() + tarfile.offset = self.offset_data + self._block(self.size) + self.size = origsize + return self + + def _proc_pax(self, tarfile): + """Process an extended or global header as described in + POSIX.1-2008. + """ + # Read the header information. + buf = tarfile.fileobj.read(self._block(self.size)) + + # A pax header stores supplemental information for either + # the following file (extended) or all following files + # (global). + if self.type == XGLTYPE: + pax_headers = tarfile.pax_headers + else: + pax_headers = tarfile.pax_headers.copy() + + # Check if the pax header contains a hdrcharset field. This tells us + # the encoding of the path, linkpath, uname and gname fields. Normally, + # these fields are UTF-8 encoded but since POSIX.1-2008 tar + # implementations are allowed to store them as raw binary strings if + # the translation to UTF-8 fails. + match = re.search(br"\d+ hdrcharset=([^\n]+)\n", buf) + if match is not None: + pax_headers["hdrcharset"] = match.group(1).decode("utf8") + + # For the time being, we don't care about anything other than "BINARY". + # The only other value that is currently allowed by the standard is + # "ISO-IR 10646 2000 UTF-8" in other words UTF-8. + hdrcharset = pax_headers.get("hdrcharset") + if hdrcharset == "BINARY": + encoding = tarfile.encoding + else: + encoding = "utf8" + + # Parse pax header information. A record looks like that: + # "%d %s=%s\n" % (length, keyword, value). length is the size + # of the complete record including the length field itself and + # the newline. keyword and value are both UTF-8 encoded strings. + regex = re.compile(br"(\d+) ([^=]+)=") + pos = 0 + while True: + match = regex.match(buf, pos) + if not match: + break + + length, keyword = match.groups() + length = int(length) + value = buf[match.end(2) + 1:match.start(1) + length - 1] + + # Normally, we could just use "utf8" as the encoding and "strict" + # as the error handler, but we better not take the risk. For + # example, GNU tar <= 1.23 is known to store filenames it cannot + # translate to UTF-8 as raw strings (unfortunately without a + # hdrcharset=BINARY header). + # We first try the strict standard encoding, and if that fails we + # fall back on the user's encoding and error handler. + keyword = self._decode_pax_field(keyword, "utf8", "utf8", + tarfile.errors) + if keyword in PAX_NAME_FIELDS: + value = self._decode_pax_field(value, encoding, tarfile.encoding, + tarfile.errors) + else: + value = self._decode_pax_field(value, "utf8", "utf8", + tarfile.errors) + + pax_headers[keyword] = value + pos += length + + # Fetch the next header. + try: + next = self.fromtarfile(tarfile) + except HeaderError: + raise SubsequentHeaderError("missing or bad subsequent header") + + # Process GNU sparse information. + if "GNU.sparse.map" in pax_headers: + # GNU extended sparse format version 0.1. + self._proc_gnusparse_01(next, pax_headers) + + elif "GNU.sparse.size" in pax_headers: + # GNU extended sparse format version 0.0. + self._proc_gnusparse_00(next, pax_headers, buf) + + elif pax_headers.get("GNU.sparse.major") == "1" and pax_headers.get("GNU.sparse.minor") == "0": + # GNU extended sparse format version 1.0. + self._proc_gnusparse_10(next, pax_headers, tarfile) + + if self.type in (XHDTYPE, SOLARIS_XHDTYPE): + # Patch the TarInfo object with the extended header info. + next._apply_pax_info(pax_headers, tarfile.encoding, tarfile.errors) + next.offset = self.offset + + if "size" in pax_headers: + # If the extended header replaces the size field, + # we need to recalculate the offset where the next + # header starts. + offset = next.offset_data + if next.isreg() or next.type not in SUPPORTED_TYPES: + offset += next._block(next.size) + tarfile.offset = offset + + return next + + def _proc_gnusparse_00(self, next, pax_headers, buf): + """Process a GNU tar extended sparse header, version 0.0. + """ + offsets = [] + for match in re.finditer(br"\d+ GNU.sparse.offset=(\d+)\n", buf): + offsets.append(int(match.group(1))) + numbytes = [] + for match in re.finditer(br"\d+ GNU.sparse.numbytes=(\d+)\n", buf): + numbytes.append(int(match.group(1))) + next.sparse = list(zip(offsets, numbytes)) + + def _proc_gnusparse_01(self, next, pax_headers): + """Process a GNU tar extended sparse header, version 0.1. + """ + sparse = [int(x) for x in pax_headers["GNU.sparse.map"].split(",")] + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _proc_gnusparse_10(self, next, pax_headers, tarfile): + """Process a GNU tar extended sparse header, version 1.0. + """ + fields = None + sparse = [] + buf = tarfile.fileobj.read(BLOCKSIZE) + fields, buf = buf.split(b"\n", 1) + fields = int(fields) + while len(sparse) < fields * 2: + if b"\n" not in buf: + buf += tarfile.fileobj.read(BLOCKSIZE) + number, buf = buf.split(b"\n", 1) + sparse.append(int(number)) + next.offset_data = tarfile.fileobj.tell() + next.sparse = list(zip(sparse[::2], sparse[1::2])) + + def _apply_pax_info(self, pax_headers, encoding, errors): + """Replace fields with supplemental information from a previous + pax extended or global header. + """ + for keyword, value in pax_headers.items(): + if keyword == "GNU.sparse.name": + setattr(self, "path", value) + elif keyword == "GNU.sparse.size": + setattr(self, "size", int(value)) + elif keyword == "GNU.sparse.realsize": + setattr(self, "size", int(value)) + elif keyword in PAX_FIELDS: + if keyword in PAX_NUMBER_FIELDS: + try: + value = PAX_NUMBER_FIELDS[keyword](value) + except ValueError: + value = 0 + if keyword == "path": + value = value.rstrip("/") + setattr(self, keyword, value) + + self.pax_headers = pax_headers.copy() + + def _decode_pax_field(self, value, encoding, fallback_encoding, fallback_errors): + """Decode a single field from a pax record. + """ + try: + return value.decode(encoding, "strict") + except UnicodeDecodeError: + return value.decode(fallback_encoding, fallback_errors) + + def _block(self, count): + """Round up a byte count by BLOCKSIZE and return it, + e.g. _block(834) => 1024. + """ + blocks, remainder = divmod(count, BLOCKSIZE) + if remainder: + blocks += 1 + return blocks * BLOCKSIZE + + def isreg(self): + return self.type in REGULAR_TYPES + def isfile(self): + return self.isreg() + def isdir(self): + return self.type == DIRTYPE + def issym(self): + return self.type == SYMTYPE + def islnk(self): + return self.type == LNKTYPE + def ischr(self): + return self.type == CHRTYPE + def isblk(self): + return self.type == BLKTYPE + def isfifo(self): + return self.type == FIFOTYPE + def issparse(self): + return self.sparse is not None + def isdev(self): + return self.type in (CHRTYPE, BLKTYPE, FIFOTYPE) +# class TarInfo + +class TarFile(object): + """The TarFile Class provides an interface to tar archives. + """ + + debug = 0 # May be set from 0 (no msgs) to 3 (all msgs) + + dereference = False # If true, add content of linked file to the + # tar file, else the link. + + ignore_zeros = False # If true, skips empty or invalid blocks and + # continues processing. + + errorlevel = 1 # If 0, fatal errors only appear in debug + # messages (if debug >= 0). If > 0, errors + # are passed to the caller as exceptions. + + format = DEFAULT_FORMAT # The format to use when creating an archive. + + encoding = ENCODING # Encoding for 8-bit character strings. + + errors = None # Error handler for unicode conversion. + + tarinfo = TarInfo # The default TarInfo class to use. + + fileobject = ExFileObject # The default ExFileObject class to use. + + def __init__(self, name=None, mode="r", fileobj=None, format=None, + tarinfo=None, dereference=None, ignore_zeros=None, encoding=None, + errors="surrogateescape", pax_headers=None, debug=None, errorlevel=None): + """Open an (uncompressed) tar archive `name'. `mode' is either 'r' to + read from an existing archive, 'a' to append data to an existing + file or 'w' to create a new file overwriting an existing one. `mode' + defaults to 'r'. + If `fileobj' is given, it is used for reading or writing data. If it + can be determined, `mode' is overridden by `fileobj's mode. + `fileobj' is not closed, when TarFile is closed. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + self.mode = mode + self._mode = {"r": "rb", "a": "r+b", "w": "wb"}[mode] + + if not fileobj: + if self.mode == "a" and not os.path.exists(name): + # Create nonexistent files in append mode. + self.mode = "w" + self._mode = "wb" + fileobj = bltn_open(name, self._mode) + self._extfileobj = False + else: + if name is None and hasattr(fileobj, "name"): + name = fileobj.name + if hasattr(fileobj, "mode"): + self._mode = fileobj.mode + self._extfileobj = True + self.name = os.path.abspath(name) if name else None + self.fileobj = fileobj + + # Init attributes. + if format is not None: + self.format = format + if tarinfo is not None: + self.tarinfo = tarinfo + if dereference is not None: + self.dereference = dereference + if ignore_zeros is not None: + self.ignore_zeros = ignore_zeros + if encoding is not None: + self.encoding = encoding + self.errors = errors + + if pax_headers is not None and self.format == PAX_FORMAT: + self.pax_headers = pax_headers + else: + self.pax_headers = {} + + if debug is not None: + self.debug = debug + if errorlevel is not None: + self.errorlevel = errorlevel + + # Init datastructures. + self.closed = False + self.members = [] # list of members as TarInfo objects + self._loaded = False # flag if all members have been read + self.offset = self.fileobj.tell() + # current position in the archive file + self.inodes = {} # dictionary caching the inodes of + # archive members already added + + try: + if self.mode == "r": + self.firstmember = None + self.firstmember = self.next() + + if self.mode == "a": + # Move to the end of the archive, + # before the first empty block. + while True: + self.fileobj.seek(self.offset) + try: + tarinfo = self.tarinfo.fromtarfile(self) + self.members.append(tarinfo) + except EOFHeaderError: + self.fileobj.seek(self.offset) + break + except HeaderError as e: + raise ReadError(str(e)) + + if self.mode in "aw": + self._loaded = True + + if self.pax_headers: + buf = self.tarinfo.create_pax_global_header(self.pax_headers.copy()) + self.fileobj.write(buf) + self.offset += len(buf) + except: + if not self._extfileobj: + self.fileobj.close() + self.closed = True + raise + + #-------------------------------------------------------------------------- + # Below are the classmethods which act as alternate constructors to the + # TarFile class. The open() method is the only one that is needed for + # public use; it is the "super"-constructor and is able to select an + # adequate "sub"-constructor for a particular compression using the mapping + # from OPEN_METH. + # + # This concept allows one to subclass TarFile without losing the comfort of + # the super-constructor. A sub-constructor is registered and made available + # by adding it to the mapping in OPEN_METH. + + @classmethod + def open(cls, name=None, mode="r", fileobj=None, bufsize=RECORDSIZE, **kwargs): + """Open a tar archive for reading, writing or appending. Return + an appropriate TarFile class. + + mode: + 'r' or 'r:*' open for reading with transparent compression + 'r:' open for reading exclusively uncompressed + 'r:gz' open for reading with gzip compression + 'r:bz2' open for reading with bzip2 compression + 'a' or 'a:' open for appending, creating the file if necessary + 'w' or 'w:' open for writing without compression + 'w:gz' open for writing with gzip compression + 'w:bz2' open for writing with bzip2 compression + + 'r|*' open a stream of tar blocks with transparent compression + 'r|' open an uncompressed stream of tar blocks for reading + 'r|gz' open a gzip compressed stream of tar blocks + 'r|bz2' open a bzip2 compressed stream of tar blocks + 'w|' open an uncompressed stream for writing + 'w|gz' open a gzip compressed stream for writing + 'w|bz2' open a bzip2 compressed stream for writing + """ + + if not name and not fileobj: + raise ValueError("nothing to open") + + if mode in ("r", "r:*"): + # Find out which *open() is appropriate for opening the file. + for comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + if fileobj is not None: + saved_pos = fileobj.tell() + try: + return func(name, "r", fileobj, **kwargs) + except (ReadError, CompressionError) as e: + if fileobj is not None: + fileobj.seek(saved_pos) + continue + raise ReadError("file could not be opened successfully") + + elif ":" in mode: + filemode, comptype = mode.split(":", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + # Select the *open() function according to + # given compression. + if comptype in cls.OPEN_METH: + func = getattr(cls, cls.OPEN_METH[comptype]) + else: + raise CompressionError("unknown compression type %r" % comptype) + return func(name, filemode, fileobj, **kwargs) + + elif "|" in mode: + filemode, comptype = mode.split("|", 1) + filemode = filemode or "r" + comptype = comptype or "tar" + + if filemode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + stream = _Stream(name, filemode, comptype, fileobj, bufsize) + try: + t = cls(name, filemode, stream, **kwargs) + except: + stream.close() + raise + t._extfileobj = False + return t + + elif mode in "aw": + return cls.taropen(name, mode, fileobj, **kwargs) + + raise ValueError("undiscernible mode") + + @classmethod + def taropen(cls, name, mode="r", fileobj=None, **kwargs): + """Open uncompressed tar archive name for reading or writing. + """ + if len(mode) > 1 or mode not in "raw": + raise ValueError("mode must be 'r', 'a' or 'w'") + return cls(name, mode, fileobj, **kwargs) + + @classmethod + def gzopen(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open gzip compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'") + + try: + import gzip + gzip.GzipFile + except (ImportError, AttributeError): + raise CompressionError("gzip module is not available") + + extfileobj = fileobj is not None + try: + fileobj = gzip.GzipFile(name, mode + "b", compresslevel, fileobj) + t = cls.taropen(name, mode, fileobj, **kwargs) + except IOError: + if not extfileobj and fileobj is not None: + fileobj.close() + if fileobj is None: + raise + raise ReadError("not a gzip file") + except: + if not extfileobj and fileobj is not None: + fileobj.close() + raise + t._extfileobj = extfileobj + return t + + @classmethod + def bz2open(cls, name, mode="r", fileobj=None, compresslevel=9, **kwargs): + """Open bzip2 compressed tar archive name for reading or writing. + Appending is not allowed. + """ + if len(mode) > 1 or mode not in "rw": + raise ValueError("mode must be 'r' or 'w'.") + + try: + import bz2 + except ImportError: + raise CompressionError("bz2 module is not available") + + if fileobj is not None: + fileobj = _BZ2Proxy(fileobj, mode) + else: + fileobj = bz2.BZ2File(name, mode, compresslevel=compresslevel) + + try: + t = cls.taropen(name, mode, fileobj, **kwargs) + except (IOError, EOFError): + fileobj.close() + raise ReadError("not a bzip2 file") + t._extfileobj = False + return t + + # All *open() methods are registered here. + OPEN_METH = { + "tar": "taropen", # uncompressed tar + "gz": "gzopen", # gzip compressed tar + "bz2": "bz2open" # bzip2 compressed tar + } + + #-------------------------------------------------------------------------- + # The public methods which TarFile provides: + + def close(self): + """Close the TarFile. In write-mode, two finishing zero blocks are + appended to the archive. + """ + if self.closed: + return + + if self.mode in "aw": + self.fileobj.write(NUL * (BLOCKSIZE * 2)) + self.offset += (BLOCKSIZE * 2) + # fill up the end with zero-blocks + # (like option -b20 for tar does) + blocks, remainder = divmod(self.offset, RECORDSIZE) + if remainder > 0: + self.fileobj.write(NUL * (RECORDSIZE - remainder)) + + if not self._extfileobj: + self.fileobj.close() + self.closed = True + + def getmember(self, name): + """Return a TarInfo object for member `name'. If `name' can not be + found in the archive, KeyError is raised. If a member occurs more + than once in the archive, its last occurrence is assumed to be the + most up-to-date version. + """ + tarinfo = self._getmember(name) + if tarinfo is None: + raise KeyError("filename %r not found" % name) + return tarinfo + + def getmembers(self): + """Return the members of the archive as a list of TarInfo objects. The + list has the same order as the members in the archive. + """ + self._check() + if not self._loaded: # if we want to obtain a list of + self._load() # all members, we first have to + # scan the whole archive. + return self.members + + def getnames(self): + """Return the members of the archive as a list of their names. It has + the same order as the list returned by getmembers(). + """ + return [tarinfo.name for tarinfo in self.getmembers()] + + def gettarinfo(self, name=None, arcname=None, fileobj=None): + """Create a TarInfo object for either the file `name' or the file + object `fileobj' (using os.fstat on its file descriptor). You can + modify some of the TarInfo's attributes before you add it using + addfile(). If given, `arcname' specifies an alternative name for the + file in the archive. + """ + self._check("aw") + + # When fileobj is given, replace name by + # fileobj's real name. + if fileobj is not None: + name = fileobj.name + + # Building the name of the member in the archive. + # Backward slashes are converted to forward slashes, + # Absolute paths are turned to relative paths. + if arcname is None: + arcname = name + drv, arcname = os.path.splitdrive(arcname) + arcname = arcname.replace(os.sep, "/") + arcname = arcname.lstrip("/") + + # Now, fill the TarInfo object with + # information specific for the file. + tarinfo = self.tarinfo() + tarinfo.tarfile = self + + # Use os.stat or os.lstat, depending on platform + # and if symlinks shall be resolved. + if fileobj is None: + if hasattr(os, "lstat") and not self.dereference: + statres = os.lstat(name) + else: + statres = os.stat(name) + else: + statres = os.fstat(fileobj.fileno()) + linkname = "" + + stmd = statres.st_mode + if stat.S_ISREG(stmd): + inode = (statres.st_ino, statres.st_dev) + if not self.dereference and statres.st_nlink > 1 and \ + inode in self.inodes and arcname != self.inodes[inode]: + # Is it a hardlink to an already + # archived file? + type = LNKTYPE + linkname = self.inodes[inode] + else: + # The inode is added only if its valid. + # For win32 it is always 0. + type = REGTYPE + if inode[0]: + self.inodes[inode] = arcname + elif stat.S_ISDIR(stmd): + type = DIRTYPE + elif stat.S_ISFIFO(stmd): + type = FIFOTYPE + elif stat.S_ISLNK(stmd): + type = SYMTYPE + linkname = os.readlink(name) + elif stat.S_ISCHR(stmd): + type = CHRTYPE + elif stat.S_ISBLK(stmd): + type = BLKTYPE + else: + return None + + # Fill the TarInfo object with all + # information we can get. + tarinfo.name = arcname + tarinfo.mode = stmd + tarinfo.uid = statres.st_uid + tarinfo.gid = statres.st_gid + if type == REGTYPE: + tarinfo.size = statres.st_size + else: + tarinfo.size = 0 + tarinfo.mtime = statres.st_mtime + tarinfo.type = type + tarinfo.linkname = linkname + if pwd: + try: + tarinfo.uname = pwd.getpwuid(tarinfo.uid)[0] + except KeyError: + pass + if grp: + try: + tarinfo.gname = grp.getgrgid(tarinfo.gid)[0] + except KeyError: + pass + + if type in (CHRTYPE, BLKTYPE): + if hasattr(os, "major") and hasattr(os, "minor"): + tarinfo.devmajor = os.major(statres.st_rdev) + tarinfo.devminor = os.minor(statres.st_rdev) + return tarinfo + + def list(self, verbose=True): + """Print a table of contents to sys.stdout. If `verbose' is False, only + the names of the members are printed. If it is True, an `ls -l'-like + output is produced. + """ + self._check() + + for tarinfo in self: + if verbose: + print(filemode(tarinfo.mode), end=' ') + print("%s/%s" % (tarinfo.uname or tarinfo.uid, + tarinfo.gname or tarinfo.gid), end=' ') + if tarinfo.ischr() or tarinfo.isblk(): + print("%10s" % ("%d,%d" \ + % (tarinfo.devmajor, tarinfo.devminor)), end=' ') + else: + print("%10d" % tarinfo.size, end=' ') + print("%d-%02d-%02d %02d:%02d:%02d" \ + % time.localtime(tarinfo.mtime)[:6], end=' ') + + print(tarinfo.name + ("/" if tarinfo.isdir() else ""), end=' ') + + if verbose: + if tarinfo.issym(): + print("->", tarinfo.linkname, end=' ') + if tarinfo.islnk(): + print("link to", tarinfo.linkname, end=' ') + print() + + def add(self, name, arcname=None, recursive=True, exclude=None, filter=None): + """Add the file `name' to the archive. `name' may be any type of file + (directory, fifo, symbolic link, etc.). If given, `arcname' + specifies an alternative name for the file in the archive. + Directories are added recursively by default. This can be avoided by + setting `recursive' to False. `exclude' is a function that should + return True for each filename to be excluded. `filter' is a function + that expects a TarInfo object argument and returns the changed + TarInfo object, if it returns None the TarInfo object will be + excluded from the archive. + """ + self._check("aw") + + if arcname is None: + arcname = name + + # Exclude pathnames. + if exclude is not None: + import warnings + warnings.warn("use the filter argument instead", + DeprecationWarning, 2) + if exclude(name): + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Skip if somebody tries to archive the archive... + if self.name is not None and os.path.abspath(name) == self.name: + self._dbg(2, "tarfile: Skipped %r" % name) + return + + self._dbg(1, name) + + # Create a TarInfo object from the file. + tarinfo = self.gettarinfo(name, arcname) + + if tarinfo is None: + self._dbg(1, "tarfile: Unsupported type %r" % name) + return + + # Change or exclude the TarInfo object. + if filter is not None: + tarinfo = filter(tarinfo) + if tarinfo is None: + self._dbg(2, "tarfile: Excluded %r" % name) + return + + # Append the tar header and data to the archive. + if tarinfo.isreg(): + f = bltn_open(name, "rb") + self.addfile(tarinfo, f) + f.close() + + elif tarinfo.isdir(): + self.addfile(tarinfo) + if recursive: + for f in os.listdir(name): + self.add(os.path.join(name, f), os.path.join(arcname, f), + recursive, exclude, filter=filter) + + else: + self.addfile(tarinfo) + + def addfile(self, tarinfo, fileobj=None): + """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is + given, tarinfo.size bytes are read from it and added to the archive. + You can create TarInfo objects using gettarinfo(). + On Windows platforms, `fileobj' should always be opened with mode + 'rb' to avoid irritation about the file size. + """ + self._check("aw") + + tarinfo = copy.copy(tarinfo) + + buf = tarinfo.tobuf(self.format, self.encoding, self.errors) + self.fileobj.write(buf) + self.offset += len(buf) + + # If there's data to follow, append it. + if fileobj is not None: + copyfileobj(fileobj, self.fileobj, tarinfo.size) + blocks, remainder = divmod(tarinfo.size, BLOCKSIZE) + if remainder > 0: + self.fileobj.write(NUL * (BLOCKSIZE - remainder)) + blocks += 1 + self.offset += blocks * BLOCKSIZE + + self.members.append(tarinfo) + + def extractall(self, path=".", members=None): + """Extract all members from the archive to the current working + directory and set owner, modification time and permissions on + directories afterwards. `path' specifies a different directory + to extract to. `members' is optional and must be a subset of the + list returned by getmembers(). + """ + directories = [] + + if members is None: + members = self + + for tarinfo in members: + if tarinfo.isdir(): + # Extract directories with a safe mode. + directories.append(tarinfo) + tarinfo = copy.copy(tarinfo) + tarinfo.mode = 0o700 + # Do not set_attrs directories, as we will do that further down + self.extract(tarinfo, path, set_attrs=not tarinfo.isdir()) + + # Reverse sort directories. + directories.sort(key=lambda a: a.name) + directories.reverse() + + # Set correct owner, mtime and filemode on directories. + for tarinfo in directories: + dirpath = os.path.join(path, tarinfo.name) + try: + self.chown(tarinfo, dirpath) + self.utime(tarinfo, dirpath) + self.chmod(tarinfo, dirpath) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extract(self, member, path="", set_attrs=True): + """Extract a member from the archive to the current working directory, + using its full name. Its file information is extracted as accurately + as possible. `member' may be a filename or a TarInfo object. You can + specify a different directory using `path'. File attributes (owner, + mtime, mode) are set unless `set_attrs' is False. + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + # Prepare the link target for makelink(). + if tarinfo.islnk(): + tarinfo._link_target = os.path.join(path, tarinfo.linkname) + + try: + self._extract_member(tarinfo, os.path.join(path, tarinfo.name), + set_attrs=set_attrs) + except EnvironmentError as e: + if self.errorlevel > 0: + raise + else: + if e.filename is None: + self._dbg(1, "tarfile: %s" % e.strerror) + else: + self._dbg(1, "tarfile: %s %r" % (e.strerror, e.filename)) + except ExtractError as e: + if self.errorlevel > 1: + raise + else: + self._dbg(1, "tarfile: %s" % e) + + def extractfile(self, member): + """Extract a member from the archive as a file object. `member' may be + a filename or a TarInfo object. If `member' is a regular file, a + file-like object is returned. If `member' is a link, a file-like + object is constructed from the link's target. If `member' is none of + the above, None is returned. + The file-like object is read-only and provides the following + methods: read(), readline(), readlines(), seek() and tell() + """ + self._check("r") + + if isinstance(member, str): + tarinfo = self.getmember(member) + else: + tarinfo = member + + if tarinfo.isreg(): + return self.fileobject(self, tarinfo) + + elif tarinfo.type not in SUPPORTED_TYPES: + # If a member's type is unknown, it is treated as a + # regular file. + return self.fileobject(self, tarinfo) + + elif tarinfo.islnk() or tarinfo.issym(): + if isinstance(self.fileobj, _Stream): + # A small but ugly workaround for the case that someone tries + # to extract a (sym)link as a file-object from a non-seekable + # stream of tar blocks. + raise StreamError("cannot extract (sym)link as file object") + else: + # A (sym)link's file object is its target's file object. + return self.extractfile(self._find_link_target(tarinfo)) + else: + # If there's no data associated with the member (directory, chrdev, + # blkdev, etc.), return None instead of a file object. + return None + + def _extract_member(self, tarinfo, targetpath, set_attrs=True): + """Extract the TarInfo object tarinfo to a physical + file called targetpath. + """ + # Fetch the TarInfo object for the given name + # and build the destination pathname, replacing + # forward slashes to platform specific separators. + targetpath = targetpath.rstrip("/") + targetpath = targetpath.replace("/", os.sep) + + # Create all upper directories. + upperdirs = os.path.dirname(targetpath) + if upperdirs and not os.path.exists(upperdirs): + # Create directories that are not part of the archive with + # default permissions. + os.makedirs(upperdirs) + + if tarinfo.islnk() or tarinfo.issym(): + self._dbg(1, "%s -> %s" % (tarinfo.name, tarinfo.linkname)) + else: + self._dbg(1, tarinfo.name) + + if tarinfo.isreg(): + self.makefile(tarinfo, targetpath) + elif tarinfo.isdir(): + self.makedir(tarinfo, targetpath) + elif tarinfo.isfifo(): + self.makefifo(tarinfo, targetpath) + elif tarinfo.ischr() or tarinfo.isblk(): + self.makedev(tarinfo, targetpath) + elif tarinfo.islnk() or tarinfo.issym(): + self.makelink(tarinfo, targetpath) + elif tarinfo.type not in SUPPORTED_TYPES: + self.makeunknown(tarinfo, targetpath) + else: + self.makefile(tarinfo, targetpath) + + if set_attrs: + self.chown(tarinfo, targetpath) + if not tarinfo.issym(): + self.chmod(tarinfo, targetpath) + self.utime(tarinfo, targetpath) + + #-------------------------------------------------------------------------- + # Below are the different file methods. They are called via + # _extract_member() when extract() is called. They can be replaced in a + # subclass to implement other functionality. + + def makedir(self, tarinfo, targetpath): + """Make a directory called targetpath. + """ + try: + # Use a safe mode for the directory, the real mode is set + # later in _extract_member(). + os.mkdir(targetpath, 0o700) + except EnvironmentError as e: + if e.errno != errno.EEXIST: + raise + + def makefile(self, tarinfo, targetpath): + """Make a file called targetpath. + """ + source = self.fileobj + source.seek(tarinfo.offset_data) + target = bltn_open(targetpath, "wb") + if tarinfo.sparse is not None: + for offset, size in tarinfo.sparse: + target.seek(offset) + copyfileobj(source, target, size) + else: + copyfileobj(source, target, tarinfo.size) + target.seek(tarinfo.size) + target.truncate() + target.close() + + def makeunknown(self, tarinfo, targetpath): + """Make a file from a TarInfo object with an unknown type + at targetpath. + """ + self.makefile(tarinfo, targetpath) + self._dbg(1, "tarfile: Unknown file type %r, " \ + "extracted as regular file." % tarinfo.type) + + def makefifo(self, tarinfo, targetpath): + """Make a fifo called targetpath. + """ + if hasattr(os, "mkfifo"): + os.mkfifo(targetpath) + else: + raise ExtractError("fifo not supported by system") + + def makedev(self, tarinfo, targetpath): + """Make a character or block device called targetpath. + """ + if not hasattr(os, "mknod") or not hasattr(os, "makedev"): + raise ExtractError("special devices not supported by system") + + mode = tarinfo.mode + if tarinfo.isblk(): + mode |= stat.S_IFBLK + else: + mode |= stat.S_IFCHR + + os.mknod(targetpath, mode, + os.makedev(tarinfo.devmajor, tarinfo.devminor)) + + def makelink(self, tarinfo, targetpath): + """Make a (symbolic) link called targetpath. If it cannot be created + (platform limitation), we try to make a copy of the referenced file + instead of a link. + """ + try: + # For systems that support symbolic and hard links. + if tarinfo.issym(): + os.symlink(tarinfo.linkname, targetpath) + else: + # See extract(). + if os.path.exists(tarinfo._link_target): + os.link(tarinfo._link_target, targetpath) + else: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except symlink_exception: + if tarinfo.issym(): + linkpath = os.path.join(os.path.dirname(tarinfo.name), + tarinfo.linkname) + else: + linkpath = tarinfo.linkname + else: + try: + self._extract_member(self._find_link_target(tarinfo), + targetpath) + except KeyError: + raise ExtractError("unable to resolve link inside archive") + + def chown(self, tarinfo, targetpath): + """Set owner of targetpath according to tarinfo. + """ + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + g = tarinfo.gid + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + u = tarinfo.uid + try: + if tarinfo.issym() and hasattr(os, "lchown"): + os.lchown(targetpath, u, g) + else: + if sys.platform != "os2emx": + os.chown(targetpath, u, g) + except EnvironmentError as e: + raise ExtractError("could not change owner") + + def chmod(self, tarinfo, targetpath): + """Set file permissions of targetpath according to tarinfo. + """ + if hasattr(os, 'chmod'): + try: + os.chmod(targetpath, tarinfo.mode) + except EnvironmentError as e: + raise ExtractError("could not change mode") + + def utime(self, tarinfo, targetpath): + """Set modification time of targetpath according to tarinfo. + """ + if not hasattr(os, 'utime'): + return + try: + os.utime(targetpath, (tarinfo.mtime, tarinfo.mtime)) + except EnvironmentError as e: + raise ExtractError("could not change modification time") + + #-------------------------------------------------------------------------- + def next(self): + """Return the next member of the archive as a TarInfo object, when + TarFile is opened for reading. Return None if there is no more + available. + """ + self._check("ra") + if self.firstmember is not None: + m = self.firstmember + self.firstmember = None + return m + + # Read the next block. + self.fileobj.seek(self.offset) + tarinfo = None + while True: + try: + tarinfo = self.tarinfo.fromtarfile(self) + except EOFHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + except InvalidHeaderError as e: + if self.ignore_zeros: + self._dbg(2, "0x%X: %s" % (self.offset, e)) + self.offset += BLOCKSIZE + continue + elif self.offset == 0: + raise ReadError(str(e)) + except EmptyHeaderError: + if self.offset == 0: + raise ReadError("empty file") + except TruncatedHeaderError as e: + if self.offset == 0: + raise ReadError(str(e)) + except SubsequentHeaderError as e: + raise ReadError(str(e)) + break + + if tarinfo is not None: + self.members.append(tarinfo) + else: + self._loaded = True + + return tarinfo + + #-------------------------------------------------------------------------- + # Little helper methods: + + def _getmember(self, name, tarinfo=None, normalize=False): + """Find an archive member by name from bottom to top. + If tarinfo is given, it is used as the starting point. + """ + # Ensure that all members have been loaded. + members = self.getmembers() + + # Limit the member search list up to tarinfo. + if tarinfo is not None: + members = members[:members.index(tarinfo)] + + if normalize: + name = os.path.normpath(name) + + for member in reversed(members): + if normalize: + member_name = os.path.normpath(member.name) + else: + member_name = member.name + + if name == member_name: + return member + + def _load(self): + """Read through the entire archive file and look for readable + members. + """ + while True: + tarinfo = self.next() + if tarinfo is None: + break + self._loaded = True + + def _check(self, mode=None): + """Check if TarFile is still open, and if the operation's mode + corresponds to TarFile's mode. + """ + if self.closed: + raise IOError("%s is closed" % self.__class__.__name__) + if mode is not None and self.mode not in mode: + raise IOError("bad operation for mode %r" % self.mode) + + def _find_link_target(self, tarinfo): + """Find the target member of a symlink or hardlink member in the + archive. + """ + if tarinfo.issym(): + # Always search the entire archive. + linkname = os.path.dirname(tarinfo.name) + "/" + tarinfo.linkname + limit = None + else: + # Search the archive before the link, because a hard link is + # just a reference to an already archived file. + linkname = tarinfo.linkname + limit = tarinfo + + member = self._getmember(linkname, tarinfo=limit, normalize=True) + if member is None: + raise KeyError("linkname %r not found" % linkname) + return member + + def __iter__(self): + """Provide an iterator object. + """ + if self._loaded: + return iter(self.members) + else: + return TarIter(self) + + def _dbg(self, level, msg): + """Write debugging output to sys.stderr. + """ + if level <= self.debug: + print(msg, file=sys.stderr) + + def __enter__(self): + self._check() + return self + + def __exit__(self, type, value, traceback): + if type is None: + self.close() + else: + # An exception occurred. We must not call close() because + # it would try to write end-of-archive blocks and padding. + if not self._extfileobj: + self.fileobj.close() + self.closed = True +# class TarFile + +class TarIter(object): + """Iterator Class. + + for tarinfo in TarFile(...): + suite... + """ + + def __init__(self, tarfile): + """Construct a TarIter object. + """ + self.tarfile = tarfile + self.index = 0 + def __iter__(self): + """Return iterator object. + """ + return self + + def __next__(self): + """Return the next item using TarFile's next() method. + When all members have been read, set TarFile as _loaded. + """ + # Fix for SF #1100429: Under rare circumstances it can + # happen that getmembers() is called during iteration, + # which will cause TarIter to stop prematurely. + if not self.tarfile._loaded: + tarinfo = self.tarfile.next() + if not tarinfo: + self.tarfile._loaded = True + raise StopIteration + else: + try: + tarinfo = self.tarfile.members[self.index] + except IndexError: + raise StopIteration + self.index += 1 + return tarinfo + + next = __next__ # for Python 2.x + +#-------------------- +# exported functions +#-------------------- +def is_tarfile(name): + """Return True if name points to a tar archive that we + are able to handle, else return False. + """ + try: + t = open(name) + t.close() + return True + except TarError: + return False + +bltn_open = open +open = TarFile.open diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py new file mode 100644 index 0000000..ff328c8 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/compat.py @@ -0,0 +1,1120 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import absolute_import + +import os +import re +import sys + +try: + import ssl +except ImportError: # pragma: no cover + ssl = None + +if sys.version_info[0] < 3: # pragma: no cover + from StringIO import StringIO + string_types = basestring, + text_type = unicode + from types import FileType as file_type + import __builtin__ as builtins + import ConfigParser as configparser + from ._backport import shutil + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urlunsplit + from urllib import (urlretrieve, quote as _quote, unquote, url2pathname, + pathname2url, ContentTooShortError, splittype) + + def quote(s): + if isinstance(s, unicode): + s = s.encode('utf-8') + return _quote(s) + + import urllib2 + from urllib2 import (Request, urlopen, URLError, HTTPError, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib2 import HTTPSHandler + import httplib + import xmlrpclib + import Queue as queue + from HTMLParser import HTMLParser + import htmlentitydefs + raw_input = raw_input + from itertools import ifilter as filter + from itertools import ifilterfalse as filterfalse + + _userprog = None + def splituser(host): + """splituser('user[:passwd]@host[:port]') --> 'user[:passwd]', 'host[:port]'.""" + global _userprog + if _userprog is None: + import re + _userprog = re.compile('^(.*)@(.*)$') + + match = _userprog.match(host) + if match: return match.group(1, 2) + return None, host + +else: # pragma: no cover + from io import StringIO + string_types = str, + text_type = str + from io import TextIOWrapper as file_type + import builtins + import configparser + import shutil + from urllib.parse import (urlparse, urlunparse, urljoin, splituser, quote, + unquote, urlsplit, urlunsplit, splittype) + from urllib.request import (urlopen, urlretrieve, Request, url2pathname, + pathname2url, + HTTPBasicAuthHandler, HTTPPasswordMgr, + HTTPHandler, HTTPRedirectHandler, + build_opener) + if ssl: + from urllib.request import HTTPSHandler + from urllib.error import HTTPError, URLError, ContentTooShortError + import http.client as httplib + import urllib.request as urllib2 + import xmlrpc.client as xmlrpclib + import queue + from html.parser import HTMLParser + import html.entities as htmlentitydefs + raw_input = input + from itertools import filterfalse + filter = filter + +try: + from ssl import match_hostname, CertificateError +except ImportError: # pragma: no cover + class CertificateError(ValueError): + pass + + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + parts = dn.split('.') + leftmost, remainder = parts[0], parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + + def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") + + +try: + from types import SimpleNamespace as Container +except ImportError: # pragma: no cover + class Container(object): + """ + A generic container for when multiple values need to be returned + """ + def __init__(self, **kwargs): + self.__dict__.update(kwargs) + + +try: + from shutil import which +except ImportError: # pragma: no cover + # Implementation from Python 3.3 + def which(cmd, mode=os.F_OK | os.X_OK, path=None): + """Given a command, mode, and a PATH string, return the path which + conforms to the given mode on the PATH, or None if there is no such + file. + + `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result + of os.environ.get("PATH"), or can be overridden with a custom search + path. + + """ + # Check that a given file can be accessed with the correct mode. + # Additionally check that `file` is not a directory, as on Windows + # directories pass the os.access check. + def _access_check(fn, mode): + return (os.path.exists(fn) and os.access(fn, mode) + and not os.path.isdir(fn)) + + # If we're given a path with a directory part, look it up directly rather + # than referring to PATH directories. This includes checking relative to the + # current directory, e.g. ./script + if os.path.dirname(cmd): + if _access_check(cmd, mode): + return cmd + return None + + if path is None: + path = os.environ.get("PATH", os.defpath) + if not path: + return None + path = path.split(os.pathsep) + + if sys.platform == "win32": + # The current directory takes precedence on Windows. + if not os.curdir in path: + path.insert(0, os.curdir) + + # PATHEXT is necessary to check on Windows. + pathext = os.environ.get("PATHEXT", "").split(os.pathsep) + # See if the given file matches any of the expected path extensions. + # This will allow us to short circuit when given "python.exe". + # If it does match, only test that one, otherwise we have to try + # others. + if any(cmd.lower().endswith(ext.lower()) for ext in pathext): + files = [cmd] + else: + files = [cmd + ext for ext in pathext] + else: + # On other platforms you don't have things like PATHEXT to tell you + # what file suffixes are executable, so just pass on cmd as-is. + files = [cmd] + + seen = set() + for dir in path: + normdir = os.path.normcase(dir) + if not normdir in seen: + seen.add(normdir) + for thefile in files: + name = os.path.join(dir, thefile) + if _access_check(name, mode): + return name + return None + + +# ZipFile is a context manager in 2.7, but not in 2.6 + +from zipfile import ZipFile as BaseZipFile + +if hasattr(BaseZipFile, '__enter__'): # pragma: no cover + ZipFile = BaseZipFile +else: # pragma: no cover + from zipfile import ZipExtFile as BaseZipExtFile + + class ZipExtFile(BaseZipExtFile): + def __init__(self, base): + self.__dict__.update(base.__dict__) + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + class ZipFile(BaseZipFile): + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.close() + # return None, so if an exception occurred, it will propagate + + def open(self, *args, **kwargs): + base = BaseZipFile.open(self, *args, **kwargs) + return ZipExtFile(base) + +try: + from platform import python_implementation +except ImportError: # pragma: no cover + def python_implementation(): + """Return a string identifying the Python implementation.""" + if 'PyPy' in sys.version: + return 'PyPy' + if os.name == 'java': + return 'Jython' + if sys.version.startswith('IronPython'): + return 'IronPython' + return 'CPython' + +try: + import sysconfig +except ImportError: # pragma: no cover + from ._backport import sysconfig + +try: + callable = callable +except NameError: # pragma: no cover + from collections import Callable + + def callable(obj): + return isinstance(obj, Callable) + + +try: + fsencode = os.fsencode + fsdecode = os.fsdecode +except AttributeError: # pragma: no cover + # Issue #99: on some systems (e.g. containerised), + # sys.getfilesystemencoding() returns None, and we need a real value, + # so fall back to utf-8. From the CPython 2.7 docs relating to Unix and + # sys.getfilesystemencoding(): the return value is "the user’s preference + # according to the result of nl_langinfo(CODESET), or None if the + # nl_langinfo(CODESET) failed." + _fsencoding = sys.getfilesystemencoding() or 'utf-8' + if _fsencoding == 'mbcs': + _fserrors = 'strict' + else: + _fserrors = 'surrogateescape' + + def fsencode(filename): + if isinstance(filename, bytes): + return filename + elif isinstance(filename, text_type): + return filename.encode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + + def fsdecode(filename): + if isinstance(filename, text_type): + return filename + elif isinstance(filename, bytes): + return filename.decode(_fsencoding, _fserrors) + else: + raise TypeError("expect bytes or str, not %s" % + type(filename).__name__) + +try: + from tokenize import detect_encoding +except ImportError: # pragma: no cover + from codecs import BOM_UTF8, lookup + import re + + cookie_re = re.compile(r"coding[:=]\s*([-\w.]+)") + + def _get_normal_name(orig_enc): + """Imitates get_normal_name in tokenizer.c.""" + # Only care about the first 12 characters. + enc = orig_enc[:12].lower().replace("_", "-") + if enc == "utf-8" or enc.startswith("utf-8-"): + return "utf-8" + if enc in ("latin-1", "iso-8859-1", "iso-latin-1") or \ + enc.startswith(("latin-1-", "iso-8859-1-", "iso-latin-1-")): + return "iso-8859-1" + return orig_enc + + def detect_encoding(readline): + """ + The detect_encoding() function is used to detect the encoding that should + be used to decode a Python source file. It requires one argument, readline, + in the same way as the tokenize() generator. + + It will call readline a maximum of twice, and return the encoding used + (as a string) and a list of any lines (left as bytes) it has read in. + + It detects the encoding from the presence of a utf-8 bom or an encoding + cookie as specified in pep-0263. If both a bom and a cookie are present, + but disagree, a SyntaxError will be raised. If the encoding cookie is an + invalid charset, raise a SyntaxError. Note that if a utf-8 bom is found, + 'utf-8-sig' is returned. + + If no encoding is specified, then the default of 'utf-8' will be returned. + """ + try: + filename = readline.__self__.name + except AttributeError: + filename = None + bom_found = False + encoding = None + default = 'utf-8' + def read_or_stop(): + try: + return readline() + except StopIteration: + return b'' + + def find_cookie(line): + try: + # Decode as UTF-8. Either the line is an encoding declaration, + # in which case it should be pure ASCII, or it must be UTF-8 + # per default encoding. + line_string = line.decode('utf-8') + except UnicodeDecodeError: + msg = "invalid or missing encoding declaration" + if filename is not None: + msg = '{} for {!r}'.format(msg, filename) + raise SyntaxError(msg) + + matches = cookie_re.findall(line_string) + if not matches: + return None + encoding = _get_normal_name(matches[0]) + try: + codec = lookup(encoding) + except LookupError: + # This behaviour mimics the Python interpreter + if filename is None: + msg = "unknown encoding: " + encoding + else: + msg = "unknown encoding for {!r}: {}".format(filename, + encoding) + raise SyntaxError(msg) + + if bom_found: + if codec.name != 'utf-8': + # This behaviour mimics the Python interpreter + if filename is None: + msg = 'encoding problem: utf-8' + else: + msg = 'encoding problem for {!r}: utf-8'.format(filename) + raise SyntaxError(msg) + encoding += '-sig' + return encoding + + first = read_or_stop() + if first.startswith(BOM_UTF8): + bom_found = True + first = first[3:] + default = 'utf-8-sig' + if not first: + return default, [] + + encoding = find_cookie(first) + if encoding: + return encoding, [first] + + second = read_or_stop() + if not second: + return default, [first] + + encoding = find_cookie(second) + if encoding: + return encoding, [first, second] + + return default, [first, second] + +# For converting & <-> & etc. +try: + from html import escape +except ImportError: + from cgi import escape +if sys.version_info[:2] < (3, 4): + unescape = HTMLParser().unescape +else: + from html import unescape + +try: + from collections import ChainMap +except ImportError: # pragma: no cover + from collections import MutableMapping + + try: + from reprlib import recursive_repr as _recursive_repr + except ImportError: + def _recursive_repr(fillvalue='...'): + ''' + Decorator to make a repr function return fillvalue for a recursive + call + ''' + + def decorating_function(user_function): + repr_running = set() + + def wrapper(self): + key = id(self), get_ident() + if key in repr_running: + return fillvalue + repr_running.add(key) + try: + result = user_function(self) + finally: + repr_running.discard(key) + return result + + # Can't use functools.wraps() here because of bootstrap issues + wrapper.__module__ = getattr(user_function, '__module__') + wrapper.__doc__ = getattr(user_function, '__doc__') + wrapper.__name__ = getattr(user_function, '__name__') + wrapper.__annotations__ = getattr(user_function, '__annotations__', {}) + return wrapper + + return decorating_function + + class ChainMap(MutableMapping): + ''' A ChainMap groups multiple dicts (or other mappings) together + to create a single, updateable view. + + The underlying mappings are stored in a list. That list is public and can + accessed or updated using the *maps* attribute. There is no other state. + + Lookups search the underlying mappings successively until a key is found. + In contrast, writes, updates, and deletions only operate on the first + mapping. + + ''' + + def __init__(self, *maps): + '''Initialize a ChainMap by setting *maps* to the given mappings. + If no mappings are provided, a single empty dictionary is used. + + ''' + self.maps = list(maps) or [{}] # always at least one map + + def __missing__(self, key): + raise KeyError(key) + + def __getitem__(self, key): + for mapping in self.maps: + try: + return mapping[key] # can't use 'key in mapping' with defaultdict + except KeyError: + pass + return self.__missing__(key) # support subclasses that define __missing__ + + def get(self, key, default=None): + return self[key] if key in self else default + + def __len__(self): + return len(set().union(*self.maps)) # reuses stored hash values if possible + + def __iter__(self): + return iter(set().union(*self.maps)) + + def __contains__(self, key): + return any(key in m for m in self.maps) + + def __bool__(self): + return any(self.maps) + + @_recursive_repr() + def __repr__(self): + return '{0.__class__.__name__}({1})'.format( + self, ', '.join(map(repr, self.maps))) + + @classmethod + def fromkeys(cls, iterable, *args): + 'Create a ChainMap with a single dict created from the iterable.' + return cls(dict.fromkeys(iterable, *args)) + + def copy(self): + 'New ChainMap or subclass with a new copy of maps[0] and refs to maps[1:]' + return self.__class__(self.maps[0].copy(), *self.maps[1:]) + + __copy__ = copy + + def new_child(self): # like Django's Context.push() + 'New ChainMap with a new dict followed by all previous maps.' + return self.__class__({}, *self.maps) + + @property + def parents(self): # like Django's Context.pop() + 'New ChainMap from maps[1:].' + return self.__class__(*self.maps[1:]) + + def __setitem__(self, key, value): + self.maps[0][key] = value + + def __delitem__(self, key): + try: + del self.maps[0][key] + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def popitem(self): + 'Remove and return an item pair from maps[0]. Raise KeyError is maps[0] is empty.' + try: + return self.maps[0].popitem() + except KeyError: + raise KeyError('No keys found in the first mapping.') + + def pop(self, key, *args): + 'Remove *key* from maps[0] and return its value. Raise KeyError if *key* not in maps[0].' + try: + return self.maps[0].pop(key, *args) + except KeyError: + raise KeyError('Key not found in the first mapping: {!r}'.format(key)) + + def clear(self): + 'Clear maps[0], leaving maps[1:] intact.' + self.maps[0].clear() + +try: + from importlib.util import cache_from_source # Python >= 3.4 +except ImportError: # pragma: no cover + try: + from imp import cache_from_source + except ImportError: # pragma: no cover + def cache_from_source(path, debug_override=None): + assert path.endswith('.py') + if debug_override is None: + debug_override = __debug__ + if debug_override: + suffix = 'c' + else: + suffix = 'o' + return path + suffix + +try: + from collections import OrderedDict +except ImportError: # pragma: no cover +## {{{ http://code.activestate.com/recipes/576693/ (r9) +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + try: + from thread import get_ident as _get_ident + except ImportError: + from dummy_thread import get_ident as _get_ident + + try: + from _abcoll import KeysView, ValuesView, ItemsView + except ImportError: + pass + + + class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running=None): + 'od.__repr__() <==> repr(od)' + if not _repr_running: _repr_running = {} + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) + +try: + from logging.config import BaseConfigurator, valid_ident +except ImportError: # pragma: no cover + IDENTIFIER = re.compile('^[a-z_][a-z0-9_]*$', re.I) + + + def valid_ident(s): + m = IDENTIFIER.match(s) + if not m: + raise ValueError('Not a valid Python identifier: %r' % s) + return True + + + # The ConvertingXXX classes are wrappers around standard Python containers, + # and they serve to convert any suitable values in the container. The + # conversion converts base dicts, lists and tuples to their wrapped + # equivalents, whereas strings which match a conversion format are converted + # appropriately. + # + # Each wrapper should have a configurator attribute holding the actual + # configurator to use for conversion. + + class ConvertingDict(dict): + """A converting dictionary wrapper.""" + + def __getitem__(self, key): + value = dict.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def get(self, key, default=None): + value = dict.get(self, key, default) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, key, default=None): + value = dict.pop(self, key, default) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class ConvertingList(list): + """A converting list wrapper.""" + def __getitem__(self, key): + value = list.__getitem__(self, key) + result = self.configurator.convert(value) + #If the converted value is different, save for next time + if value is not result: + self[key] = result + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + def pop(self, idx=-1): + value = list.pop(self, idx) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + return result + + class ConvertingTuple(tuple): + """A converting tuple wrapper.""" + def __getitem__(self, key): + value = tuple.__getitem__(self, key) + result = self.configurator.convert(value) + if value is not result: + if type(result) in (ConvertingDict, ConvertingList, + ConvertingTuple): + result.parent = self + result.key = key + return result + + class BaseConfigurator(object): + """ + The configurator base class which defines some useful defaults. + """ + + CONVERT_PATTERN = re.compile(r'^(?P<prefix>[a-z]+)://(?P<suffix>.*)$') + + WORD_PATTERN = re.compile(r'^\s*(\w+)\s*') + DOT_PATTERN = re.compile(r'^\.\s*(\w+)\s*') + INDEX_PATTERN = re.compile(r'^\[\s*(\w+)\s*\]\s*') + DIGIT_PATTERN = re.compile(r'^\d+$') + + value_converters = { + 'ext' : 'ext_convert', + 'cfg' : 'cfg_convert', + } + + # We might want to use a different one, e.g. importlib + importer = staticmethod(__import__) + + def __init__(self, config): + self.config = ConvertingDict(config) + self.config.configurator = self + + def resolve(self, s): + """ + Resolve strings to objects using standard import and attribute + syntax. + """ + name = s.split('.') + used = name.pop(0) + try: + found = self.importer(used) + for frag in name: + used += '.' + frag + try: + found = getattr(found, frag) + except AttributeError: + self.importer(used) + found = getattr(found, frag) + return found + except ImportError: + e, tb = sys.exc_info()[1:] + v = ValueError('Cannot resolve %r: %s' % (s, e)) + v.__cause__, v.__traceback__ = e, tb + raise v + + def ext_convert(self, value): + """Default converter for the ext:// protocol.""" + return self.resolve(value) + + def cfg_convert(self, value): + """Default converter for the cfg:// protocol.""" + rest = value + m = self.WORD_PATTERN.match(rest) + if m is None: + raise ValueError("Unable to convert %r" % value) + else: + rest = rest[m.end():] + d = self.config[m.groups()[0]] + #print d, rest + while rest: + m = self.DOT_PATTERN.match(rest) + if m: + d = d[m.groups()[0]] + else: + m = self.INDEX_PATTERN.match(rest) + if m: + idx = m.groups()[0] + if not self.DIGIT_PATTERN.match(idx): + d = d[idx] + else: + try: + n = int(idx) # try as number first (most likely) + d = d[n] + except TypeError: + d = d[idx] + if m: + rest = rest[m.end():] + else: + raise ValueError('Unable to convert ' + '%r at %r' % (value, rest)) + #rest should be empty + return d + + def convert(self, value): + """ + Convert values to an appropriate type. dicts, lists and tuples are + replaced by their converting alternatives. Strings are checked to + see if they have a conversion format and are converted if they do. + """ + if not isinstance(value, ConvertingDict) and isinstance(value, dict): + value = ConvertingDict(value) + value.configurator = self + elif not isinstance(value, ConvertingList) and isinstance(value, list): + value = ConvertingList(value) + value.configurator = self + elif not isinstance(value, ConvertingTuple) and\ + isinstance(value, tuple): + value = ConvertingTuple(value) + value.configurator = self + elif isinstance(value, string_types): + m = self.CONVERT_PATTERN.match(value) + if m: + d = m.groupdict() + prefix = d['prefix'] + converter = self.value_converters.get(prefix, None) + if converter: + suffix = d['suffix'] + converter = getattr(self, converter) + value = converter(suffix) + return value + + def configure_custom(self, config): + """Configure an object with a user-supplied factory.""" + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + kwargs = dict([(k, config[k]) for k in config if valid_ident(k)]) + result = c(**kwargs) + if props: + for name, value in props.items(): + setattr(result, name, value) + return result + + def as_tuple(self, value): + """Utility function which converts lists to tuples.""" + if isinstance(value, list): + value = tuple(value) + return value diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/database.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/database.py new file mode 100644 index 0000000..a19905e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/database.py @@ -0,0 +1,1336 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""PEP 376 implementation.""" + +from __future__ import unicode_literals + +import base64 +import codecs +import contextlib +import hashlib +import logging +import os +import posixpath +import sys +import zipimport + +from . import DistlibException, resources +from .compat import StringIO +from .version import get_scheme, UnsupportedVersionError +from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .util import (parse_requirement, cached_property, parse_name_and_version, + read_exports, write_exports, CSVReader, CSVWriter) + + +__all__ = ['Distribution', 'BaseInstalledDistribution', + 'InstalledDistribution', 'EggInfoDistribution', + 'DistributionPath'] + + +logger = logging.getLogger(__name__) + +EXPORTS_FILENAME = 'pydist-exports.json' +COMMANDS_FILENAME = 'pydist-commands.json' + +DIST_FILES = ('INSTALLER', METADATA_FILENAME, 'RECORD', 'REQUESTED', + 'RESOURCES', EXPORTS_FILENAME, 'SHARED') + +DISTINFO_EXT = '.dist-info' + + +class _Cache(object): + """ + A simple cache mapping names and .dist-info paths to distributions + """ + def __init__(self): + """ + Initialise an instance. There is normally one for each DistributionPath. + """ + self.name = {} + self.path = {} + self.generated = False + + def clear(self): + """ + Clear the cache, setting it to its initial state. + """ + self.name.clear() + self.path.clear() + self.generated = False + + def add(self, dist): + """ + Add a distribution to the cache. + :param dist: The distribution to add. + """ + if dist.path not in self.path: + self.path[dist.path] = dist + self.name.setdefault(dist.key, []).append(dist) + + +class DistributionPath(object): + """ + Represents a set of distributions installed on a path (typically sys.path). + """ + def __init__(self, path=None, include_egg=False): + """ + Create an instance from a path, optionally including legacy (distutils/ + setuptools/distribute) distributions. + :param path: The path to use, as a list of directories. If not specified, + sys.path is used. + :param include_egg: If True, this instance will look for and return legacy + distributions as well as those based on PEP 376. + """ + if path is None: + path = sys.path + self.path = path + self._include_dist = True + self._include_egg = include_egg + + self._cache = _Cache() + self._cache_egg = _Cache() + self._cache_enabled = True + self._scheme = get_scheme('default') + + def _get_cache_enabled(self): + return self._cache_enabled + + def _set_cache_enabled(self, value): + self._cache_enabled = value + + cache_enabled = property(_get_cache_enabled, _set_cache_enabled) + + def clear_cache(self): + """ + Clears the internal cache. + """ + self._cache.clear() + self._cache_egg.clear() + + + def _yield_distributions(self): + """ + Yield .dist-info and/or .egg(-info) distributions. + """ + # We need to check if we've seen some resources already, because on + # some Linux systems (e.g. some Debian/Ubuntu variants) there are + # symlinks which alias other files in the environment. + seen = set() + for path in self.path: + finder = resources.finder_for_path(path) + if finder is None: + continue + r = finder.find('') + if not r or not r.is_container: + continue + rset = sorted(r.resources) + for entry in rset: + r = finder.find(entry) + if not r or r.path in seen: + continue + if self._include_dist and entry.endswith(DISTINFO_EXT): + possible_filenames = [METADATA_FILENAME, WHEEL_METADATA_FILENAME] + for metadata_filename in possible_filenames: + metadata_path = posixpath.join(entry, metadata_filename) + pydist = finder.find(metadata_path) + if pydist: + break + else: + continue + + with contextlib.closing(pydist.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + logger.debug('Found %s', r.path) + seen.add(r.path) + yield new_dist_class(r.path, metadata=metadata, + env=self) + elif self._include_egg and entry.endswith(('.egg-info', + '.egg')): + logger.debug('Found %s', r.path) + seen.add(r.path) + yield old_dist_class(r.path, self) + + def _generate_cache(self): + """ + Scan the path for distributions and populate the cache with + those that are found. + """ + gen_dist = not self._cache.generated + gen_egg = self._include_egg and not self._cache_egg.generated + if gen_dist or gen_egg: + for dist in self._yield_distributions(): + if isinstance(dist, InstalledDistribution): + self._cache.add(dist) + else: + self._cache_egg.add(dist) + + if gen_dist: + self._cache.generated = True + if gen_egg: + self._cache_egg.generated = True + + @classmethod + def distinfo_dirname(cls, name, version): + """ + The *name* and *version* parameters are converted into their + filename-escaped form, i.e. any ``'-'`` characters are replaced + with ``'_'`` other than the one in ``'dist-info'`` and the one + separating the name from the version number. + + :parameter name: is converted to a standard distribution name by replacing + any runs of non- alphanumeric characters with a single + ``'-'``. + :type name: string + :parameter version: is converted to a standard version string. Spaces + become dots, and all other non-alphanumeric characters + (except dots) become dashes, with runs of multiple + dashes condensed to a single dash. + :type version: string + :returns: directory name + :rtype: string""" + name = name.replace('-', '_') + return '-'.join([name, version]) + DISTINFO_EXT + + def get_distributions(self): + """ + Provides an iterator that looks for distributions and returns + :class:`InstalledDistribution` or + :class:`EggInfoDistribution` instances for each one of them. + + :rtype: iterator of :class:`InstalledDistribution` and + :class:`EggInfoDistribution` instances + """ + if not self._cache_enabled: + for dist in self._yield_distributions(): + yield dist + else: + self._generate_cache() + + for dist in self._cache.path.values(): + yield dist + + if self._include_egg: + for dist in self._cache_egg.path.values(): + yield dist + + def get_distribution(self, name): + """ + Looks for a named distribution on the path. + + This function only returns the first result found, as no more than one + value is expected. If nothing is found, ``None`` is returned. + + :rtype: :class:`InstalledDistribution`, :class:`EggInfoDistribution` + or ``None`` + """ + result = None + name = name.lower() + if not self._cache_enabled: + for dist in self._yield_distributions(): + if dist.key == name: + result = dist + break + else: + self._generate_cache() + + if name in self._cache.name: + result = self._cache.name[name][0] + elif self._include_egg and name in self._cache_egg.name: + result = self._cache_egg.name[name][0] + return result + + def provides_distribution(self, name, version=None): + """ + Iterates over all distributions to find which distributions provide *name*. + If a *version* is provided, it will be used to filter the results. + + This function only returns the first result found, since no more than + one values are expected. If the directory is not found, returns ``None``. + + :parameter version: a version specifier that indicates the version + required, conforming to the format in ``PEP-345`` + + :type name: string + :type version: string + """ + matcher = None + if version is not None: + try: + matcher = self._scheme.matcher('%s (%s)' % (name, version)) + except ValueError: + raise DistlibException('invalid name or version: %r, %r' % + (name, version)) + + for dist in self.get_distributions(): + # We hit a problem on Travis where enum34 was installed and doesn't + # have a provides attribute ... + if not hasattr(dist, 'provides'): + logger.debug('No "provides": %s', dist) + else: + provided = dist.provides + + for p in provided: + p_name, p_ver = parse_name_and_version(p) + if matcher is None: + if p_name == name: + yield dist + break + else: + if p_name == name and matcher.match(p_ver): + yield dist + break + + def get_file_path(self, name, relative_path): + """ + Return the path to a resource file. + """ + dist = self.get_distribution(name) + if dist is None: + raise LookupError('no distribution named %r found' % name) + return dist.get_resource_path(relative_path) + + def get_exported_entries(self, category, name=None): + """ + Return all of the exported entries in a particular category. + + :param category: The category to search for entries. + :param name: If specified, only entries with that name are returned. + """ + for dist in self.get_distributions(): + r = dist.exports + if category in r: + d = r[category] + if name is not None: + if name in d: + yield d[name] + else: + for v in d.values(): + yield v + + +class Distribution(object): + """ + A base class for distributions, whether installed or from indexes. + Either way, it must have some metadata, so that's all that's needed + for construction. + """ + + build_time_dependency = False + """ + Set to True if it's known to be only a build-time dependency (i.e. + not needed after installation). + """ + + requested = False + """A boolean that indicates whether the ``REQUESTED`` metadata file is + present (in other words, whether the package was installed by user + request or it was installed as a dependency).""" + + def __init__(self, metadata): + """ + Initialise an instance. + :param metadata: The instance of :class:`Metadata` describing this + distribution. + """ + self.metadata = metadata + self.name = metadata.name + self.key = self.name.lower() # for case-insensitive comparisons + self.version = metadata.version + self.locator = None + self.digest = None + self.extras = None # additional features requested + self.context = None # environment marker overrides + self.download_urls = set() + self.digests = {} + + @property + def source_url(self): + """ + The source archive download URL for this distribution. + """ + return self.metadata.source_url + + download_url = source_url # Backward compatibility + + @property + def name_and_version(self): + """ + A utility property which displays the name and version in parentheses. + """ + return '%s (%s)' % (self.name, self.version) + + @property + def provides(self): + """ + A set of distribution names and versions provided by this distribution. + :return: A set of "name (version)" strings. + """ + plist = self.metadata.provides + s = '%s (%s)' % (self.name, self.version) + if s not in plist: + plist.append(s) + return plist + + def _get_requirements(self, req_attr): + md = self.metadata + logger.debug('Getting requirements from metadata %r', md.todict()) + reqts = getattr(md, req_attr) + return set(md.get_requirements(reqts, extras=self.extras, + env=self.context)) + + @property + def run_requires(self): + return self._get_requirements('run_requires') + + @property + def meta_requires(self): + return self._get_requirements('meta_requires') + + @property + def build_requires(self): + return self._get_requirements('build_requires') + + @property + def test_requires(self): + return self._get_requirements('test_requires') + + @property + def dev_requires(self): + return self._get_requirements('dev_requires') + + def matches_requirement(self, req): + """ + Say if this instance matches (fulfills) a requirement. + :param req: The requirement to match. + :rtype req: str + :return: True if it matches, else False. + """ + # Requirement may contain extras - parse to lose those + # from what's passed to the matcher + r = parse_requirement(req) + scheme = get_scheme(self.metadata.scheme) + try: + matcher = scheme.matcher(r.requirement) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + result = False + for p in self.provides: + p_name, p_ver = parse_name_and_version(p) + if p_name != name: + continue + try: + result = matcher.match(p_ver) + break + except UnsupportedVersionError: + pass + return result + + def __repr__(self): + """ + Return a textual representation of this instance, + """ + if self.source_url: + suffix = ' [%s]' % self.source_url + else: + suffix = '' + return '<Distribution %s (%s)%s>' % (self.name, self.version, suffix) + + def __eq__(self, other): + """ + See if this distribution is the same as another. + :param other: The distribution to compare with. To be equal to one + another. distributions must have the same type, name, + version and source_url. + :return: True if it is the same, else False. + """ + if type(other) is not type(self): + result = False + else: + result = (self.name == other.name and + self.version == other.version and + self.source_url == other.source_url) + return result + + def __hash__(self): + """ + Compute hash in a way which matches the equality test. + """ + return hash(self.name) + hash(self.version) + hash(self.source_url) + + +class BaseInstalledDistribution(Distribution): + """ + This is the base class for installed distributions (whether PEP 376 or + legacy). + """ + + hasher = None + + def __init__(self, metadata, path, env=None): + """ + Initialise an instance. + :param metadata: An instance of :class:`Metadata` which describes the + distribution. This will normally have been initialised + from a metadata file in the ``path``. + :param path: The path of the ``.dist-info`` or ``.egg-info`` + directory for the distribution. + :param env: This is normally the :class:`DistributionPath` + instance where this distribution was found. + """ + super(BaseInstalledDistribution, self).__init__(metadata) + self.path = path + self.dist_path = env + + def get_hash(self, data, hasher=None): + """ + Get the hash of some data, using a particular hash algorithm, if + specified. + + :param data: The data to be hashed. + :type data: bytes + :param hasher: The name of a hash implementation, supported by hashlib, + or ``None``. Examples of valid values are ``'sha1'``, + ``'sha224'``, ``'sha384'``, '``sha256'``, ``'md5'`` and + ``'sha512'``. If no hasher is specified, the ``hasher`` + attribute of the :class:`InstalledDistribution` instance + is used. If the hasher is determined to be ``None``, MD5 + is used as the hashing algorithm. + :returns: The hash of the data. If a hasher was explicitly specified, + the returned hash will be prefixed with the specified hasher + followed by '='. + :rtype: str + """ + if hasher is None: + hasher = self.hasher + if hasher is None: + hasher = hashlib.md5 + prefix = '' + else: + hasher = getattr(hashlib, hasher) + prefix = '%s=' % self.hasher + digest = hasher(data).digest() + digest = base64.urlsafe_b64encode(digest).rstrip(b'=').decode('ascii') + return '%s%s' % (prefix, digest) + + +class InstalledDistribution(BaseInstalledDistribution): + """ + Created with the *path* of the ``.dist-info`` directory provided to the + constructor. It reads the metadata contained in ``pydist.json`` when it is + instantiated., or uses a passed in Metadata instance (useful for when + dry-run mode is being used). + """ + + hasher = 'sha256' + + def __init__(self, path, metadata=None, env=None): + self.modules = [] + self.finder = finder = resources.finder_for_path(path) + if finder is None: + raise ValueError('finder unavailable for %s' % path) + if env and env._cache_enabled and path in env._cache.path: + metadata = env._cache.path[path].metadata + elif metadata is None: + r = finder.find(METADATA_FILENAME) + # Temporary - for Wheel 0.23 support + if r is None: + r = finder.find(WHEEL_METADATA_FILENAME) + # Temporary - for legacy support + if r is None: + r = finder.find('METADATA') + if r is None: + raise ValueError('no %s found in %s' % (METADATA_FILENAME, + path)) + with contextlib.closing(r.as_stream()) as stream: + metadata = Metadata(fileobj=stream, scheme='legacy') + + super(InstalledDistribution, self).__init__(metadata, path, env) + + if env and env._cache_enabled: + env._cache.add(self) + + r = finder.find('REQUESTED') + self.requested = r is not None + p = os.path.join(path, 'top_level.txt') + if os.path.exists(p): + with open(p, 'rb') as f: + data = f.read() + self.modules = data.splitlines() + + def __repr__(self): + return '<InstalledDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def _get_records(self): + """ + Get the list of installed files for the distribution + :return: A list of tuples of path, hash and size. Note that hash and + size might be ``None`` for some entries. The path is exactly + as stored in the file (which is as in PEP 376). + """ + results = [] + r = self.get_distinfo_resource('RECORD') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as record_reader: + # Base location is parent dir of .dist-info dir + #base_location = os.path.dirname(self.path) + #base_location = os.path.abspath(base_location) + for row in record_reader: + missing = [None for i in range(len(row), 3)] + path, checksum, size = row + missing + #if not os.path.isabs(path): + # path = path.replace('/', os.sep) + # path = os.path.join(base_location, path) + results.append((path, checksum, size)) + return results + + @cached_property + def exports(self): + """ + Return the information exported by this distribution. + :return: A dictionary of exports, mapping an export category to a dict + of :class:`ExportEntry` instances describing the individual + export entries, and keyed by name. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + result = self.read_exports() + return result + + def read_exports(self): + """ + Read exports data from a file in .ini format. + + :return: A dictionary of exports, mapping an export category to a list + of :class:`ExportEntry` instances describing the individual + export entries. + """ + result = {} + r = self.get_distinfo_resource(EXPORTS_FILENAME) + if r: + with contextlib.closing(r.as_stream()) as stream: + result = read_exports(stream) + return result + + def write_exports(self, exports): + """ + Write a dictionary of exports to a file in .ini format. + :param exports: A dictionary of exports, mapping an export category to + a list of :class:`ExportEntry` instances describing the + individual export entries. + """ + rf = self.get_distinfo_file(EXPORTS_FILENAME) + with open(rf, 'w') as f: + write_exports(exports, f) + + def get_resource_path(self, relative_path): + """ + NOTE: This API may change in the future. + + Return the absolute path to a resource file with the given relative + path. + + :param relative_path: The path, relative to .dist-info, of the resource + of interest. + :return: The absolute path where the resource is to be found. + """ + r = self.get_distinfo_resource('RESOURCES') + with contextlib.closing(r.as_stream()) as stream: + with CSVReader(stream=stream) as resources_reader: + for relative, destination in resources_reader: + if relative == relative_path: + return destination + raise KeyError('no resource file with relative path %r ' + 'is installed' % relative_path) + + def list_installed_files(self): + """ + Iterates over the ``RECORD`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: iterator of (path, hash, size) + """ + for result in self._get_records(): + yield result + + def write_installed_files(self, paths, prefix, dry_run=False): + """ + Writes the ``RECORD`` file, using the ``paths`` iterable passed in. Any + existing ``RECORD`` file is silently overwritten. + + prefix is used to determine when to write absolute paths. + """ + prefix = os.path.join(prefix, '') + base = os.path.dirname(self.path) + base_under_prefix = base.startswith(prefix) + base = os.path.join(base, '') + record_path = self.get_distinfo_file('RECORD') + logger.info('creating %s', record_path) + if dry_run: + return None + with CSVWriter(record_path) as writer: + for path in paths: + if os.path.isdir(path) or path.endswith(('.pyc', '.pyo')): + # do not put size and hash, as in PEP-376 + hash_value = size = '' + else: + size = '%d' % os.path.getsize(path) + with open(path, 'rb') as fp: + hash_value = self.get_hash(fp.read()) + if path.startswith(base) or (base_under_prefix and + path.startswith(prefix)): + path = os.path.relpath(path, base) + writer.writerow((path, hash_value, size)) + + # add the RECORD file itself + if record_path.startswith(base): + record_path = os.path.relpath(record_path, base) + writer.writerow((record_path, '', '')) + return record_path + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + base = os.path.dirname(self.path) + record_path = self.get_distinfo_file('RECORD') + for path, hash_value, size in self.list_installed_files(): + if not os.path.isabs(path): + path = os.path.join(base, path) + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + elif os.path.isfile(path): + actual_size = str(os.path.getsize(path)) + if size and actual_size != size: + mismatches.append((path, 'size', size, actual_size)) + elif hash_value: + if '=' in hash_value: + hasher = hash_value.split('=', 1)[0] + else: + hasher = None + + with open(path, 'rb') as f: + actual_hash = self.get_hash(f.read(), hasher) + if actual_hash != hash_value: + mismatches.append((path, 'hash', hash_value, actual_hash)) + return mismatches + + @cached_property + def shared_locations(self): + """ + A dictionary of shared locations whose keys are in the set 'prefix', + 'purelib', 'platlib', 'scripts', 'headers', 'data' and 'namespace'. + The corresponding value is the absolute path of that category for + this distribution, and takes into account any paths selected by the + user at installation time (e.g. via command-line arguments). In the + case of the 'namespace' key, this would be a list of absolute paths + for the roots of namespace packages in this distribution. + + The first time this property is accessed, the relevant information is + read from the SHARED file in the .dist-info directory. + """ + result = {} + shared_path = os.path.join(self.path, 'SHARED') + if os.path.isfile(shared_path): + with codecs.open(shared_path, 'r', encoding='utf-8') as f: + lines = f.read().splitlines() + for line in lines: + key, value = line.split('=', 1) + if key == 'namespace': + result.setdefault(key, []).append(value) + else: + result[key] = value + return result + + def write_shared_locations(self, paths, dry_run=False): + """ + Write shared location information to the SHARED file in .dist-info. + :param paths: A dictionary as described in the documentation for + :meth:`shared_locations`. + :param dry_run: If True, the action is logged but no file is actually + written. + :return: The path of the file written to. + """ + shared_path = os.path.join(self.path, 'SHARED') + logger.info('creating %s', shared_path) + if dry_run: + return None + lines = [] + for key in ('prefix', 'lib', 'headers', 'scripts', 'data'): + path = paths[key] + if os.path.isdir(paths[key]): + lines.append('%s=%s' % (key, path)) + for ns in paths.get('namespace', ()): + lines.append('namespace=%s' % ns) + + with codecs.open(shared_path, 'w', encoding='utf-8') as f: + f.write('\n'.join(lines)) + return shared_path + + def get_distinfo_resource(self, path): + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + finder = resources.finder_for_path(self.path) + if finder is None: + raise DistlibException('Unable to get a finder for %s' % self.path) + return finder.find(path) + + def get_distinfo_file(self, path): + """ + Returns a path located under the ``.dist-info`` directory. Returns a + string representing the path. + + :parameter path: a ``'/'``-separated path relative to the + ``.dist-info`` directory or an absolute path; + If *path* is an absolute path and doesn't start + with the ``.dist-info`` directory path, + a :class:`DistlibException` is raised + :type path: str + :rtype: str + """ + # Check if it is an absolute path # XXX use relpath, add tests + if path.find(os.sep) >= 0: + # it's an absolute path? + distinfo_dirname, path = path.split(os.sep)[-2:] + if distinfo_dirname != self.path.split(os.sep)[-1]: + raise DistlibException( + 'dist-info file %r does not belong to the %r %s ' + 'distribution' % (path, self.name, self.version)) + + # The file must be relative + if path not in DIST_FILES: + raise DistlibException('invalid path for a dist-info file: ' + '%r at %r' % (path, self.path)) + + return os.path.join(self.path, path) + + def list_distinfo_files(self): + """ + Iterates over the ``RECORD`` entries and returns paths for each line if + the path is pointing to a file located in the ``.dist-info`` directory + or one of its subdirectories. + + :returns: iterator of paths + """ + base = os.path.dirname(self.path) + for path, checksum, size in self._get_records(): + # XXX add separator or use real relpath algo + if not os.path.isabs(path): + path = os.path.join(base, path) + if path.startswith(self.path): + yield path + + def __eq__(self, other): + return (isinstance(other, InstalledDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + + +class EggInfoDistribution(BaseInstalledDistribution): + """Created with the *path* of the ``.egg-info`` directory or file provided + to the constructor. It reads the metadata contained in the file itself, or + if the given path happens to be a directory, the metadata is read from the + file ``PKG-INFO`` under that directory.""" + + requested = True # as we have no way of knowing, assume it was + shared_locations = {} + + def __init__(self, path, env=None): + def set_name_and_version(s, n, v): + s.name = n + s.key = n.lower() # for case-insensitive comparisons + s.version = v + + self.path = path + self.dist_path = env + if env and env._cache_enabled and path in env._cache_egg.path: + metadata = env._cache_egg.path[path].metadata + set_name_and_version(self, metadata.name, metadata.version) + else: + metadata = self._get_metadata(path) + + # Need to be set before caching + set_name_and_version(self, metadata.name, metadata.version) + + if env and env._cache_enabled: + env._cache_egg.add(self) + super(EggInfoDistribution, self).__init__(metadata, path, env) + + def _get_metadata(self, path): + requires = None + + def parse_requires_data(data): + """Create a list of dependencies from a requires.txt file. + + *data*: the contents of a setuptools-produced requires.txt file. + """ + reqs = [] + lines = data.splitlines() + for line in lines: + line = line.strip() + if line.startswith('['): + logger.warning('Unexpected line: quitting requirement scan: %r', + line) + break + r = parse_requirement(line) + if not r: + logger.warning('Not recognised as a requirement: %r', line) + continue + if r.extras: + logger.warning('extra requirements in requires.txt are ' + 'not supported') + if not r.constraints: + reqs.append(r.name) + else: + cons = ', '.join('%s%s' % c for c in r.constraints) + reqs.append('%s (%s)' % (r.name, cons)) + return reqs + + def parse_requires_path(req_path): + """Create a list of dependencies from a requires.txt file. + + *req_path*: the path to a setuptools-produced requires.txt file. + """ + + reqs = [] + try: + with codecs.open(req_path, 'r', 'utf-8') as fp: + reqs = parse_requires_data(fp.read()) + except IOError: + pass + return reqs + + tl_path = tl_data = None + if path.endswith('.egg'): + if os.path.isdir(path): + p = os.path.join(path, 'EGG-INFO') + meta_path = os.path.join(p, 'PKG-INFO') + metadata = Metadata(path=meta_path, scheme='legacy') + req_path = os.path.join(p, 'requires.txt') + tl_path = os.path.join(p, 'top_level.txt') + requires = parse_requires_path(req_path) + else: + # FIXME handle the case where zipfile is not available + zipf = zipimport.zipimporter(path) + fileobj = StringIO( + zipf.get_data('EGG-INFO/PKG-INFO').decode('utf8')) + metadata = Metadata(fileobj=fileobj, scheme='legacy') + try: + data = zipf.get_data('EGG-INFO/requires.txt') + tl_data = zipf.get_data('EGG-INFO/top_level.txt').decode('utf-8') + requires = parse_requires_data(data.decode('utf-8')) + except IOError: + requires = None + elif path.endswith('.egg-info'): + if os.path.isdir(path): + req_path = os.path.join(path, 'requires.txt') + requires = parse_requires_path(req_path) + path = os.path.join(path, 'PKG-INFO') + tl_path = os.path.join(path, 'top_level.txt') + metadata = Metadata(path=path, scheme='legacy') + else: + raise DistlibException('path must end with .egg-info or .egg, ' + 'got %r' % path) + + if requires: + metadata.add_requirements(requires) + # look for top-level modules in top_level.txt, if present + if tl_data is None: + if tl_path is not None and os.path.exists(tl_path): + with open(tl_path, 'rb') as f: + tl_data = f.read().decode('utf-8') + if not tl_data: + tl_data = [] + else: + tl_data = tl_data.splitlines() + self.modules = tl_data + return metadata + + def __repr__(self): + return '<EggInfoDistribution %r %s at %r>' % ( + self.name, self.version, self.path) + + def __str__(self): + return "%s %s" % (self.name, self.version) + + def check_installed_files(self): + """ + Checks that the hashes and sizes of the files in ``RECORD`` are + matched by the files themselves. Returns a (possibly empty) list of + mismatches. Each entry in the mismatch list will be a tuple consisting + of the path, 'exists', 'size' or 'hash' according to what didn't match + (existence is checked first, then size, then hash), the expected + value and the actual value. + """ + mismatches = [] + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + for path, _, _ in self.list_installed_files(): + if path == record_path: + continue + if not os.path.exists(path): + mismatches.append((path, 'exists', True, False)) + return mismatches + + def list_installed_files(self): + """ + Iterates over the ``installed-files.txt`` entries and returns a tuple + ``(path, hash, size)`` for each line. + + :returns: a list of (path, hash, size) + """ + + def _md5(path): + f = open(path, 'rb') + try: + content = f.read() + finally: + f.close() + return hashlib.md5(content).hexdigest() + + def _size(path): + return os.stat(path).st_size + + record_path = os.path.join(self.path, 'installed-files.txt') + result = [] + if os.path.exists(record_path): + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + p = os.path.normpath(os.path.join(self.path, line)) + # "./" is present as a marker between installed files + # and installation metadata files + if not os.path.exists(p): + logger.warning('Non-existent file: %s', p) + if p.endswith(('.pyc', '.pyo')): + continue + #otherwise fall through and fail + if not os.path.isdir(p): + result.append((p, _md5(p), _size(p))) + result.append((record_path, None, None)) + return result + + def list_distinfo_files(self, absolute=False): + """ + Iterates over the ``installed-files.txt`` entries and returns paths for + each line if the path is pointing to a file located in the + ``.egg-info`` directory or one of its subdirectories. + + :parameter absolute: If *absolute* is ``True``, each returned path is + transformed into a local absolute path. Otherwise the + raw value from ``installed-files.txt`` is returned. + :type absolute: boolean + :returns: iterator of paths + """ + record_path = os.path.join(self.path, 'installed-files.txt') + if os.path.exists(record_path): + skip = True + with codecs.open(record_path, 'r', encoding='utf-8') as f: + for line in f: + line = line.strip() + if line == './': + skip = False + continue + if not skip: + p = os.path.normpath(os.path.join(self.path, line)) + if p.startswith(self.path): + if absolute: + yield p + else: + yield line + + def __eq__(self, other): + return (isinstance(other, EggInfoDistribution) and + self.path == other.path) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + __hash__ = object.__hash__ + +new_dist_class = InstalledDistribution +old_dist_class = EggInfoDistribution + + +class DependencyGraph(object): + """ + Represents a dependency graph between distributions. + + The dependency relationships are stored in an ``adjacency_list`` that maps + distributions to a list of ``(other, label)`` tuples where ``other`` + is a distribution and the edge is labeled with ``label`` (i.e. the version + specifier, if such was provided). Also, for more efficient traversal, for + every distribution ``x``, a list of predecessors is kept in + ``reverse_list[x]``. An edge from distribution ``a`` to + distribution ``b`` means that ``a`` depends on ``b``. If any missing + dependencies are found, they are stored in ``missing``, which is a + dictionary that maps distributions to a list of requirements that were not + provided by any other distributions. + """ + + def __init__(self): + self.adjacency_list = {} + self.reverse_list = {} + self.missing = {} + + def add_distribution(self, distribution): + """Add the *distribution* to the graph. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + """ + self.adjacency_list[distribution] = [] + self.reverse_list[distribution] = [] + #self.missing[distribution] = [] + + def add_edge(self, x, y, label=None): + """Add an edge from distribution *x* to distribution *y* with the given + *label*. + + :type x: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type y: :class:`distutils2.database.InstalledDistribution` or + :class:`distutils2.database.EggInfoDistribution` + :type label: ``str`` or ``None`` + """ + self.adjacency_list[x].append((y, label)) + # multiple edges are allowed, so be careful + if x not in self.reverse_list[y]: + self.reverse_list[y].append(x) + + def add_missing(self, distribution, requirement): + """ + Add a missing *requirement* for the given *distribution*. + + :type distribution: :class:`distutils2.database.InstalledDistribution` + or :class:`distutils2.database.EggInfoDistribution` + :type requirement: ``str`` + """ + logger.debug('%s missing %r', distribution, requirement) + self.missing.setdefault(distribution, []).append(requirement) + + def _repr_dist(self, dist): + return '%s %s' % (dist.name, dist.version) + + def repr_node(self, dist, level=1): + """Prints only a subgraph""" + output = [self._repr_dist(dist)] + for other, label in self.adjacency_list[dist]: + dist = self._repr_dist(other) + if label is not None: + dist = '%s [%s]' % (dist, label) + output.append(' ' * level + str(dist)) + suboutput = self.repr_node(other, level + 1) + subs = suboutput.split('\n') + output.extend(subs[1:]) + return '\n'.join(output) + + def to_dot(self, f, skip_disconnected=True): + """Writes a DOT output for the graph to the provided file *f*. + + If *skip_disconnected* is set to ``True``, then all distributions + that are not dependent on any other distribution are skipped. + + :type f: has to support ``file``-like operations + :type skip_disconnected: ``bool`` + """ + disconnected = [] + + f.write("digraph dependencies {\n") + for dist, adjs in self.adjacency_list.items(): + if len(adjs) == 0 and not skip_disconnected: + disconnected.append(dist) + for other, label in adjs: + if not label is None: + f.write('"%s" -> "%s" [label="%s"]\n' % + (dist.name, other.name, label)) + else: + f.write('"%s" -> "%s"\n' % (dist.name, other.name)) + if not skip_disconnected and len(disconnected) > 0: + f.write('subgraph disconnected {\n') + f.write('label = "Disconnected"\n') + f.write('bgcolor = red\n') + + for dist in disconnected: + f.write('"%s"' % dist.name) + f.write('\n') + f.write('}\n') + f.write('}\n') + + def topological_sort(self): + """ + Perform a topological sort of the graph. + :return: A tuple, the first element of which is a topologically sorted + list of distributions, and the second element of which is a + list of distributions that cannot be sorted because they have + circular dependencies and so form a cycle. + """ + result = [] + # Make a shallow copy of the adjacency list + alist = {} + for k, v in self.adjacency_list.items(): + alist[k] = v[:] + while True: + # See what we can remove in this run + to_remove = [] + for k, v in list(alist.items())[:]: + if not v: + to_remove.append(k) + del alist[k] + if not to_remove: + # What's left in alist (if anything) is a cycle. + break + # Remove from the adjacency list of others + for k, v in alist.items(): + alist[k] = [(d, r) for d, r in v if d not in to_remove] + logger.debug('Moving to result: %s', + ['%s (%s)' % (d.name, d.version) for d in to_remove]) + result.extend(to_remove) + return result, list(alist.keys()) + + def __repr__(self): + """Representation of the graph""" + output = [] + for dist, adjs in self.adjacency_list.items(): + output.append(self.repr_node(dist)) + return '\n'.join(output) + + +def make_graph(dists, scheme='default'): + """Makes a dependency graph from the given distributions. + + :parameter dists: a list of distributions + :type dists: list of :class:`distutils2.database.InstalledDistribution` and + :class:`distutils2.database.EggInfoDistribution` instances + :rtype: a :class:`DependencyGraph` instance + """ + scheme = get_scheme(scheme) + graph = DependencyGraph() + provided = {} # maps names to lists of (version, dist) tuples + + # first, build the graph and find out what's provided + for dist in dists: + graph.add_distribution(dist) + + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + provided.setdefault(name, []).append((version, dist)) + + # now make the edges + for dist in dists: + requires = (dist.run_requires | dist.meta_requires | + dist.build_requires | dist.dev_requires) + for req in requires: + try: + matcher = scheme.matcher(req) + except UnsupportedVersionError: + # XXX compat-mode if cannot read the version + logger.warning('could not read version %r - using name only', + req) + name = req.split()[0] + matcher = scheme.matcher(name) + + name = matcher.key # case-insensitive + + matched = False + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + graph.add_edge(dist, provider, req) + matched = True + break + if not matched: + graph.add_missing(dist, req) + return graph + + +def get_dependent_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + dependent on *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + dep = [dist] # dependent distributions + todo = graph.reverse_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop() + dep.append(d) + for succ in graph.reverse_list[d]: + if succ not in dep: + todo.append(succ) + + dep.pop(0) # remove dist from dep, was there to prevent infinite loops + return dep + + +def get_required_dists(dists, dist): + """Recursively generate a list of distributions from *dists* that are + required by *dist*. + + :param dists: a list of distributions + :param dist: a distribution, member of *dists* for which we are interested + """ + if dist not in dists: + raise DistlibException('given distribution %r is not a member ' + 'of the list' % dist.name) + graph = make_graph(dists) + + req = [] # required distributions + todo = graph.adjacency_list[dist] # list of nodes we should inspect + + while todo: + d = todo.pop()[0] + req.append(d) + for pred in graph.adjacency_list[d]: + if pred not in req: + todo.append(pred) + + return req + + +def make_dist(name, version, **kwargs): + """ + A convenience method for making a dist given just a name and version. + """ + summary = kwargs.pop('summary', 'Placeholder for summary') + md = Metadata(**kwargs) + md.name = name + md.version = version + md.summary = summary or 'Placeholder for summary' + return Distribution(md) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/index.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/index.py new file mode 100644 index 0000000..2406be2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/index.py @@ -0,0 +1,516 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import hashlib +import logging +import os +import shutil +import subprocess +import tempfile +try: + from threading import Thread +except ImportError: + from dummy_threading import Thread + +from . import DistlibException +from .compat import (HTTPBasicAuthHandler, Request, HTTPPasswordMgr, + urlparse, build_opener, string_types) +from .util import cached_property, zip_dir, ServerProxy + +logger = logging.getLogger(__name__) + +DEFAULT_INDEX = 'https://pypi.python.org/pypi' +DEFAULT_REALM = 'pypi' + +class PackageIndex(object): + """ + This class represents a package index compatible with PyPI, the Python + Package Index. + """ + + boundary = b'----------ThIs_Is_tHe_distlib_index_bouNdaRY_$' + + def __init__(self, url=None): + """ + Initialise an instance. + + :param url: The URL of the index. If not specified, the URL for PyPI is + used. + """ + self.url = url or DEFAULT_INDEX + self.read_configuration() + scheme, netloc, path, params, query, frag = urlparse(self.url) + if params or query or frag or scheme not in ('http', 'https'): + raise DistlibException('invalid repository: %s' % self.url) + self.password_handler = None + self.ssl_verifier = None + self.gpg = None + self.gpg_home = None + with open(os.devnull, 'w') as sink: + # Use gpg by default rather than gpg2, as gpg2 insists on + # prompting for passwords + for s in ('gpg', 'gpg2'): + try: + rc = subprocess.check_call([s, '--version'], stdout=sink, + stderr=sink) + if rc == 0: + self.gpg = s + break + except OSError: + pass + + def _get_pypirc_command(self): + """ + Get the distutils command for interacting with PyPI configurations. + :return: the command. + """ + from distutils.core import Distribution + from distutils.config import PyPIRCCommand + d = Distribution() + return PyPIRCCommand(d) + + def read_configuration(self): + """ + Read the PyPI access configuration as supported by distutils, getting + PyPI to do the actual work. This populates ``username``, ``password``, + ``realm`` and ``url`` attributes from the configuration. + """ + # get distutils to do the work + c = self._get_pypirc_command() + c.repository = self.url + cfg = c._read_pypirc() + self.username = cfg.get('username') + self.password = cfg.get('password') + self.realm = cfg.get('realm', 'pypi') + self.url = cfg.get('repository', self.url) + + def save_configuration(self): + """ + Save the PyPI access configuration. You must have set ``username`` and + ``password`` attributes before calling this method. + + Again, distutils is used to do the actual work. + """ + self.check_credentials() + # get distutils to do the work + c = self._get_pypirc_command() + c._store_pypirc(self.username, self.password) + + def check_credentials(self): + """ + Check that ``username`` and ``password`` have been set, and raise an + exception if not. + """ + if self.username is None or self.password is None: + raise DistlibException('username and password must be set') + pm = HTTPPasswordMgr() + _, netloc, _, _, _, _ = urlparse(self.url) + pm.add_password(self.realm, netloc, self.username, self.password) + self.password_handler = HTTPBasicAuthHandler(pm) + + def register(self, metadata): + """ + Register a distribution on PyPI, using the provided metadata. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the distribution to be + registered. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + metadata.validate() + d = metadata.todict() + d[':action'] = 'verify' + request = self.encode_request(d.items(), []) + response = self.send_request(request) + d[':action'] = 'submit' + request = self.encode_request(d.items(), []) + return self.send_request(request) + + def _reader(self, name, stream, outbuf): + """ + Thread runner for reading lines of from a subprocess into a buffer. + + :param name: The logical name of the stream (used for logging only). + :param stream: The stream to read from. This will typically a pipe + connected to the output stream of a subprocess. + :param outbuf: The list to append the read lines to. + """ + while True: + s = stream.readline() + if not s: + break + s = s.decode('utf-8').rstrip() + outbuf.append(s) + logger.debug('%s: %s' % (name, s)) + stream.close() + + def get_sign_command(self, filename, signer, sign_password, + keystore=None): + """ + Return a suitable command for signing a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The signing command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + if sign_password is not None: + cmd.extend(['--batch', '--passphrase-fd', '0']) + td = tempfile.mkdtemp() + sf = os.path.join(td, os.path.basename(filename) + '.asc') + cmd.extend(['--detach-sign', '--armor', '--local-user', + signer, '--output', sf, filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd, sf + + def run_command(self, cmd, input_data=None): + """ + Run a command in a child process , passing it any input data specified. + + :param cmd: The command to run. + :param input_data: If specified, this must be a byte string containing + data to be sent to the child process. + :return: A tuple consisting of the subprocess' exit code, a list of + lines read from the subprocess' ``stdout``, and a list of + lines read from the subprocess' ``stderr``. + """ + kwargs = { + 'stdout': subprocess.PIPE, + 'stderr': subprocess.PIPE, + } + if input_data is not None: + kwargs['stdin'] = subprocess.PIPE + stdout = [] + stderr = [] + p = subprocess.Popen(cmd, **kwargs) + # We don't use communicate() here because we may need to + # get clever with interacting with the command + t1 = Thread(target=self._reader, args=('stdout', p.stdout, stdout)) + t1.start() + t2 = Thread(target=self._reader, args=('stderr', p.stderr, stderr)) + t2.start() + if input_data is not None: + p.stdin.write(input_data) + p.stdin.close() + + p.wait() + t1.join() + t2.join() + return p.returncode, stdout, stderr + + def sign_file(self, filename, signer, sign_password, keystore=None): + """ + Sign a file. + + :param filename: The pathname to the file to be signed. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The absolute pathname of the file where the signature is + stored. + """ + cmd, sig_file = self.get_sign_command(filename, signer, sign_password, + keystore) + rc, stdout, stderr = self.run_command(cmd, + sign_password.encode('utf-8')) + if rc != 0: + raise DistlibException('sign command failed with error ' + 'code %s' % rc) + return sig_file + + def upload_file(self, metadata, filename, signer=None, sign_password=None, + filetype='sdist', pyversion='source', keystore=None): + """ + Upload a release file to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the file to be uploaded. + :param filename: The pathname of the file to be uploaded. + :param signer: The identifier of the signer of the file. + :param sign_password: The passphrase for the signer's + private key used for signing. + :param filetype: The type of the file being uploaded. This is the + distutils command which produced that file, e.g. + ``sdist`` or ``bdist_wheel``. + :param pyversion: The version of Python which the release relates + to. For code compatible with any Python, this would + be ``source``, otherwise it would be e.g. ``3.2``. + :param keystore: The path to a directory which contains the keys + used in signing. If not specified, the instance's + ``gpg_home`` attribute is used instead. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.exists(filename): + raise DistlibException('not found: %s' % filename) + metadata.validate() + d = metadata.todict() + sig_file = None + if signer: + if not self.gpg: + logger.warning('no signing program available - not signed') + else: + sig_file = self.sign_file(filename, signer, sign_password, + keystore) + with open(filename, 'rb') as f: + file_data = f.read() + md5_digest = hashlib.md5(file_data).hexdigest() + sha256_digest = hashlib.sha256(file_data).hexdigest() + d.update({ + ':action': 'file_upload', + 'protocol_version': '1', + 'filetype': filetype, + 'pyversion': pyversion, + 'md5_digest': md5_digest, + 'sha256_digest': sha256_digest, + }) + files = [('content', os.path.basename(filename), file_data)] + if sig_file: + with open(sig_file, 'rb') as f: + sig_data = f.read() + files.append(('gpg_signature', os.path.basename(sig_file), + sig_data)) + shutil.rmtree(os.path.dirname(sig_file)) + request = self.encode_request(d.items(), files) + return self.send_request(request) + + def upload_documentation(self, metadata, doc_dir): + """ + Upload documentation to the index. + + :param metadata: A :class:`Metadata` instance defining at least a name + and version number for the documentation to be + uploaded. + :param doc_dir: The pathname of the directory which contains the + documentation. This should be the directory that + contains the ``index.html`` for the documentation. + :return: The HTTP response received from PyPI upon submission of the + request. + """ + self.check_credentials() + if not os.path.isdir(doc_dir): + raise DistlibException('not a directory: %r' % doc_dir) + fn = os.path.join(doc_dir, 'index.html') + if not os.path.exists(fn): + raise DistlibException('not found: %r' % fn) + metadata.validate() + name, version = metadata.name, metadata.version + zip_data = zip_dir(doc_dir).getvalue() + fields = [(':action', 'doc_upload'), + ('name', name), ('version', version)] + files = [('content', name, zip_data)] + request = self.encode_request(fields, files) + return self.send_request(request) + + def get_verify_command(self, signature_filename, data_filename, + keystore=None): + """ + Return a suitable command for verifying a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: The verifying command as a list suitable to be + passed to :class:`subprocess.Popen`. + """ + cmd = [self.gpg, '--status-fd', '2', '--no-tty'] + if keystore is None: + keystore = self.gpg_home + if keystore: + cmd.extend(['--homedir', keystore]) + cmd.extend(['--verify', signature_filename, data_filename]) + logger.debug('invoking: %s', ' '.join(cmd)) + return cmd + + def verify_signature(self, signature_filename, data_filename, + keystore=None): + """ + Verify a signature for a file. + + :param signature_filename: The pathname to the file containing the + signature. + :param data_filename: The pathname to the file containing the + signed data. + :param keystore: The path to a directory which contains the keys + used in verification. If not specified, the + instance's ``gpg_home`` attribute is used instead. + :return: True if the signature was verified, else False. + """ + if not self.gpg: + raise DistlibException('verification unavailable because gpg ' + 'unavailable') + cmd = self.get_verify_command(signature_filename, data_filename, + keystore) + rc, stdout, stderr = self.run_command(cmd) + if rc not in (0, 1): + raise DistlibException('verify command failed with error ' + 'code %s' % rc) + return rc == 0 + + def download_file(self, url, destfile, digest=None, reporthook=None): + """ + This is a convenience method for downloading a file from an URL. + Normally, this will be a file from the index, though currently + no check is made for this (i.e. a file can be downloaded from + anywhere). + + The method is just like the :func:`urlretrieve` function in the + standard library, except that it allows digest computation to be + done during download and checking that the downloaded data + matched any expected value. + + :param url: The URL of the file to be downloaded (assumed to be + available via an HTTP GET request). + :param destfile: The pathname where the downloaded file is to be + saved. + :param digest: If specified, this must be a (hasher, value) + tuple, where hasher is the algorithm used (e.g. + ``'md5'``) and ``value`` is the expected value. + :param reporthook: The same as for :func:`urlretrieve` in the + standard library. + """ + if digest is None: + digester = None + logger.debug('No digest specified') + else: + if isinstance(digest, (list, tuple)): + hasher, digest = digest + else: + hasher = 'md5' + digester = getattr(hashlib, hasher)() + logger.debug('Digest specified: %s' % digest) + # The following code is equivalent to urlretrieve. + # We need to do it this way so that we can compute the + # digest of the file as we go. + with open(destfile, 'wb') as dfp: + # addinfourl is not a context manager on 2.x + # so we have to use try/finally + sfp = self.send_request(Request(url)) + try: + headers = sfp.info() + blocksize = 8192 + size = -1 + read = 0 + blocknum = 0 + if "content-length" in headers: + size = int(headers["Content-Length"]) + if reporthook: + reporthook(blocknum, blocksize, size) + while True: + block = sfp.read(blocksize) + if not block: + break + read += len(block) + dfp.write(block) + if digester: + digester.update(block) + blocknum += 1 + if reporthook: + reporthook(blocknum, blocksize, size) + finally: + sfp.close() + + # check that we got the whole file, if we can + if size >= 0 and read < size: + raise DistlibException( + 'retrieval incomplete: got only %d out of %d bytes' + % (read, size)) + # if we have a digest, it must match. + if digester: + actual = digester.hexdigest() + if digest != actual: + raise DistlibException('%s digest mismatch for %s: expected ' + '%s, got %s' % (hasher, destfile, + digest, actual)) + logger.debug('Digest verified: %s', digest) + + def send_request(self, req): + """ + Send a standard library :class:`Request` to PyPI and return its + response. + + :param req: The request to send. + :return: The HTTP response from PyPI (a standard library HTTPResponse). + """ + handlers = [] + if self.password_handler: + handlers.append(self.password_handler) + if self.ssl_verifier: + handlers.append(self.ssl_verifier) + opener = build_opener(*handlers) + return opener.open(req) + + def encode_request(self, fields, files): + """ + Encode fields and files for posting to an HTTP server. + + :param fields: The fields to send as a list of (fieldname, value) + tuples. + :param files: The files to send as a list of (fieldname, filename, + file_bytes) tuple. + """ + # Adapted from packaging, which in turn was adapted from + # http://code.activestate.com/recipes/146306 + + parts = [] + boundary = self.boundary + for k, values in fields: + if not isinstance(values, (list, tuple)): + values = [values] + + for v in values: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"' % + k).encode('utf-8'), + b'', + v.encode('utf-8'))) + for key, filename, value in files: + parts.extend(( + b'--' + boundary, + ('Content-Disposition: form-data; name="%s"; filename="%s"' % + (key, filename)).encode('utf-8'), + b'', + value)) + + parts.extend((b'--' + boundary + b'--', b'')) + + body = b'\r\n'.join(parts) + ct = b'multipart/form-data; boundary=' + boundary + headers = { + 'Content-type': ct, + 'Content-length': str(len(body)) + } + return Request(self.url, body, headers) + + def search(self, terms, operator=None): + if isinstance(terms, string_types): + terms = {'name': terms} + rpc_proxy = ServerProxy(self.url, timeout=3.0) + try: + return rpc_proxy.search(terms, operator or 'and') + finally: + rpc_proxy('close')() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py new file mode 100644 index 0000000..11d2636 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/locators.py @@ -0,0 +1,1292 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# + +import gzip +from io import BytesIO +import json +import logging +import os +import posixpath +import re +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import zlib + +from . import DistlibException +from .compat import (urljoin, urlparse, urlunparse, url2pathname, pathname2url, + queue, quote, unescape, string_types, build_opener, + HTTPRedirectHandler as BaseRedirectHandler, text_type, + Request, HTTPError, URLError) +from .database import Distribution, DistributionPath, make_dist +from .metadata import Metadata, MetadataInvalidError +from .util import (cached_property, parse_credentials, ensure_slash, + split_filename, get_project_data, parse_requirement, + parse_name_and_version, ServerProxy, normalize_name) +from .version import get_scheme, UnsupportedVersionError +from .wheel import Wheel, is_compatible + +logger = logging.getLogger(__name__) + +HASHER_HASH = re.compile(r'^(\w+)=([a-f0-9]+)') +CHARSET = re.compile(r';\s*charset\s*=\s*(.*)\s*$', re.I) +HTML_CONTENT_TYPE = re.compile('text/html|application/x(ht)?ml') +DEFAULT_INDEX = 'https://pypi.python.org/pypi' + +def get_all_distribution_names(url=None): + """ + Return all distribution names known by an index. + :param url: The URL of the index. + :return: A list of all known distribution names. + """ + if url is None: + url = DEFAULT_INDEX + client = ServerProxy(url, timeout=3.0) + try: + return client.list_packages() + finally: + client('close')() + +class RedirectHandler(BaseRedirectHandler): + """ + A class to work around a bug in some Python 3.2.x releases. + """ + # There's a bug in the base version for some 3.2.x + # (e.g. 3.2.2 on Ubuntu Oneiric). If a Location header + # returns e.g. /abc, it bails because it says the scheme '' + # is bogus, when actually it should use the request's + # URL for the scheme. See Python issue #13696. + def http_error_302(self, req, fp, code, msg, headers): + # Some servers (incorrectly) return multiple Location headers + # (so probably same goes for URI). Use first header. + newurl = None + for key in ('location', 'uri'): + if key in headers: + newurl = headers[key] + break + if newurl is None: # pragma: no cover + return + urlparts = urlparse(newurl) + if urlparts.scheme == '': + newurl = urljoin(req.get_full_url(), newurl) + if hasattr(headers, 'replace_header'): + headers.replace_header(key, newurl) + else: + headers[key] = newurl + return BaseRedirectHandler.http_error_302(self, req, fp, code, msg, + headers) + + http_error_301 = http_error_303 = http_error_307 = http_error_302 + +class Locator(object): + """ + A base class for locators - things that locate distributions. + """ + source_extensions = ('.tar.gz', '.tar.bz2', '.tar', '.zip', '.tgz', '.tbz') + binary_extensions = ('.egg', '.exe', '.whl') + excluded_extensions = ('.pdf',) + + # A list of tags indicating which wheels you want to match. The default + # value of None matches against the tags compatible with the running + # Python. If you want to match other values, set wheel_tags on a locator + # instance to a list of tuples (pyver, abi, arch) which you want to match. + wheel_tags = None + + downloadable_extensions = source_extensions + ('.whl',) + + def __init__(self, scheme='default'): + """ + Initialise an instance. + :param scheme: Because locators look for most recent versions, they + need to know the version scheme to use. This specifies + the current PEP-recommended scheme - use ``'legacy'`` + if you need to support existing distributions on PyPI. + """ + self._cache = {} + self.scheme = scheme + # Because of bugs in some of the handlers on some of the platforms, + # we use our own opener rather than just using urlopen. + self.opener = build_opener(RedirectHandler()) + # If get_project() is called from locate(), the matcher instance + # is set from the requirement passed to locate(). See issue #18 for + # why this can be useful to know. + self.matcher = None + self.errors = queue.Queue() + + def get_errors(self): + """ + Return any errors which have occurred. + """ + result = [] + while not self.errors.empty(): # pragma: no cover + try: + e = self.errors.get(False) + result.append(e) + except self.errors.Empty: + continue + self.errors.task_done() + return result + + def clear_errors(self): + """ + Clear any errors which may have been logged. + """ + # Just get the errors and throw them away + self.get_errors() + + def clear_cache(self): + self._cache.clear() + + def _get_scheme(self): + return self._scheme + + def _set_scheme(self, value): + self._scheme = value + + scheme = property(_get_scheme, _set_scheme) + + def _get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This should be implemented in subclasses. + + If called from a locate() request, self.matcher will be set to a + matcher for the requirement to satisfy, otherwise it will be None. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Please implement in the subclass') + + def get_project(self, name): + """ + For a given project, get a dictionary mapping available versions to Distribution + instances. + + This calls _get_project to do all the work, and just implements a caching layer on top. + """ + if self._cache is None: # pragma: no cover + result = self._get_project(name) + elif name in self._cache: + result = self._cache[name] + else: + self.clear_errors() + result = self._get_project(name) + self._cache[name] = result + return result + + def score_url(self, url): + """ + Give an url a score which can be used to choose preferred URLs + for a given project release. + """ + t = urlparse(url) + basename = posixpath.basename(t.path) + compatible = True + is_wheel = basename.endswith('.whl') + is_downloadable = basename.endswith(self.downloadable_extensions) + if is_wheel: + compatible = is_compatible(Wheel(basename), self.wheel_tags) + return (t.scheme == 'https', 'pypi.python.org' in t.netloc, + is_downloadable, is_wheel, compatible, basename) + + def prefer_url(self, url1, url2): + """ + Choose one of two URLs where both are candidates for distribution + archives for the same version of a distribution (for example, + .tar.gz vs. zip). + + The current implementation favours https:// URLs over http://, archives + from PyPI over those from other locations, wheel compatibility (if a + wheel) and then the archive name. + """ + result = url2 + if url1: + s1 = self.score_url(url1) + s2 = self.score_url(url2) + if s1 > s2: + result = url1 + if result != url2: + logger.debug('Not replacing %r with %r', url1, url2) + else: + logger.debug('Replacing %r with %r', url1, url2) + return result + + def split_filename(self, filename, project_name): + """ + Attempt to split a filename in project name, version and Python version. + """ + return split_filename(filename, project_name) + + def convert_url_to_download_info(self, url, project_name): + """ + See if a URL is a candidate for a download URL for a project (the URL + has typically been scraped from an HTML page). + + If it is, a dictionary is returned with keys "name", "version", + "filename" and "url"; otherwise, None is returned. + """ + def same_project(name1, name2): + return normalize_name(name1) == normalize_name(name2) + + result = None + scheme, netloc, path, params, query, frag = urlparse(url) + if frag.lower().startswith('egg='): # pragma: no cover + logger.debug('%s: version hint in fragment: %r', + project_name, frag) + m = HASHER_HASH.match(frag) + if m: + algo, digest = m.groups() + else: + algo, digest = None, None + origpath = path + if path and path[-1] == '/': # pragma: no cover + path = path[:-1] + if path.endswith('.whl'): + try: + wheel = Wheel(path) + if is_compatible(wheel, self.wheel_tags): + if project_name is None: + include = True + else: + include = same_project(wheel.name, project_name) + if include: + result = { + 'name': wheel.name, + 'version': wheel.version, + 'filename': wheel.filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + 'python-version': ', '.join( + ['.'.join(list(v[2:])) for v in wheel.pyver]), + } + except Exception as e: # pragma: no cover + logger.warning('invalid path for wheel: %s', path) + elif not path.endswith(self.downloadable_extensions): # pragma: no cover + logger.debug('Not downloadable: %s', path) + else: # downloadable extension + path = filename = posixpath.basename(path) + for ext in self.downloadable_extensions: + if path.endswith(ext): + path = path[:-len(ext)] + t = self.split_filename(path, project_name) + if not t: # pragma: no cover + logger.debug('No match for project/version: %s', path) + else: + name, version, pyver = t + if not project_name or same_project(project_name, name): + result = { + 'name': name, + 'version': version, + 'filename': filename, + 'url': urlunparse((scheme, netloc, origpath, + params, query, '')), + #'packagetype': 'sdist', + } + if pyver: # pragma: no cover + result['python-version'] = pyver + break + if result and algo: + result['%s_digest' % algo] = digest + return result + + def _get_digest(self, info): + """ + Get a digest from a dictionary by looking at keys of the form + 'algo_digest'. + + Returns a 2-tuple (algo, digest) if found, else None. Currently + looks only for SHA256, then MD5. + """ + result = None + for algo in ('sha256', 'md5'): + key = '%s_digest' % algo + if key in info: + result = (algo, info[key]) + break + return result + + def _update_version_data(self, result, info): + """ + Update a result dictionary (the final result from _get_project) with a + dictionary for a specific version, which typically holds information + gleaned from a filename or URL for an archive for the distribution. + """ + name = info.pop('name') + version = info.pop('version') + if version in result: + dist = result[version] + md = dist.metadata + else: + dist = make_dist(name, version, scheme=self.scheme) + md = dist.metadata + dist.digest = digest = self._get_digest(info) + url = info['url'] + result['digests'][url] = digest + if md.source_url != info['url']: + md.source_url = self.prefer_url(md.source_url, url) + result['urls'].setdefault(version, set()).add(url) + dist.locator = self + result[version] = dist + + def locate(self, requirement, prereleases=False): + """ + Find the most recent distribution which matches the given + requirement. + + :param requirement: A requirement of the form 'foo (1.0)' or perhaps + 'foo (>= 1.0, < 2.0, != 1.3)' + :param prereleases: If ``True``, allow pre-release versions + to be located. Otherwise, pre-release versions + are not returned. + :return: A :class:`Distribution` instance, or ``None`` if no such + distribution could be located. + """ + result = None + r = parse_requirement(requirement) + if r is None: # pragma: no cover + raise DistlibException('Not a valid requirement: %r' % requirement) + scheme = get_scheme(self.scheme) + self.matcher = matcher = scheme.matcher(r.requirement) + logger.debug('matcher: %s (%s)', matcher, type(matcher).__name__) + versions = self.get_project(r.name) + if len(versions) > 2: # urls and digests keys are present + # sometimes, versions are invalid + slist = [] + vcls = matcher.version_class + for k in versions: + if k in ('urls', 'digests'): + continue + try: + if not matcher.match(k): + logger.debug('%s did not match %r', matcher, k) + else: + if prereleases or not vcls(k).is_prerelease: + slist.append(k) + else: + logger.debug('skipping pre-release ' + 'version %s of %s', k, matcher.name) + except Exception: # pragma: no cover + logger.warning('error matching %s with %r', matcher, k) + pass # slist.append(k) + if len(slist) > 1: + slist = sorted(slist, key=scheme.key) + if slist: + logger.debug('sorted list: %s', slist) + version = slist[-1] + result = versions[version] + if result: + if r.extras: + result.extras = r.extras + result.download_urls = versions.get('urls', {}).get(version, set()) + d = {} + sd = versions.get('digests', {}) + for url in result.download_urls: + if url in sd: # pragma: no cover + d[url] = sd[url] + result.digests = d + self.matcher = None + return result + + +class PyPIRPCLocator(Locator): + """ + This locator uses XML-RPC to locate distributions. It therefore + cannot be used with simple mirrors (that only mirror file content). + """ + def __init__(self, url, **kwargs): + """ + Initialise an instance. + + :param url: The URL to use for XML-RPC. + :param kwargs: Passed to the superclass constructor. + """ + super(PyPIRPCLocator, self).__init__(**kwargs) + self.base_url = url + self.client = ServerProxy(url, timeout=3.0) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + return set(self.client.list_packages()) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + versions = self.client.package_releases(name, True) + for v in versions: + urls = self.client.release_urls(name, v) + data = self.client.release_data(name, v) + metadata = Metadata(scheme=self.scheme) + metadata.name = data['name'] + metadata.version = data['version'] + metadata.license = data.get('license') + metadata.keywords = data.get('keywords', []) + metadata.summary = data.get('summary') + dist = Distribution(metadata) + if urls: + info = urls[0] + metadata.source_url = info['url'] + dist.digest = self._get_digest(info) + dist.locator = self + result[v] = dist + for info in urls: + url = info['url'] + digest = self._get_digest(info) + result['urls'].setdefault(v, set()).add(url) + result['digests'][url] = digest + return result + +class PyPIJSONLocator(Locator): + """ + This locator uses PyPI's JSON interface. It's very limited in functionality + and probably not worth using. + """ + def __init__(self, url, **kwargs): + super(PyPIJSONLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + url = urljoin(self.base_url, '%s/json' % quote(name)) + try: + resp = self.opener.open(url) + data = resp.read().decode() # for now + d = json.loads(data) + md = Metadata(scheme=self.scheme) + data = d['info'] + md.name = data['name'] + md.version = data['version'] + md.license = data.get('license') + md.keywords = data.get('keywords', []) + md.summary = data.get('summary') + dist = Distribution(md) + dist.locator = self + urls = d['urls'] + result[md.version] = dist + for info in d['urls']: + url = info['url'] + dist.download_urls.add(url) + dist.digests[url] = self._get_digest(info) + result['urls'].setdefault(md.version, set()).add(url) + result['digests'][url] = self._get_digest(info) + # Now get other releases + for version, infos in d['releases'].items(): + if version == md.version: + continue # already done + omd = Metadata(scheme=self.scheme) + omd.name = md.name + omd.version = version + odist = Distribution(omd) + odist.locator = self + result[version] = odist + for info in infos: + url = info['url'] + odist.download_urls.add(url) + odist.digests[url] = self._get_digest(info) + result['urls'].setdefault(version, set()).add(url) + result['digests'][url] = self._get_digest(info) +# for info in urls: +# md.source_url = info['url'] +# dist.digest = self._get_digest(info) +# dist.locator = self +# for info in urls: +# url = info['url'] +# result['urls'].setdefault(md.version, set()).add(url) +# result['digests'][url] = self._get_digest(info) + except Exception as e: + self.errors.put(text_type(e)) + logger.exception('JSON fetch failed: %s', e) + return result + + +class Page(object): + """ + This class represents a scraped HTML page. + """ + # The following slightly hairy-looking regex just looks for the contents of + # an anchor link, which has an attribute "href" either immediately preceded + # or immediately followed by a "rel" attribute. The attribute values can be + # declared with double quotes, single quotes or no quotes - which leads to + # the length of the expression. + _href = re.compile(""" +(rel\\s*=\\s*(?:"(?P<rel1>[^"]*)"|'(?P<rel2>[^']*)'|(?P<rel3>[^>\\s\n]*))\\s+)? +href\\s*=\\s*(?:"(?P<url1>[^"]*)"|'(?P<url2>[^']*)'|(?P<url3>[^>\\s\n]*)) +(\\s+rel\\s*=\\s*(?:"(?P<rel4>[^"]*)"|'(?P<rel5>[^']*)'|(?P<rel6>[^>\\s\n]*)))? +""", re.I | re.S | re.X) + _base = re.compile(r"""<base\s+href\s*=\s*['"]?([^'">]+)""", re.I | re.S) + + def __init__(self, data, url): + """ + Initialise an instance with the Unicode page contents and the URL they + came from. + """ + self.data = data + self.base_url = self.url = url + m = self._base.search(self.data) + if m: + self.base_url = m.group(1) + + _clean_re = re.compile(r'[^a-z0-9$&+,/:;=?@.#%_\\|-]', re.I) + + @cached_property + def links(self): + """ + Return the URLs of all the links on a page together with information + about their "rel" attribute, for determining which ones to treat as + downloads and which ones to queue for further scraping. + """ + def clean(url): + "Tidy up an URL." + scheme, netloc, path, params, query, frag = urlparse(url) + return urlunparse((scheme, netloc, quote(path), + params, query, frag)) + + result = set() + for match in self._href.finditer(self.data): + d = match.groupdict('') + rel = (d['rel1'] or d['rel2'] or d['rel3'] or + d['rel4'] or d['rel5'] or d['rel6']) + url = d['url1'] or d['url2'] or d['url3'] + url = urljoin(self.base_url, url) + url = unescape(url) + url = self._clean_re.sub(lambda m: '%%%2x' % ord(m.group(0)), url) + result.add((url, rel)) + # We sort the result, hoping to bring the most recent versions + # to the front + result = sorted(result, key=lambda t: t[0], reverse=True) + return result + + +class SimpleScrapingLocator(Locator): + """ + A locator which scrapes HTML pages to locate downloads for a distribution. + This runs multiple threads to do the I/O; performance is at least as good + as pip's PackageFinder, which works in an analogous fashion. + """ + + # These are used to deal with various Content-Encoding schemes. + decoders = { + 'deflate': zlib.decompress, + 'gzip': lambda b: gzip.GzipFile(fileobj=BytesIO(d)).read(), + 'none': lambda b: b, + } + + def __init__(self, url, timeout=None, num_workers=10, **kwargs): + """ + Initialise an instance. + :param url: The root URL to use for scraping. + :param timeout: The timeout, in seconds, to be applied to requests. + This defaults to ``None`` (no timeout specified). + :param num_workers: The number of worker threads you want to do I/O, + This defaults to 10. + :param kwargs: Passed to the superclass. + """ + super(SimpleScrapingLocator, self).__init__(**kwargs) + self.base_url = ensure_slash(url) + self.timeout = timeout + self._page_cache = {} + self._seen = set() + self._to_fetch = queue.Queue() + self._bad_hosts = set() + self.skip_externals = False + self.num_workers = num_workers + self._lock = threading.RLock() + # See issue #45: we need to be resilient when the locator is used + # in a thread, e.g. with concurrent.futures. We can't use self._lock + # as it is for coordinating our internal threads - the ones created + # in _prepare_threads. + self._gplock = threading.RLock() + + def _prepare_threads(self): + """ + Threads are created only when get_project is called, and terminate + before it returns. They are there primarily to parallelise I/O (i.e. + fetching web pages). + """ + self._threads = [] + for i in range(self.num_workers): + t = threading.Thread(target=self._fetch) + t.setDaemon(True) + t.start() + self._threads.append(t) + + def _wait_threads(self): + """ + Tell all the threads to terminate (by sending a sentinel value) and + wait for them to do so. + """ + # Note that you need two loops, since you can't say which + # thread will get each sentinel + for t in self._threads: + self._to_fetch.put(None) # sentinel + for t in self._threads: + t.join() + self._threads = [] + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + with self._gplock: + self.result = result + self.project_name = name + url = urljoin(self.base_url, '%s/' % quote(name)) + self._seen.clear() + self._page_cache.clear() + self._prepare_threads() + try: + logger.debug('Queueing %s', url) + self._to_fetch.put(url) + self._to_fetch.join() + finally: + self._wait_threads() + del self.result + return result + + platform_dependent = re.compile(r'\b(linux-(i\d86|x86_64|arm\w+)|' + r'win(32|-amd64)|macosx-?\d+)\b', re.I) + + def _is_platform_dependent(self, url): + """ + Does an URL refer to a platform-specific download? + """ + return self.platform_dependent.search(url) + + def _process_download(self, url): + """ + See if an URL is a suitable download for a project. + + If it is, register information in the result dictionary (for + _get_project) about the specific version it's for. + + Note that the return value isn't actually used other than as a boolean + value. + """ + if self._is_platform_dependent(url): + info = None + else: + info = self.convert_url_to_download_info(url, self.project_name) + logger.debug('process_download: %s -> %s', url, info) + if info: + with self._lock: # needed because self.result is shared + self._update_version_data(self.result, info) + return info + + def _should_queue(self, link, referrer, rel): + """ + Determine whether a link URL from a referring page and with a + particular "rel" attribute should be queued for scraping. + """ + scheme, netloc, path, _, _, _ = urlparse(link) + if path.endswith(self.source_extensions + self.binary_extensions + + self.excluded_extensions): + result = False + elif self.skip_externals and not link.startswith(self.base_url): + result = False + elif not referrer.startswith(self.base_url): + result = False + elif rel not in ('homepage', 'download'): + result = False + elif scheme not in ('http', 'https', 'ftp'): + result = False + elif self._is_platform_dependent(link): + result = False + else: + host = netloc.split(':', 1)[0] + if host.lower() == 'localhost': + result = False + else: + result = True + logger.debug('should_queue: %s (%s) from %s -> %s', link, rel, + referrer, result) + return result + + def _fetch(self): + """ + Get a URL to fetch from the work queue, get the HTML page, examine its + links for download candidates and candidates for further scraping. + + This is a handy method to run in a thread. + """ + while True: + url = self._to_fetch.get() + try: + if url: + page = self.get_page(url) + if page is None: # e.g. after an error + continue + for link, rel in page.links: + if link not in self._seen: + try: + self._seen.add(link) + if (not self._process_download(link) and + self._should_queue(link, url, rel)): + logger.debug('Queueing %s from %s', link, url) + self._to_fetch.put(link) + except MetadataInvalidError: # e.g. invalid versions + pass + except Exception as e: # pragma: no cover + self.errors.put(text_type(e)) + finally: + # always do this, to avoid hangs :-) + self._to_fetch.task_done() + if not url: + #logger.debug('Sentinel seen, quitting.') + break + + def get_page(self, url): + """ + Get the HTML for an URL, possibly from an in-memory cache. + + XXX TODO Note: this cache is never actually cleared. It's assumed that + the data won't get stale over the lifetime of a locator instance (not + necessarily true for the default_locator). + """ + # http://peak.telecommunity.com/DevCenter/EasyInstall#package-index-api + scheme, netloc, path, _, _, _ = urlparse(url) + if scheme == 'file' and os.path.isdir(url2pathname(path)): + url = urljoin(ensure_slash(url), 'index.html') + + if url in self._page_cache: + result = self._page_cache[url] + logger.debug('Returning %s from cache: %s', url, result) + else: + host = netloc.split(':', 1)[0] + result = None + if host in self._bad_hosts: + logger.debug('Skipping %s due to bad host %s', url, host) + else: + req = Request(url, headers={'Accept-encoding': 'identity'}) + try: + logger.debug('Fetching %s', url) + resp = self.opener.open(req, timeout=self.timeout) + logger.debug('Fetched %s', url) + headers = resp.info() + content_type = headers.get('Content-Type', '') + if HTML_CONTENT_TYPE.match(content_type): + final_url = resp.geturl() + data = resp.read() + encoding = headers.get('Content-Encoding') + if encoding: + decoder = self.decoders[encoding] # fail if not found + data = decoder(data) + encoding = 'utf-8' + m = CHARSET.search(content_type) + if m: + encoding = m.group(1) + try: + data = data.decode(encoding) + except UnicodeError: # pragma: no cover + data = data.decode('latin-1') # fallback + result = Page(data, final_url) + self._page_cache[final_url] = result + except HTTPError as e: + if e.code != 404: + logger.exception('Fetch failed: %s: %s', url, e) + except URLError as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + with self._lock: + self._bad_hosts.add(host) + except Exception as e: # pragma: no cover + logger.exception('Fetch failed: %s: %s', url, e) + finally: + self._page_cache[url] = result # even if None (failure) + return result + + _distname_re = re.compile('<a href=[^>]*>([^<]+)<') + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + page = self.get_page(self.base_url) + if not page: + raise DistlibException('Unable to get %s' % self.base_url) + for match in self._distname_re.finditer(page.data): + result.add(match.group(1)) + return result + +class DirectoryLocator(Locator): + """ + This class locates distributions in a directory tree. + """ + + def __init__(self, path, **kwargs): + """ + Initialise an instance. + :param path: The root of the directory tree to search. + :param kwargs: Passed to the superclass constructor, + except for: + * recursive - if True (the default), subdirectories are + recursed into. If False, only the top-level directory + is searched, + """ + self.recursive = kwargs.pop('recursive', True) + super(DirectoryLocator, self).__init__(**kwargs) + path = os.path.abspath(path) + if not os.path.isdir(path): # pragma: no cover + raise DistlibException('Not a directory: %r' % path) + self.base_dir = path + + def should_include(self, filename, parent): + """ + Should a filename be considered as a candidate for a distribution + archive? As well as the filename, the directory which contains it + is provided, though not used by the current implementation. + """ + return filename.endswith(self.downloadable_extensions) + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, name) + if info: + self._update_version_data(result, info) + if not self.recursive: + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for root, dirs, files in os.walk(self.base_dir): + for fn in files: + if self.should_include(fn, root): + fn = os.path.join(root, fn) + url = urlunparse(('file', '', + pathname2url(os.path.abspath(fn)), + '', '', '')) + info = self.convert_url_to_download_info(url, None) + if info: + result.add(info['name']) + if not self.recursive: + break + return result + +class JSONLocator(Locator): + """ + This locator uses special extended metadata (not available on PyPI) and is + the basis of performant dependency resolution in distlib. Other locators + require archive downloads before dependencies can be determined! As you + might imagine, that can be slow. + """ + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + raise NotImplementedError('Not available from this locator') + + def _get_project(self, name): + result = {'urls': {}, 'digests': {}} + data = get_project_data(name) + if data: + for info in data.get('files', []): + if info['ptype'] != 'sdist' or info['pyversion'] != 'source': + continue + # We don't store summary in project metadata as it makes + # the data bigger for no benefit during dependency + # resolution + dist = make_dist(data['name'], info['version'], + summary=data.get('summary', + 'Placeholder for summary'), + scheme=self.scheme) + md = dist.metadata + md.source_url = info['url'] + # TODO SHA256 digest + if 'digest' in info and info['digest']: + dist.digest = ('md5', info['digest']) + md.dependencies = info.get('requirements', {}) + dist.exports = info.get('exports', {}) + result[dist.version] = dist + result['urls'].setdefault(dist.version, set()).add(info['url']) + return result + +class DistPathLocator(Locator): + """ + This locator finds installed distributions in a path. It can be useful for + adding to an :class:`AggregatingLocator`. + """ + def __init__(self, distpath, **kwargs): + """ + Initialise an instance. + + :param distpath: A :class:`DistributionPath` instance to search. + """ + super(DistPathLocator, self).__init__(**kwargs) + assert isinstance(distpath, DistributionPath) + self.distpath = distpath + + def _get_project(self, name): + dist = self.distpath.get_distribution(name) + if dist is None: + result = {'urls': {}, 'digests': {}} + else: + result = { + dist.version: dist, + 'urls': {dist.version: set([dist.source_url])}, + 'digests': {dist.version: set([None])} + } + return result + + +class AggregatingLocator(Locator): + """ + This class allows you to chain and/or merge a list of locators. + """ + def __init__(self, *locators, **kwargs): + """ + Initialise an instance. + + :param locators: The list of locators to search. + :param kwargs: Passed to the superclass constructor, + except for: + * merge - if False (the default), the first successful + search from any of the locators is returned. If True, + the results from all locators are merged (this can be + slow). + """ + self.merge = kwargs.pop('merge', False) + self.locators = locators + super(AggregatingLocator, self).__init__(**kwargs) + + def clear_cache(self): + super(AggregatingLocator, self).clear_cache() + for locator in self.locators: + locator.clear_cache() + + def _set_scheme(self, value): + self._scheme = value + for locator in self.locators: + locator.scheme = value + + scheme = property(Locator.scheme.fget, _set_scheme) + + def _get_project(self, name): + result = {} + for locator in self.locators: + d = locator.get_project(name) + if d: + if self.merge: + files = result.get('urls', {}) + digests = result.get('digests', {}) + # next line could overwrite result['urls'], result['digests'] + result.update(d) + df = result.get('urls') + if files and df: + for k, v in files.items(): + if k in df: + df[k] |= v + else: + df[k] = v + dd = result.get('digests') + if digests and dd: + dd.update(digests) + else: + # See issue #18. If any dists are found and we're looking + # for specific constraints, we only return something if + # a match is found. For example, if a DirectoryLocator + # returns just foo (1.0) while we're looking for + # foo (>= 2.0), we'll pretend there was nothing there so + # that subsequent locators can be queried. Otherwise we + # would just return foo (1.0) which would then lead to a + # failure to find foo (>= 2.0), because other locators + # weren't searched. Note that this only matters when + # merge=False. + if self.matcher is None: + found = True + else: + found = False + for k in d: + if self.matcher.match(k): + found = True + break + if found: + result = d + break + return result + + def get_distribution_names(self): + """ + Return all the distribution names known to this locator. + """ + result = set() + for locator in self.locators: + try: + result |= locator.get_distribution_names() + except NotImplementedError: + pass + return result + + +# We use a legacy scheme simply because most of the dists on PyPI use legacy +# versions which don't conform to PEP 426 / PEP 440. +default_locator = AggregatingLocator( + JSONLocator(), + SimpleScrapingLocator('https://pypi.python.org/simple/', + timeout=3.0), + scheme='legacy') + +locate = default_locator.locate + +NAME_VERSION_RE = re.compile(r'(?P<name>[\w-]+)\s*' + r'\(\s*(==\s*)?(?P<ver>[^)]+)\)$') + +class DependencyFinder(object): + """ + Locate dependencies for distributions. + """ + + def __init__(self, locator=None): + """ + Initialise an instance, using the specified locator + to locate distributions. + """ + self.locator = locator or default_locator + self.scheme = get_scheme(self.locator.scheme) + + def add_distribution(self, dist): + """ + Add a distribution to the finder. This will update internal information + about who provides what. + :param dist: The distribution to add. + """ + logger.debug('adding distribution %s', dist) + name = dist.key + self.dists_by_name[name] = dist + self.dists[(name, dist.version)] = dist + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Add to provided: %s, %s, %s', name, version, dist) + self.provided.setdefault(name, set()).add((version, dist)) + + def remove_distribution(self, dist): + """ + Remove a distribution from the finder. This will update internal + information about who provides what. + :param dist: The distribution to remove. + """ + logger.debug('removing distribution %s', dist) + name = dist.key + del self.dists_by_name[name] + del self.dists[(name, dist.version)] + for p in dist.provides: + name, version = parse_name_and_version(p) + logger.debug('Remove from provided: %s, %s, %s', name, version, dist) + s = self.provided[name] + s.remove((version, dist)) + if not s: + del self.provided[name] + + def get_matcher(self, reqt): + """ + Get a version matcher for a requirement. + :param reqt: The requirement + :type reqt: str + :return: A version matcher (an instance of + :class:`distlib.version.Matcher`). + """ + try: + matcher = self.scheme.matcher(reqt) + except UnsupportedVersionError: # pragma: no cover + # XXX compat-mode if cannot read the version + name = reqt.split()[0] + matcher = self.scheme.matcher(name) + return matcher + + def find_providers(self, reqt): + """ + Find the distributions which can fulfill a requirement. + + :param reqt: The requirement. + :type reqt: str + :return: A set of distribution which can fulfill the requirement. + """ + matcher = self.get_matcher(reqt) + name = matcher.key # case-insensitive + result = set() + provided = self.provided + if name in provided: + for version, provider in provided[name]: + try: + match = matcher.match(version) + except UnsupportedVersionError: + match = False + + if match: + result.add(provider) + break + return result + + def try_to_replace(self, provider, other, problems): + """ + Attempt to replace one provider with another. This is typically used + when resolving dependencies from multiple sources, e.g. A requires + (B >= 1.0) while C requires (B >= 1.1). + + For successful replacement, ``provider`` must meet all the requirements + which ``other`` fulfills. + + :param provider: The provider we are trying to replace with. + :param other: The provider we're trying to replace. + :param problems: If False is returned, this will contain what + problems prevented replacement. This is currently + a tuple of the literal string 'cantreplace', + ``provider``, ``other`` and the set of requirements + that ``provider`` couldn't fulfill. + :return: True if we can replace ``other`` with ``provider``, else + False. + """ + rlist = self.reqts[other] + unmatched = set() + for s in rlist: + matcher = self.get_matcher(s) + if not matcher.match(provider.version): + unmatched.add(s) + if unmatched: + # can't replace other with provider + problems.add(('cantreplace', provider, other, + frozenset(unmatched))) + result = False + else: + # can replace other with provider + self.remove_distribution(other) + del self.reqts[other] + for s in rlist: + self.reqts.setdefault(provider, set()).add(s) + self.add_distribution(provider) + result = True + return result + + def find(self, requirement, meta_extras=None, prereleases=False): + """ + Find a distribution and all distributions it depends on. + + :param requirement: The requirement specifying the distribution to + find, or a Distribution instance. + :param meta_extras: A list of meta extras such as :test:, :build: and + so on. + :param prereleases: If ``True``, allow pre-release versions to be + returned - otherwise, don't return prereleases + unless they're all that's available. + + Return a set of :class:`Distribution` instances and a set of + problems. + + The distributions returned should be such that they have the + :attr:`required` attribute set to ``True`` if they were + from the ``requirement`` passed to ``find()``, and they have the + :attr:`build_time_dependency` attribute set to ``True`` unless they + are post-installation dependencies of the ``requirement``. + + The problems should be a tuple consisting of the string + ``'unsatisfied'`` and the requirement which couldn't be satisfied + by any distribution known to the locator. + """ + + self.provided = {} + self.dists = {} + self.dists_by_name = {} + self.reqts = {} + + meta_extras = set(meta_extras or []) + if ':*:' in meta_extras: + meta_extras.remove(':*:') + # :meta: and :run: are implicitly included + meta_extras |= set([':test:', ':build:', ':dev:']) + + if isinstance(requirement, Distribution): + dist = odist = requirement + logger.debug('passed %s as requirement', odist) + else: + dist = odist = self.locator.locate(requirement, + prereleases=prereleases) + if dist is None: + raise DistlibException('Unable to locate %r' % requirement) + logger.debug('located %s', odist) + dist.requested = True + problems = set() + todo = set([dist]) + install_dists = set([odist]) + while todo: + dist = todo.pop() + name = dist.key # case-insensitive + if name not in self.dists_by_name: + self.add_distribution(dist) + else: + #import pdb; pdb.set_trace() + other = self.dists_by_name[name] + if other != dist: + self.try_to_replace(dist, other, problems) + + ireqts = dist.run_requires | dist.meta_requires + sreqts = dist.build_requires + ereqts = set() + if meta_extras and dist in install_dists: + for key in ('test', 'build', 'dev'): + e = ':%s:' % key + if e in meta_extras: + ereqts |= getattr(dist, '%s_requires' % key) + all_reqts = ireqts | sreqts | ereqts + for r in all_reqts: + providers = self.find_providers(r) + if not providers: + logger.debug('No providers found for %r', r) + provider = self.locator.locate(r, prereleases=prereleases) + # If no provider is found and we didn't consider + # prereleases, consider them now. + if provider is None and not prereleases: + provider = self.locator.locate(r, prereleases=True) + if provider is None: + logger.debug('Cannot satisfy %r', r) + problems.add(('unsatisfied', r)) + else: + n, v = provider.key, provider.version + if (n, v) not in self.dists: + todo.add(provider) + providers.add(provider) + if r in ireqts and dist in install_dists: + install_dists.add(provider) + logger.debug('Adding %s to install_dists', + provider.name_and_version) + for p in providers: + name = p.key + if name not in self.dists_by_name: + self.reqts.setdefault(p, set()).add(r) + else: + other = self.dists_by_name[name] + if other != p: + # see if other can be replaced by p + self.try_to_replace(p, other, problems) + + dists = set(self.dists.values()) + for dist in dists: + dist.build_time_dependency = dist not in install_dists + if dist.build_time_dependency: + logger.debug('%s is a build-time dependency only.', + dist.name_and_version) + logger.debug('find done for %s', odist) + return dists, problems diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py new file mode 100644 index 0000000..ca0fe44 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/manifest.py @@ -0,0 +1,393 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2013 Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Class representing the list of files in a distribution. + +Equivalent to distutils.filelist, but fixes some problems. +""" +import fnmatch +import logging +import os +import re +import sys + +from . import DistlibException +from .compat import fsdecode +from .util import convert_path + + +__all__ = ['Manifest'] + +logger = logging.getLogger(__name__) + +# a \ followed by some spaces + EOL +_COLLAPSE_PATTERN = re.compile('\\\\w*\n', re.M) +_COMMENTED_LINE = re.compile('#.*?(?=\n)|\n(?=$)', re.M | re.S) + +# +# Due to the different results returned by fnmatch.translate, we need +# to do slightly different processing for Python 2.7 and 3.2 ... this needed +# to be brought in for Python 3.6 onwards. +# +_PYTHON_VERSION = sys.version_info[:2] + +class Manifest(object): + """A list of files built by on exploring the filesystem and filtered by + applying various patterns to what we find there. + """ + + def __init__(self, base=None): + """ + Initialise an instance. + + :param base: The base directory to explore under. + """ + self.base = os.path.abspath(os.path.normpath(base or os.getcwd())) + self.prefix = self.base + os.sep + self.allfiles = None + self.files = set() + + # + # Public API + # + + def findall(self): + """Find all files under the base and set ``allfiles`` to the absolute + pathnames of files found. + """ + from stat import S_ISREG, S_ISDIR, S_ISLNK + + self.allfiles = allfiles = [] + root = self.base + stack = [root] + pop = stack.pop + push = stack.append + + while stack: + root = pop() + names = os.listdir(root) + + for name in names: + fullname = os.path.join(root, name) + + # Avoid excess stat calls -- just one will do, thank you! + stat = os.stat(fullname) + mode = stat.st_mode + if S_ISREG(mode): + allfiles.append(fsdecode(fullname)) + elif S_ISDIR(mode) and not S_ISLNK(mode): + push(fullname) + + def add(self, item): + """ + Add a file to the manifest. + + :param item: The pathname to add. This can be relative to the base. + """ + if not item.startswith(self.prefix): + item = os.path.join(self.base, item) + self.files.add(os.path.normpath(item)) + + def add_many(self, items): + """ + Add a list of files to the manifest. + + :param items: The pathnames to add. These can be relative to the base. + """ + for item in items: + self.add(item) + + def sorted(self, wantdirs=False): + """ + Return sorted files in directory order + """ + + def add_dir(dirs, d): + dirs.add(d) + logger.debug('add_dir added %s', d) + if d != self.base: + parent, _ = os.path.split(d) + assert parent not in ('', '/') + add_dir(dirs, parent) + + result = set(self.files) # make a copy! + if wantdirs: + dirs = set() + for f in result: + add_dir(dirs, os.path.dirname(f)) + result |= dirs + return [os.path.join(*path_tuple) for path_tuple in + sorted(os.path.split(path) for path in result)] + + def clear(self): + """Clear all collected files.""" + self.files = set() + self.allfiles = [] + + def process_directive(self, directive): + """ + Process a directive which either adds some files from ``allfiles`` to + ``files``, or removes some files from ``files``. + + :param directive: The directive to process. This should be in a format + compatible with distutils ``MANIFEST.in`` files: + + http://docs.python.org/distutils/sourcedist.html#commands + """ + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dirpattern). + action, patterns, thedir, dirpattern = self._parse_directive(directive) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=True): + logger.warning('no files found matching %r', pattern) + + elif action == 'exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=True) + #if not found: + # logger.warning('no previously-included files ' + # 'found matching %r', pattern) + + elif action == 'global-include': + for pattern in patterns: + if not self._include_pattern(pattern, anchor=False): + logger.warning('no files found matching %r ' + 'anywhere in distribution', pattern) + + elif action == 'global-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, anchor=False) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found anywhere in ' + # 'distribution', pattern) + + elif action == 'recursive-include': + for pattern in patterns: + if not self._include_pattern(pattern, prefix=thedir): + logger.warning('no files found matching %r ' + 'under directory %r', pattern, thedir) + + elif action == 'recursive-exclude': + for pattern in patterns: + found = self._exclude_pattern(pattern, prefix=thedir) + #if not found: + # logger.warning('no previously-included files ' + # 'matching %r found under directory %r', + # pattern, thedir) + + elif action == 'graft': + if not self._include_pattern(None, prefix=dirpattern): + logger.warning('no directories found matching %r', + dirpattern) + + elif action == 'prune': + if not self._exclude_pattern(None, prefix=dirpattern): + logger.warning('no previously-included directories found ' + 'matching %r', dirpattern) + else: # pragma: no cover + # This should never happen, as it should be caught in + # _parse_template_line + raise DistlibException( + 'invalid action %r' % action) + + # + # Private API + # + + def _parse_directive(self, directive): + """ + Validate a directive. + :param directive: The directive to validate. + :return: A tuple of action, patterns, thedir, dir_patterns + """ + words = directive.split() + if len(words) == 1 and words[0] not in ('include', 'exclude', + 'global-include', + 'global-exclude', + 'recursive-include', + 'recursive-exclude', + 'graft', 'prune'): + # no action given, let's use the default 'include' + words.insert(0, 'include') + + action = words[0] + patterns = thedir = dir_pattern = None + + if action in ('include', 'exclude', + 'global-include', 'global-exclude'): + if len(words) < 2: + raise DistlibException( + '%r expects <pattern1> <pattern2> ...' % action) + + patterns = [convert_path(word) for word in words[1:]] + + elif action in ('recursive-include', 'recursive-exclude'): + if len(words) < 3: + raise DistlibException( + '%r expects <dir> <pattern1> <pattern2> ...' % action) + + thedir = convert_path(words[1]) + patterns = [convert_path(word) for word in words[2:]] + + elif action in ('graft', 'prune'): + if len(words) != 2: + raise DistlibException( + '%r expects a single <dir_pattern>' % action) + + dir_pattern = convert_path(words[1]) + + else: + raise DistlibException('unknown action %r' % action) + + return action, patterns, thedir, dir_pattern + + def _include_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Select strings (presumably filenames) from 'self.files' that + match 'pattern', a Unix-style wildcard (glob) pattern. + + Patterns are not quite the same as implemented by the 'fnmatch' + module: '*' and '?' match non-special characters, where "special" + is platform-dependent: slash on Unix; colon, slash, and backslash on + DOS/Windows; and colon on Mac OS. + + If 'anchor' is true (the default), then the pattern match is more + stringent: "*.py" will match "foo.py" but not "foo/bar.py". If + 'anchor' is false, both of these will match. + + If 'prefix' is supplied, then only filenames starting with 'prefix' + (itself a pattern) and ending with 'pattern', with anything in between + them, will match. 'anchor' is ignored in this case. + + If 'is_regex' is true, 'anchor' and 'prefix' are ignored, and + 'pattern' is assumed to be either a string containing a regex or a + regex object -- no translation is done, the regex is just compiled + and used as-is. + + Selected strings will be added to self.files. + + Return True if files are found. + """ + # XXX docstring lying about what the special chars are? + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + + # delayed loading of allfiles list + if self.allfiles is None: + self.findall() + + for name in self.allfiles: + if pattern_re.search(name): + self.files.add(name) + found = True + return found + + def _exclude_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Remove strings (presumably filenames) from 'files' that match + 'pattern'. + + Other parameters are the same as for 'include_pattern()', above. + The list 'self.files' is modified in place. Return True if files are + found. + + This API is public to allow e.g. exclusion of SCM subdirs, e.g. when + packaging source distributions + """ + found = False + pattern_re = self._translate_pattern(pattern, anchor, prefix, is_regex) + for f in list(self.files): + if pattern_re.search(f): + self.files.remove(f) + found = True + return found + + def _translate_pattern(self, pattern, anchor=True, prefix=None, + is_regex=False): + """Translate a shell-like wildcard pattern to a compiled regular + expression. + + Return the compiled regex. If 'is_regex' true, + then 'pattern' is directly compiled to a regex (if it's a string) + or just returned as-is (assumes it's a regex object). + """ + if is_regex: + if isinstance(pattern, str): + return re.compile(pattern) + else: + return pattern + + if _PYTHON_VERSION > (3, 2): + # ditch start and end characters + start, _, end = self._glob_to_re('_').partition('_') + + if pattern: + pattern_re = self._glob_to_re(pattern) + if _PYTHON_VERSION > (3, 2): + assert pattern_re.startswith(start) and pattern_re.endswith(end) + else: + pattern_re = '' + + base = re.escape(os.path.join(self.base, '')) + if prefix is not None: + # ditch end of pattern character + if _PYTHON_VERSION <= (3, 2): + empty_pattern = self._glob_to_re('') + prefix_re = self._glob_to_re(prefix)[:-len(empty_pattern)] + else: + prefix_re = self._glob_to_re(prefix) + assert prefix_re.startswith(start) and prefix_re.endswith(end) + prefix_re = prefix_re[len(start): len(prefix_re) - len(end)] + sep = os.sep + if os.sep == '\\': + sep = r'\\' + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + sep.join((prefix_re, + '.*' + pattern_re)) + else: + pattern_re = pattern_re[len(start): len(pattern_re) - len(end)] + pattern_re = r'%s%s%s%s.*%s%s' % (start, base, prefix_re, sep, + pattern_re, end) + else: # no prefix -- respect anchor flag + if anchor: + if _PYTHON_VERSION <= (3, 2): + pattern_re = '^' + base + pattern_re + else: + pattern_re = r'%s%s%s' % (start, base, pattern_re[len(start):]) + + return re.compile(pattern_re) + + def _glob_to_re(self, pattern): + """Translate a shell-like glob pattern to a regular expression. + + Return a string containing the regex. Differs from + 'fnmatch.translate()' in that '*' does not match "special characters" + (which are platform-specific). + """ + pattern_re = fnmatch.translate(pattern) + + # '?' and '*' in the glob pattern become '.' and '.*' in the RE, which + # IMHO is wrong -- '?' and '*' aren't supposed to match slash in Unix, + # and by extension they shouldn't match such "special characters" under + # any OS. So change all non-escaped dots in the RE to match any + # character except the special characters (currently: just os.sep). + sep = os.sep + if os.sep == '\\': + # we're using a regex to manipulate a regex, so we need + # to escape the backslash twice + sep = r'\\\\' + escaped = r'\1[^%s]' % sep + pattern_re = re.sub(r'((?<!\\)(\\\\)*)\.', escaped, pattern_re) + return pattern_re diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py new file mode 100644 index 0000000..ee1f3e2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/markers.py @@ -0,0 +1,131 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Parser for the environment markers micro-language defined in PEP 508. +""" + +# Note: In PEP 345, the micro-language was Python compatible, so the ast +# module could be used to parse it. However, PEP 508 introduced operators such +# as ~= and === which aren't in Python, necessitating a different approach. + +import os +import sys +import platform +import re + +from .compat import python_implementation, urlparse, string_types +from .util import in_venv, parse_marker + +__all__ = ['interpret'] + +def _is_literal(o): + if not isinstance(o, string_types) or not o: + return False + return o[0] in '\'"' + +class Evaluator(object): + """ + This class is used to evaluate marker expessions. + """ + + operations = { + '==': lambda x, y: x == y, + '===': lambda x, y: x == y, + '~=': lambda x, y: x == y or x > y, + '!=': lambda x, y: x != y, + '<': lambda x, y: x < y, + '<=': lambda x, y: x == y or x < y, + '>': lambda x, y: x > y, + '>=': lambda x, y: x == y or x > y, + 'and': lambda x, y: x and y, + 'or': lambda x, y: x or y, + 'in': lambda x, y: x in y, + 'not in': lambda x, y: x not in y, + } + + def evaluate(self, expr, context): + """ + Evaluate a marker expression returned by the :func:`parse_requirement` + function in the specified context. + """ + if isinstance(expr, string_types): + if expr[0] in '\'"': + result = expr[1:-1] + else: + if expr not in context: + raise SyntaxError('unknown variable: %s' % expr) + result = context[expr] + else: + assert isinstance(expr, dict) + op = expr['op'] + if op not in self.operations: + raise NotImplementedError('op not implemented: %s' % op) + elhs = expr['lhs'] + erhs = expr['rhs'] + if _is_literal(expr['lhs']) and _is_literal(expr['rhs']): + raise SyntaxError('invalid comparison: %s %s %s' % (elhs, op, erhs)) + + lhs = self.evaluate(elhs, context) + rhs = self.evaluate(erhs, context) + result = self.operations[op](lhs, rhs) + return result + +def default_context(): + def format_full_version(info): + version = '%s.%s.%s' % (info.major, info.minor, info.micro) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + if hasattr(sys, 'implementation'): + implementation_version = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + implementation_version = '0' + implementation_name = '' + + result = { + 'implementation_name': implementation_name, + 'implementation_version': implementation_version, + 'os_name': os.name, + 'platform_machine': platform.machine(), + 'platform_python_implementation': platform.python_implementation(), + 'platform_release': platform.release(), + 'platform_system': platform.system(), + 'platform_version': platform.version(), + 'platform_in_venv': str(in_venv()), + 'python_full_version': platform.python_version(), + 'python_version': platform.python_version()[:3], + 'sys_platform': sys.platform, + } + return result + +DEFAULT_CONTEXT = default_context() +del default_context + +evaluator = Evaluator() + +def interpret(marker, execution_context=None): + """ + Interpret a marker and return a result depending on environment. + + :param marker: The marker to interpret. + :type marker: str + :param execution_context: The context used for name lookup. + :type execution_context: mapping + """ + try: + expr, rest = parse_marker(marker) + except Exception as e: + raise SyntaxError('Unable to interpret marker syntax: %s: %s' % (marker, e)) + if rest and rest[0] != '#': + raise SyntaxError('unexpected trailing data in marker: %s: %s' % (marker, rest)) + context = dict(DEFAULT_CONTEXT) + if execution_context: + context.update(execution_context) + return evaluator.evaluate(expr, context) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py new file mode 100644 index 0000000..6d6470f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/metadata.py @@ -0,0 +1,1091 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +"""Implementation of the Metadata for Python packages PEPs. + +Supports all metadata formats (1.0, 1.1, 1.2, and 2.0 experimental). +""" +from __future__ import unicode_literals + +import codecs +from email import message_from_file +import json +import logging +import re + + +from . import DistlibException, __version__ +from .compat import StringIO, string_types, text_type +from .markers import interpret +from .util import extract_by_key, get_extras +from .version import get_scheme, PEP440_VERSION_RE + +logger = logging.getLogger(__name__) + + +class MetadataMissingError(DistlibException): + """A required metadata is missing""" + + +class MetadataConflictError(DistlibException): + """Attempt to read or write metadata fields that are conflictual.""" + + +class MetadataUnrecognizedVersionError(DistlibException): + """Unknown metadata version number.""" + + +class MetadataInvalidError(DistlibException): + """A metadata value is invalid""" + +# public API of this module +__all__ = ['Metadata', 'PKG_INFO_ENCODING', 'PKG_INFO_PREFERRED_VERSION'] + +# Encoding used for the PKG-INFO files +PKG_INFO_ENCODING = 'utf-8' + +# preferred version. Hopefully will be changed +# to 1.2 once PEP 345 is supported everywhere +PKG_INFO_PREFERRED_VERSION = '1.1' + +_LINE_PREFIX_1_2 = re.compile('\n \\|') +_LINE_PREFIX_PRE_1_2 = re.compile('\n ') +_241_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License') + +_314_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'License', 'Classifier', 'Download-URL', 'Obsoletes', + 'Provides', 'Requires') + +_314_MARKERS = ('Obsoletes', 'Provides', 'Requires', 'Classifier', + 'Download-URL') + +_345_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External') + +_345_MARKERS = ('Provides-Dist', 'Requires-Dist', 'Requires-Python', + 'Obsoletes-Dist', 'Requires-External', 'Maintainer', + 'Maintainer-email', 'Project-URL') + +_426_FIELDS = ('Metadata-Version', 'Name', 'Version', 'Platform', + 'Supported-Platform', 'Summary', 'Description', + 'Keywords', 'Home-page', 'Author', 'Author-email', + 'Maintainer', 'Maintainer-email', 'License', + 'Classifier', 'Download-URL', 'Obsoletes-Dist', + 'Project-URL', 'Provides-Dist', 'Requires-Dist', + 'Requires-Python', 'Requires-External', 'Private-Version', + 'Obsoleted-By', 'Setup-Requires-Dist', 'Extension', + 'Provides-Extra') + +_426_MARKERS = ('Private-Version', 'Provides-Extra', 'Obsoleted-By', + 'Setup-Requires-Dist', 'Extension') + +_566_FIELDS = _426_FIELDS + ('Description-Content-Type',) + +_566_MARKERS = ('Description-Content-Type',) + +_ALL_FIELDS = set() +_ALL_FIELDS.update(_241_FIELDS) +_ALL_FIELDS.update(_314_FIELDS) +_ALL_FIELDS.update(_345_FIELDS) +_ALL_FIELDS.update(_426_FIELDS) +_ALL_FIELDS.update(_566_FIELDS) + +EXTRA_RE = re.compile(r'''extra\s*==\s*("([^"]+)"|'([^']+)')''') + + +def _version2fieldlist(version): + if version == '1.0': + return _241_FIELDS + elif version == '1.1': + return _314_FIELDS + elif version == '1.2': + return _345_FIELDS + elif version in ('1.3', '2.1'): + return _345_FIELDS + _566_FIELDS + elif version == '2.0': + return _426_FIELDS + raise MetadataUnrecognizedVersionError(version) + + +def _best_version(fields): + """Detect the best version depending on the fields used.""" + def _has_marker(keys, markers): + for marker in markers: + if marker in keys: + return True + return False + + keys = [] + for key, value in fields.items(): + if value in ([], 'UNKNOWN', None): + continue + keys.append(key) + + possible_versions = ['1.0', '1.1', '1.2', '1.3', '2.0', '2.1'] + + # first let's try to see if a field is not part of one of the version + for key in keys: + if key not in _241_FIELDS and '1.0' in possible_versions: + possible_versions.remove('1.0') + logger.debug('Removed 1.0 due to %s', key) + if key not in _314_FIELDS and '1.1' in possible_versions: + possible_versions.remove('1.1') + logger.debug('Removed 1.1 due to %s', key) + if key not in _345_FIELDS and '1.2' in possible_versions: + possible_versions.remove('1.2') + logger.debug('Removed 1.2 due to %s', key) + if key not in _566_FIELDS and '1.3' in possible_versions: + possible_versions.remove('1.3') + logger.debug('Removed 1.3 due to %s', key) + if key not in _566_FIELDS and '2.1' in possible_versions: + if key != 'Description': # In 2.1, description allowed after headers + possible_versions.remove('2.1') + logger.debug('Removed 2.1 due to %s', key) + if key not in _426_FIELDS and '2.0' in possible_versions: + possible_versions.remove('2.0') + logger.debug('Removed 2.0 due to %s', key) + + # possible_version contains qualified versions + if len(possible_versions) == 1: + return possible_versions[0] # found ! + elif len(possible_versions) == 0: + logger.debug('Out of options - unknown metadata set: %s', fields) + raise MetadataConflictError('Unknown metadata set') + + # let's see if one unique marker is found + is_1_1 = '1.1' in possible_versions and _has_marker(keys, _314_MARKERS) + is_1_2 = '1.2' in possible_versions and _has_marker(keys, _345_MARKERS) + is_2_1 = '2.1' in possible_versions and _has_marker(keys, _566_MARKERS) + is_2_0 = '2.0' in possible_versions and _has_marker(keys, _426_MARKERS) + if int(is_1_1) + int(is_1_2) + int(is_2_1) + int(is_2_0) > 1: + raise MetadataConflictError('You used incompatible 1.1/1.2/2.0/2.1 fields') + + # we have the choice, 1.0, or 1.2, or 2.0 + # - 1.0 has a broken Summary field but works with all tools + # - 1.1 is to avoid + # - 1.2 fixes Summary but has little adoption + # - 2.0 adds more features and is very new + if not is_1_1 and not is_1_2 and not is_2_1 and not is_2_0: + # we couldn't find any specific marker + if PKG_INFO_PREFERRED_VERSION in possible_versions: + return PKG_INFO_PREFERRED_VERSION + if is_1_1: + return '1.1' + if is_1_2: + return '1.2' + if is_2_1: + return '2.1' + + return '2.0' + +_ATTR2FIELD = { + 'metadata_version': 'Metadata-Version', + 'name': 'Name', + 'version': 'Version', + 'platform': 'Platform', + 'supported_platform': 'Supported-Platform', + 'summary': 'Summary', + 'description': 'Description', + 'keywords': 'Keywords', + 'home_page': 'Home-page', + 'author': 'Author', + 'author_email': 'Author-email', + 'maintainer': 'Maintainer', + 'maintainer_email': 'Maintainer-email', + 'license': 'License', + 'classifier': 'Classifier', + 'download_url': 'Download-URL', + 'obsoletes_dist': 'Obsoletes-Dist', + 'provides_dist': 'Provides-Dist', + 'requires_dist': 'Requires-Dist', + 'setup_requires_dist': 'Setup-Requires-Dist', + 'requires_python': 'Requires-Python', + 'requires_external': 'Requires-External', + 'requires': 'Requires', + 'provides': 'Provides', + 'obsoletes': 'Obsoletes', + 'project_url': 'Project-URL', + 'private_version': 'Private-Version', + 'obsoleted_by': 'Obsoleted-By', + 'extension': 'Extension', + 'provides_extra': 'Provides-Extra', +} + +_PREDICATE_FIELDS = ('Requires-Dist', 'Obsoletes-Dist', 'Provides-Dist') +_VERSIONS_FIELDS = ('Requires-Python',) +_VERSION_FIELDS = ('Version',) +_LISTFIELDS = ('Platform', 'Classifier', 'Obsoletes', + 'Requires', 'Provides', 'Obsoletes-Dist', + 'Provides-Dist', 'Requires-Dist', 'Requires-External', + 'Project-URL', 'Supported-Platform', 'Setup-Requires-Dist', + 'Provides-Extra', 'Extension') +_LISTTUPLEFIELDS = ('Project-URL',) + +_ELEMENTSFIELD = ('Keywords',) + +_UNICODEFIELDS = ('Author', 'Maintainer', 'Summary', 'Description') + +_MISSING = object() + +_FILESAFE = re.compile('[^A-Za-z0-9.]+') + + +def _get_name_and_version(name, version, for_filename=False): + """Return the distribution name with version. + + If for_filename is true, return a filename-escaped form.""" + if for_filename: + # For both name and version any runs of non-alphanumeric or '.' + # characters are replaced with a single '-'. Additionally any + # spaces in the version string become '.' + name = _FILESAFE.sub('-', name) + version = _FILESAFE.sub('-', version.replace(' ', '.')) + return '%s-%s' % (name, version) + + +class LegacyMetadata(object): + """The legacy metadata of a release. + + Supports versions 1.0, 1.1 and 1.2 (auto-detected). You can + instantiate the class with one of these arguments (or none): + - *path*, the path to a metadata file + - *fileobj* give a file-like object with metadata as content + - *mapping* is a dict-like object + - *scheme* is a version scheme name + """ + # TODO document the mapping API and UNKNOWN default key + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._fields = {} + self.requires_files = [] + self._dependencies = None + self.scheme = scheme + if path is not None: + self.read(path) + elif fileobj is not None: + self.read_file(fileobj) + elif mapping is not None: + self.update(mapping) + self.set_metadata_version() + + def set_metadata_version(self): + self._fields['Metadata-Version'] = _best_version(self._fields) + + def _write_field(self, fileobj, name, value): + fileobj.write('%s: %s\n' % (name, value)) + + def __getitem__(self, name): + return self.get(name) + + def __setitem__(self, name, value): + return self.set(name, value) + + def __delitem__(self, name): + field_name = self._convert_name(name) + try: + del self._fields[field_name] + except KeyError: + raise KeyError(name) + + def __contains__(self, name): + return (name in self._fields or + self._convert_name(name) in self._fields) + + def _convert_name(self, name): + if name in _ALL_FIELDS: + return name + name = name.replace('-', '_').lower() + return _ATTR2FIELD.get(name, name) + + def _default_value(self, name): + if name in _LISTFIELDS or name in _ELEMENTSFIELD: + return [] + return 'UNKNOWN' + + def _remove_line_prefix(self, value): + if self.metadata_version in ('1.0', '1.1'): + return _LINE_PREFIX_PRE_1_2.sub('\n', value) + else: + return _LINE_PREFIX_1_2.sub('\n', value) + + def __getattr__(self, name): + if name in _ATTR2FIELD: + return self[name] + raise AttributeError(name) + + # + # Public API + # + +# dependencies = property(_get_dependencies, _set_dependencies) + + def get_fullname(self, filesafe=False): + """Return the distribution name with version. + + If filesafe is true, return a filename-escaped form.""" + return _get_name_and_version(self['Name'], self['Version'], filesafe) + + def is_field(self, name): + """return True if name is a valid metadata key""" + name = self._convert_name(name) + return name in _ALL_FIELDS + + def is_multi_field(self, name): + name = self._convert_name(name) + return name in _LISTFIELDS + + def read(self, filepath): + """Read the metadata values from a file path.""" + fp = codecs.open(filepath, 'r', encoding='utf-8') + try: + self.read_file(fp) + finally: + fp.close() + + def read_file(self, fileob): + """Read the metadata values from a file object.""" + msg = message_from_file(fileob) + self._fields['Metadata-Version'] = msg['metadata-version'] + + # When reading, get all the fields we can + for field in _ALL_FIELDS: + if field not in msg: + continue + if field in _LISTFIELDS: + # we can have multiple lines + values = msg.get_all(field) + if field in _LISTTUPLEFIELDS and values is not None: + values = [tuple(value.split(',')) for value in values] + self.set(field, values) + else: + # single line + value = msg[field] + if value is not None and value != 'UNKNOWN': + self.set(field, value) + logger.debug('Attempting to set metadata for %s', self) + self.set_metadata_version() + + def write(self, filepath, skip_unknown=False): + """Write the metadata fields to filepath.""" + fp = codecs.open(filepath, 'w', encoding='utf-8') + try: + self.write_file(fp, skip_unknown) + finally: + fp.close() + + def write_file(self, fileobject, skip_unknown=False): + """Write the PKG-INFO format data to a file object.""" + self.set_metadata_version() + + for field in _version2fieldlist(self['Metadata-Version']): + values = self.get(field) + if skip_unknown and values in ('UNKNOWN', [], ['UNKNOWN']): + continue + if field in _ELEMENTSFIELD: + self._write_field(fileobject, field, ','.join(values)) + continue + if field not in _LISTFIELDS: + if field == 'Description': + if self.metadata_version in ('1.0', '1.1'): + values = values.replace('\n', '\n ') + else: + values = values.replace('\n', '\n |') + values = [values] + + if field in _LISTTUPLEFIELDS: + values = [','.join(value) for value in values] + + for value in values: + self._write_field(fileobject, field, value) + + def update(self, other=None, **kwargs): + """Set metadata values from the given iterable `other` and kwargs. + + Behavior is like `dict.update`: If `other` has a ``keys`` method, + they are looped over and ``self[key]`` is assigned ``other[key]``. + Else, ``other`` is an iterable of ``(key, value)`` iterables. + + Keys that don't match a metadata field or that have an empty value are + dropped. + """ + def _set(key, value): + if key in _ATTR2FIELD and value: + self.set(self._convert_name(key), value) + + if not other: + # other is None or empty container + pass + elif hasattr(other, 'keys'): + for k in other.keys(): + _set(k, other[k]) + else: + for k, v in other: + _set(k, v) + + if kwargs: + for k, v in kwargs.items(): + _set(k, v) + + def set(self, name, value): + """Control then set a metadata field.""" + name = self._convert_name(name) + + if ((name in _ELEMENTSFIELD or name == 'Platform') and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [v.strip() for v in value.split(',')] + else: + value = [] + elif (name in _LISTFIELDS and + not isinstance(value, (list, tuple))): + if isinstance(value, string_types): + value = [value] + else: + value = [] + + if logger.isEnabledFor(logging.WARNING): + project_name = self['Name'] + + scheme = get_scheme(self.scheme) + if name in _PREDICATE_FIELDS and value is not None: + for v in value: + # check that the values are valid + if not scheme.is_valid_matcher(v.split(';')[0]): + logger.warning( + "'%s': '%s' is not valid (field '%s')", + project_name, v, name) + # FIXME this rejects UNKNOWN, is that right? + elif name in _VERSIONS_FIELDS and value is not None: + if not scheme.is_valid_constraint_list(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + elif name in _VERSION_FIELDS and value is not None: + if not scheme.is_valid_version(value): + logger.warning("'%s': '%s' is not a valid version (field '%s')", + project_name, value, name) + + if name in _UNICODEFIELDS: + if name == 'Description': + value = self._remove_line_prefix(value) + + self._fields[name] = value + + def get(self, name, default=_MISSING): + """Get a metadata field.""" + name = self._convert_name(name) + if name not in self._fields: + if default is _MISSING: + default = self._default_value(name) + return default + if name in _UNICODEFIELDS: + value = self._fields[name] + return value + elif name in _LISTFIELDS: + value = self._fields[name] + if value is None: + return [] + res = [] + for val in value: + if name not in _LISTTUPLEFIELDS: + res.append(val) + else: + # That's for Project-URL + res.append((val[0], val[1])) + return res + + elif name in _ELEMENTSFIELD: + value = self._fields[name] + if isinstance(value, string_types): + return value.split(',') + return self._fields[name] + + def check(self, strict=False): + """Check if the metadata is compliant. If strict is True then raise if + no Name or Version are provided""" + self.set_metadata_version() + + # XXX should check the versions (if the file was loaded) + missing, warnings = [], [] + + for attr in ('Name', 'Version'): # required by PEP 345 + if attr not in self: + missing.append(attr) + + if strict and missing != []: + msg = 'missing required metadata: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + + for attr in ('Home-page', 'Author'): + if attr not in self: + missing.append(attr) + + # checking metadata 1.2 (XXX needs to check 1.1, 1.0) + if self['Metadata-Version'] != '1.2': + return missing, warnings + + scheme = get_scheme(self.scheme) + + def are_valid_constraints(value): + for v in value: + if not scheme.is_valid_matcher(v.split(';')[0]): + return False + return True + + for fields, controller in ((_PREDICATE_FIELDS, are_valid_constraints), + (_VERSIONS_FIELDS, + scheme.is_valid_constraint_list), + (_VERSION_FIELDS, + scheme.is_valid_version)): + for field in fields: + value = self.get(field, None) + if value is not None and not controller(value): + warnings.append("Wrong value for '%s': %s" % (field, value)) + + return missing, warnings + + def todict(self, skip_missing=False): + """Return fields as a dict. + + Field names will be converted to use the underscore-lowercase style + instead of hyphen-mixed case (i.e. home_page instead of Home-page). + """ + self.set_metadata_version() + + mapping_1_0 = ( + ('metadata_version', 'Metadata-Version'), + ('name', 'Name'), + ('version', 'Version'), + ('summary', 'Summary'), + ('home_page', 'Home-page'), + ('author', 'Author'), + ('author_email', 'Author-email'), + ('license', 'License'), + ('description', 'Description'), + ('keywords', 'Keywords'), + ('platform', 'Platform'), + ('classifiers', 'Classifier'), + ('download_url', 'Download-URL'), + ) + + data = {} + for key, field_name in mapping_1_0: + if not skip_missing or field_name in self._fields: + data[key] = self[field_name] + + if self['Metadata-Version'] == '1.2': + mapping_1_2 = ( + ('requires_dist', 'Requires-Dist'), + ('requires_python', 'Requires-Python'), + ('requires_external', 'Requires-External'), + ('provides_dist', 'Provides-Dist'), + ('obsoletes_dist', 'Obsoletes-Dist'), + ('project_url', 'Project-URL'), + ('maintainer', 'Maintainer'), + ('maintainer_email', 'Maintainer-email'), + ) + for key, field_name in mapping_1_2: + if not skip_missing or field_name in self._fields: + if key != 'project_url': + data[key] = self[field_name] + else: + data[key] = [','.join(u) for u in self[field_name]] + + elif self['Metadata-Version'] == '1.1': + mapping_1_1 = ( + ('provides', 'Provides'), + ('requires', 'Requires'), + ('obsoletes', 'Obsoletes'), + ) + for key, field_name in mapping_1_1: + if not skip_missing or field_name in self._fields: + data[key] = self[field_name] + + return data + + def add_requirements(self, requirements): + if self['Metadata-Version'] == '1.1': + # we can't have 1.1 metadata *and* Setuptools requires + for field in ('Obsoletes', 'Requires', 'Provides'): + if field in self: + del self[field] + self['Requires-Dist'] += requirements + + # Mapping API + # TODO could add iter* variants + + def keys(self): + return list(_version2fieldlist(self['Metadata-Version'])) + + def __iter__(self): + for key in self.keys(): + yield key + + def values(self): + return [self[key] for key in self.keys()] + + def items(self): + return [(key, self[key]) for key in self.keys()] + + def __repr__(self): + return '<%s %s %s>' % (self.__class__.__name__, self.name, + self.version) + + +METADATA_FILENAME = 'pydist.json' +WHEEL_METADATA_FILENAME = 'metadata.json' + + +class Metadata(object): + """ + The metadata of a release. This implementation uses 2.0 (JSON) + metadata where possible. If not possible, it wraps a LegacyMetadata + instance which handles the key-value metadata format. + """ + + METADATA_VERSION_MATCHER = re.compile(r'^\d+(\.\d+)*$') + + NAME_MATCHER = re.compile('^[0-9A-Z]([0-9A-Z_.-]*[0-9A-Z])?$', re.I) + + VERSION_MATCHER = PEP440_VERSION_RE + + SUMMARY_MATCHER = re.compile('.{1,2047}') + + METADATA_VERSION = '2.0' + + GENERATOR = 'distlib (%s)' % __version__ + + MANDATORY_KEYS = { + 'name': (), + 'version': (), + 'summary': ('legacy',), + } + + INDEX_KEYS = ('name version license summary description author ' + 'author_email keywords platform home_page classifiers ' + 'download_url') + + DEPENDENCY_KEYS = ('extras run_requires test_requires build_requires ' + 'dev_requires provides meta_requires obsoleted_by ' + 'supports_environments') + + SYNTAX_VALIDATORS = { + 'metadata_version': (METADATA_VERSION_MATCHER, ()), + 'name': (NAME_MATCHER, ('legacy',)), + 'version': (VERSION_MATCHER, ('legacy',)), + 'summary': (SUMMARY_MATCHER, ('legacy',)), + } + + __slots__ = ('_legacy', '_data', 'scheme') + + def __init__(self, path=None, fileobj=None, mapping=None, + scheme='default'): + if [path, fileobj, mapping].count(None) < 2: + raise TypeError('path, fileobj and mapping are exclusive') + self._legacy = None + self._data = None + self.scheme = scheme + #import pdb; pdb.set_trace() + if mapping is not None: + try: + self._validate_mapping(mapping, scheme) + self._data = mapping + except MetadataUnrecognizedVersionError: + self._legacy = LegacyMetadata(mapping=mapping, scheme=scheme) + self.validate() + else: + data = None + if path: + with open(path, 'rb') as f: + data = f.read() + elif fileobj: + data = fileobj.read() + if data is None: + # Initialised with no args - to be added + self._data = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + else: + if not isinstance(data, text_type): + data = data.decode('utf-8') + try: + self._data = json.loads(data) + self._validate_mapping(self._data, scheme) + except ValueError: + # Note: MetadataUnrecognizedVersionError does not + # inherit from ValueError (it's a DistlibException, + # which should not inherit from ValueError). + # The ValueError comes from the json.load - if that + # succeeds and we get a validation error, we want + # that to propagate + self._legacy = LegacyMetadata(fileobj=StringIO(data), + scheme=scheme) + self.validate() + + common_keys = set(('name', 'version', 'license', 'keywords', 'summary')) + + none_list = (None, list) + none_dict = (None, dict) + + mapped_keys = { + 'run_requires': ('Requires-Dist', list), + 'build_requires': ('Setup-Requires-Dist', list), + 'dev_requires': none_list, + 'test_requires': none_list, + 'meta_requires': none_list, + 'extras': ('Provides-Extra', list), + 'modules': none_list, + 'namespaces': none_list, + 'exports': none_dict, + 'commands': none_dict, + 'classifiers': ('Classifier', list), + 'source_url': ('Download-URL', None), + 'metadata_version': ('Metadata-Version', None), + } + + del none_list, none_dict + + def __getattribute__(self, key): + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, maker = mapped[key] + if self._legacy: + if lk is None: + result = None if maker is None else maker() + else: + result = self._legacy.get(lk) + else: + value = None if maker is None else maker() + if key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + result = self._data.get(key, value) + else: + # special cases for PEP 459 + sentinel = object() + result = sentinel + d = self._data.get('extensions') + if d: + if key == 'commands': + result = d.get('python.commands', value) + elif key == 'classifiers': + d = d.get('python.details') + if d: + result = d.get(key, value) + else: + d = d.get('python.exports') + if not d: + d = self._data.get('python.exports') + if d: + result = d.get(key, value) + if result is sentinel: + result = value + elif key not in common: + result = object.__getattribute__(self, key) + elif self._legacy: + result = self._legacy.get(key) + else: + result = self._data.get(key) + return result + + def _validate_value(self, key, value, scheme=None): + if key in self.SYNTAX_VALIDATORS: + pattern, exclusions = self.SYNTAX_VALIDATORS[key] + if (scheme or self.scheme) not in exclusions: + m = pattern.match(value) + if not m: + raise MetadataInvalidError("'%s' is an invalid value for " + "the '%s' property" % (value, + key)) + + def __setattr__(self, key, value): + self._validate_value(key, value) + common = object.__getattribute__(self, 'common_keys') + mapped = object.__getattribute__(self, 'mapped_keys') + if key in mapped: + lk, _ = mapped[key] + if self._legacy: + if lk is None: + raise NotImplementedError + self._legacy[lk] = value + elif key not in ('commands', 'exports', 'modules', 'namespaces', + 'classifiers'): + self._data[key] = value + else: + # special cases for PEP 459 + d = self._data.setdefault('extensions', {}) + if key == 'commands': + d['python.commands'] = value + elif key == 'classifiers': + d = d.setdefault('python.details', {}) + d[key] = value + else: + d = d.setdefault('python.exports', {}) + d[key] = value + elif key not in common: + object.__setattr__(self, key, value) + else: + if key == 'keywords': + if isinstance(value, string_types): + value = value.strip() + if value: + value = value.split() + else: + value = [] + if self._legacy: + self._legacy[key] = value + else: + self._data[key] = value + + @property + def name_and_version(self): + return _get_name_and_version(self.name, self.version, True) + + @property + def provides(self): + if self._legacy: + result = self._legacy['Provides-Dist'] + else: + result = self._data.setdefault('provides', []) + s = '%s (%s)' % (self.name, self.version) + if s not in result: + result.append(s) + return result + + @provides.setter + def provides(self, value): + if self._legacy: + self._legacy['Provides-Dist'] = value + else: + self._data['provides'] = value + + def get_requirements(self, reqts, extras=None, env=None): + """ + Base method to get dependencies, given a set of extras + to satisfy and an optional environment context. + :param reqts: A list of sometimes-wanted dependencies, + perhaps dependent on extras and environment. + :param extras: A list of optional components being requested. + :param env: An optional environment for marker evaluation. + """ + if self._legacy: + result = reqts + else: + result = [] + extras = get_extras(extras or [], self.extras) + for d in reqts: + if 'extra' not in d and 'environment' not in d: + # unconditional + include = True + else: + if 'extra' not in d: + # Not extra-dependent - only environment-dependent + include = True + else: + include = d.get('extra') in extras + if include: + # Not excluded because of extras, check environment + marker = d.get('environment') + if marker: + include = interpret(marker, env) + if include: + result.extend(d['requires']) + for key in ('build', 'dev', 'test'): + e = ':%s:' % key + if e in extras: + extras.remove(e) + # A recursive call, but it should terminate since 'test' + # has been removed from the extras + reqts = self._data.get('%s_requires' % key, []) + result.extend(self.get_requirements(reqts, extras=extras, + env=env)) + return result + + @property + def dictionary(self): + if self._legacy: + return self._from_legacy() + return self._data + + @property + def dependencies(self): + if self._legacy: + raise NotImplementedError + else: + return extract_by_key(self._data, self.DEPENDENCY_KEYS) + + @dependencies.setter + def dependencies(self, value): + if self._legacy: + raise NotImplementedError + else: + self._data.update(value) + + def _validate_mapping(self, mapping, scheme): + if mapping.get('metadata_version') != self.METADATA_VERSION: + raise MetadataUnrecognizedVersionError() + missing = [] + for key, exclusions in self.MANDATORY_KEYS.items(): + if key not in mapping: + if scheme not in exclusions: + missing.append(key) + if missing: + msg = 'Missing metadata items: %s' % ', '.join(missing) + raise MetadataMissingError(msg) + for k, v in mapping.items(): + self._validate_value(k, v, scheme) + + def validate(self): + if self._legacy: + missing, warnings = self._legacy.check(True) + if missing or warnings: + logger.warning('Metadata: missing: %s, warnings: %s', + missing, warnings) + else: + self._validate_mapping(self._data, self.scheme) + + def todict(self): + if self._legacy: + return self._legacy.todict(True) + else: + result = extract_by_key(self._data, self.INDEX_KEYS) + return result + + def _from_legacy(self): + assert self._legacy and not self._data + result = { + 'metadata_version': self.METADATA_VERSION, + 'generator': self.GENERATOR, + } + lmd = self._legacy.todict(True) # skip missing ones + for k in ('name', 'version', 'license', 'summary', 'description', + 'classifier'): + if k in lmd: + if k == 'classifier': + nk = 'classifiers' + else: + nk = k + result[nk] = lmd[k] + kw = lmd.get('Keywords', []) + if kw == ['']: + kw = [] + result['keywords'] = kw + keys = (('requires_dist', 'run_requires'), + ('setup_requires_dist', 'build_requires')) + for ok, nk in keys: + if ok in lmd and lmd[ok]: + result[nk] = [{'requires': lmd[ok]}] + result['provides'] = self.provides + author = {} + maintainer = {} + return result + + LEGACY_MAPPING = { + 'name': 'Name', + 'version': 'Version', + 'license': 'License', + 'summary': 'Summary', + 'description': 'Description', + 'classifiers': 'Classifier', + } + + def _to_legacy(self): + def process_entries(entries): + reqts = set() + for e in entries: + extra = e.get('extra') + env = e.get('environment') + rlist = e['requires'] + for r in rlist: + if not env and not extra: + reqts.add(r) + else: + marker = '' + if extra: + marker = 'extra == "%s"' % extra + if env: + if marker: + marker = '(%s) and %s' % (env, marker) + else: + marker = env + reqts.add(';'.join((r, marker))) + return reqts + + assert self._data and not self._legacy + result = LegacyMetadata() + nmd = self._data + for nk, ok in self.LEGACY_MAPPING.items(): + if nk in nmd: + result[ok] = nmd[nk] + r1 = process_entries(self.run_requires + self.meta_requires) + r2 = process_entries(self.build_requires + self.dev_requires) + if self.extras: + result['Provides-Extra'] = sorted(self.extras) + result['Requires-Dist'] = sorted(r1) + result['Setup-Requires-Dist'] = sorted(r2) + # TODO: other fields such as contacts + return result + + def write(self, path=None, fileobj=None, legacy=False, skip_unknown=True): + if [path, fileobj].count(None) != 1: + raise ValueError('Exactly one of path and fileobj is needed') + self.validate() + if legacy: + if self._legacy: + legacy_md = self._legacy + else: + legacy_md = self._to_legacy() + if path: + legacy_md.write(path, skip_unknown=skip_unknown) + else: + legacy_md.write_file(fileobj, skip_unknown=skip_unknown) + else: + if self._legacy: + d = self._from_legacy() + else: + d = self._data + if fileobj: + json.dump(d, fileobj, ensure_ascii=True, indent=2, + sort_keys=True) + else: + with codecs.open(path, 'w', 'utf-8') as f: + json.dump(d, f, ensure_ascii=True, indent=2, + sort_keys=True) + + def add_requirements(self, requirements): + if self._legacy: + self._legacy.add_requirements(requirements) + else: + run_requires = self._data.setdefault('run_requires', []) + always = None + for entry in run_requires: + if 'environment' not in entry and 'extra' not in entry: + always = entry + break + if always is None: + always = { 'requires': requirements } + run_requires.insert(0, always) + else: + rset = set(always['requires']) | set(requirements) + always['requires'] = sorted(rset) + + def __repr__(self): + name = self.name or '(no name)' + version = self.version or 'no version' + return '<%s %s %s (%s)>' % (self.__class__.__name__, + self.metadata_version, name, version) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py new file mode 100644 index 0000000..1884016 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/resources.py @@ -0,0 +1,355 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import bisect +import io +import logging +import os +import pkgutil +import shutil +import sys +import types +import zipimport + +from . import DistlibException +from .util import cached_property, get_cache_base, path_to_cache_dir, Cache + +logger = logging.getLogger(__name__) + + +cache = None # created when needed + + +class ResourceCache(Cache): + def __init__(self, base=None): + if base is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('resource-cache')) + super(ResourceCache, self).__init__(base) + + def is_stale(self, resource, path): + """ + Is the cache stale for the given resource? + + :param resource: The :class:`Resource` being cached. + :param path: The path of the resource in the cache. + :return: True if the cache is stale. + """ + # Cache invalidation is a hard problem :-) + return True + + def get(self, resource): + """ + Get a resource into the cache, + + :param resource: A :class:`Resource` instance. + :return: The pathname of the resource in the cache. + """ + prefix, path = resource.finder.get_cache_info(resource) + if prefix is None: + result = path + else: + result = os.path.join(self.base, self.prefix_to_dir(prefix), path) + dirname = os.path.dirname(result) + if not os.path.isdir(dirname): + os.makedirs(dirname) + if not os.path.exists(result): + stale = True + else: + stale = self.is_stale(resource, path) + if stale: + # write the bytes of the resource to the cache location + with open(result, 'wb') as f: + f.write(resource.bytes) + return result + + +class ResourceBase(object): + def __init__(self, finder, name): + self.finder = finder + self.name = name + + +class Resource(ResourceBase): + """ + A class representing an in-package resource, such as a data file. This is + not normally instantiated by user code, but rather by a + :class:`ResourceFinder` which manages the resource. + """ + is_container = False # Backwards compatibility + + def as_stream(self): + """ + Get the resource as a stream. + + This is not a property to make it obvious that it returns a new stream + each time. + """ + return self.finder.get_stream(self) + + @cached_property + def file_path(self): + global cache + if cache is None: + cache = ResourceCache() + return cache.get(self) + + @cached_property + def bytes(self): + return self.finder.get_bytes(self) + + @cached_property + def size(self): + return self.finder.get_size(self) + + +class ResourceContainer(ResourceBase): + is_container = True # Backwards compatibility + + @cached_property + def resources(self): + return self.finder.get_resources(self) + + +class ResourceFinder(object): + """ + Resource finder for file system resources. + """ + + if sys.platform.startswith('java'): + skipped_extensions = ('.pyc', '.pyo', '.class') + else: + skipped_extensions = ('.pyc', '.pyo') + + def __init__(self, module): + self.module = module + self.loader = getattr(module, '__loader__', None) + self.base = os.path.dirname(getattr(module, '__file__', '')) + + def _adjust_path(self, path): + return os.path.realpath(path) + + def _make_path(self, resource_name): + # Issue #50: need to preserve type of path on Python 2.x + # like os.path._get_sep + if isinstance(resource_name, bytes): # should only happen on 2.x + sep = b'/' + else: + sep = '/' + parts = resource_name.split(sep) + parts.insert(0, self.base) + result = os.path.join(*parts) + return self._adjust_path(result) + + def _find(self, path): + return os.path.exists(path) + + def get_cache_info(self, resource): + return None, resource.path + + def find(self, resource_name): + path = self._make_path(resource_name) + if not self._find(path): + result = None + else: + if self._is_directory(path): + result = ResourceContainer(self, resource_name) + else: + result = Resource(self, resource_name) + result.path = path + return result + + def get_stream(self, resource): + return open(resource.path, 'rb') + + def get_bytes(self, resource): + with open(resource.path, 'rb') as f: + return f.read() + + def get_size(self, resource): + return os.path.getsize(resource.path) + + def get_resources(self, resource): + def allowed(f): + return (f != '__pycache__' and not + f.endswith(self.skipped_extensions)) + return set([f for f in os.listdir(resource.path) if allowed(f)]) + + def is_container(self, resource): + return self._is_directory(resource.path) + + _is_directory = staticmethod(os.path.isdir) + + def iterator(self, resource_name): + resource = self.find(resource_name) + if resource is not None: + todo = [resource] + while todo: + resource = todo.pop(0) + yield resource + if resource.is_container: + rname = resource.name + for name in resource.resources: + if not rname: + new_name = name + else: + new_name = '/'.join([rname, name]) + child = self.find(new_name) + if child.is_container: + todo.append(child) + else: + yield child + + +class ZipResourceFinder(ResourceFinder): + """ + Resource finder for resources in .zip files. + """ + def __init__(self, module): + super(ZipResourceFinder, self).__init__(module) + archive = self.loader.archive + self.prefix_len = 1 + len(archive) + # PyPy doesn't have a _files attr on zipimporter, and you can't set one + if hasattr(self.loader, '_files'): + self._files = self.loader._files + else: + self._files = zipimport._zip_directory_cache[archive] + self.index = sorted(self._files) + + def _adjust_path(self, path): + return path + + def _find(self, path): + path = path[self.prefix_len:] + if path in self._files: + result = True + else: + if path and path[-1] != os.sep: + path = path + os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + if not result: + logger.debug('_find failed: %r %r', path, self.loader.prefix) + else: + logger.debug('_find worked: %r %r', path, self.loader.prefix) + return result + + def get_cache_info(self, resource): + prefix = self.loader.archive + path = resource.path[1 + len(prefix):] + return prefix, path + + def get_bytes(self, resource): + return self.loader.get_data(resource.path) + + def get_stream(self, resource): + return io.BytesIO(self.get_bytes(resource)) + + def get_size(self, resource): + path = resource.path[self.prefix_len:] + return self._files[path][3] + + def get_resources(self, resource): + path = resource.path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + plen = len(path) + result = set() + i = bisect.bisect(self.index, path) + while i < len(self.index): + if not self.index[i].startswith(path): + break + s = self.index[i][plen:] + result.add(s.split(os.sep, 1)[0]) # only immediate children + i += 1 + return result + + def _is_directory(self, path): + path = path[self.prefix_len:] + if path and path[-1] != os.sep: + path += os.sep + i = bisect.bisect(self.index, path) + try: + result = self.index[i].startswith(path) + except IndexError: + result = False + return result + +_finder_registry = { + type(None): ResourceFinder, + zipimport.zipimporter: ZipResourceFinder +} + +try: + # In Python 3.6, _frozen_importlib -> _frozen_importlib_external + try: + import _frozen_importlib_external as _fi + except ImportError: + import _frozen_importlib as _fi + _finder_registry[_fi.SourceFileLoader] = ResourceFinder + _finder_registry[_fi.FileFinder] = ResourceFinder + del _fi +except (ImportError, AttributeError): + pass + + +def register_finder(loader, finder_maker): + _finder_registry[type(loader)] = finder_maker + +_finder_cache = {} + + +def finder(package): + """ + Return a resource finder for a package. + :param package: The name of the package. + :return: A :class:`ResourceFinder` instance for the package. + """ + if package in _finder_cache: + result = _finder_cache[package] + else: + if package not in sys.modules: + __import__(package) + module = sys.modules[package] + path = getattr(module, '__path__', None) + if path is None: + raise DistlibException('You cannot get a finder for a module, ' + 'only for a package') + loader = getattr(module, '__loader__', None) + finder_maker = _finder_registry.get(type(loader)) + if finder_maker is None: + raise DistlibException('Unable to locate finder for %r' % package) + result = finder_maker(module) + _finder_cache[package] = result + return result + + +_dummy_module = types.ModuleType(str('__dummy__')) + + +def finder_for_path(path): + """ + Return a resource finder for a path, which should represent a container. + + :param path: The path. + :return: A :class:`ResourceFinder` instance for the path. + """ + result = None + # calls any path hooks, gets importer into cache + pkgutil.get_importer(path) + loader = sys.path_importer_cache.get(path) + finder = _finder_registry.get(type(loader)) + if finder: + module = _dummy_module + module.__file__ = os.path.join(path, '') + module.__loader__ = loader + result = finder(module) + return result diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py new file mode 100644 index 0000000..0b7c3d0 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/scripts.py @@ -0,0 +1,415 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2015 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from io import BytesIO +import logging +import os +import re +import struct +import sys + +from .compat import sysconfig, detect_encoding, ZipFile +from .resources import finder +from .util import (FileOperator, get_export_entry, convert_path, + get_executable, in_venv) + +logger = logging.getLogger(__name__) + +_DEFAULT_MANIFEST = ''' +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="%s" + type="win32"/> + + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly>'''.strip() + +# check if Python is called on the first line with this expression +FIRST_LINE_RE = re.compile(b'^#!.*pythonw?[0-9.]*([ \t].*)?$') +SCRIPT_TEMPLATE = r'''# -*- coding: utf-8 -*- +if __name__ == '__main__': + import sys, re + + def _resolve(module, func): + __import__(module) + mod = sys.modules[module] + parts = func.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + try: + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + + func = _resolve('%(module)s', '%(func)s') + rc = func() # None interpreted as 0 + except Exception as e: # only supporting Python >= 2.6 + sys.stderr.write('%%s\n' %% e) + rc = 1 + sys.exit(rc) +''' + + +def _enquote_executable(executable): + if ' ' in executable: + # make sure we quote only the executable in case of env + # for example /usr/bin/env "/dir with spaces/bin/jython" + # instead of "/usr/bin/env /dir with spaces/bin/jython" + # otherwise whole + if executable.startswith('/usr/bin/env '): + env, _executable = executable.split(' ', 1) + if ' ' in _executable and not _executable.startswith('"'): + executable = '%s "%s"' % (env, _executable) + else: + if not executable.startswith('"'): + executable = '"%s"' % executable + return executable + + +class ScriptMaker(object): + """ + A class to copy or create scripts from source scripts or callable + specifications. + """ + script_template = SCRIPT_TEMPLATE + + executable = None # for shebangs + + def __init__(self, source_dir, target_dir, add_launchers=True, + dry_run=False, fileop=None): + self.source_dir = source_dir + self.target_dir = target_dir + self.add_launchers = add_launchers + self.force = False + self.clobber = False + # It only makes sense to set mode bits on POSIX. + self.set_mode = (os.name == 'posix') or (os.name == 'java' and + os._name == 'posix') + self.variants = set(('', 'X.Y')) + self._fileop = fileop or FileOperator(dry_run) + + self._is_nt = os.name == 'nt' or ( + os.name == 'java' and os._name == 'nt') + + def _get_alternate_executable(self, executable, options): + if options.get('gui', False) and self._is_nt: # pragma: no cover + dn, fn = os.path.split(executable) + fn = fn.replace('python', 'pythonw') + executable = os.path.join(dn, fn) + return executable + + if sys.platform.startswith('java'): # pragma: no cover + def _is_shell(self, executable): + """ + Determine if the specified executable is a script + (contains a #! line) + """ + try: + with open(executable) as fp: + return fp.read(2) == '#!' + except (OSError, IOError): + logger.warning('Failed to open %s', executable) + return False + + def _fix_jython_executable(self, executable): + if self._is_shell(executable): + # Workaround for Jython is not needed on Linux systems. + import java + + if java.lang.System.getProperty('os.name') == 'Linux': + return executable + elif executable.lower().endswith('jython.exe'): + # Use wrapper exe for Jython on Windows + return executable + return '/usr/bin/env %s' % executable + + def _build_shebang(self, executable, post_interp): + """ + Build a shebang line. In the simple case (on Windows, or a shebang line + which is not too long or contains spaces) use a simple formulation for + the shebang. Otherwise, use /bin/sh as the executable, with a contrived + shebang which allows the script to run either under Python or sh, using + suitable quoting. Thanks to Harald Nordgren for his input. + + See also: http://www.in-ulm.de/~mascheck/various/shebang/#length + https://hg.mozilla.org/mozilla-central/file/tip/mach + """ + if os.name != 'posix': + simple_shebang = True + else: + # Add 3 for '#!' prefix and newline suffix. + shebang_length = len(executable) + len(post_interp) + 3 + if sys.platform == 'darwin': + max_shebang_length = 512 + else: + max_shebang_length = 127 + simple_shebang = ((b' ' not in executable) and + (shebang_length <= max_shebang_length)) + + if simple_shebang: + result = b'#!' + executable + post_interp + b'\n' + else: + result = b'#!/bin/sh\n' + result += b"'''exec' " + executable + post_interp + b' "$0" "$@"\n' + result += b"' '''" + return result + + def _get_shebang(self, encoding, post_interp=b'', options=None): + enquote = True + if self.executable: + executable = self.executable + enquote = False # assume this will be taken care of + elif not sysconfig.is_python_build(): + executable = get_executable() + elif in_venv(): # pragma: no cover + executable = os.path.join(sysconfig.get_path('scripts'), + 'python%s' % sysconfig.get_config_var('EXE')) + else: # pragma: no cover + executable = os.path.join( + sysconfig.get_config_var('BINDIR'), + 'python%s%s' % (sysconfig.get_config_var('VERSION'), + sysconfig.get_config_var('EXE'))) + if options: + executable = self._get_alternate_executable(executable, options) + + if sys.platform.startswith('java'): # pragma: no cover + executable = self._fix_jython_executable(executable) + # Normalise case for Windows + executable = os.path.normcase(executable) + # If the user didn't specify an executable, it may be necessary to + # cater for executable paths with spaces (not uncommon on Windows) + if enquote: + executable = _enquote_executable(executable) + # Issue #51: don't use fsencode, since we later try to + # check that the shebang is decodable using utf-8. + executable = executable.encode('utf-8') + # in case of IronPython, play safe and enable frames support + if (sys.platform == 'cli' and '-X:Frames' not in post_interp + and '-X:FullFrames' not in post_interp): # pragma: no cover + post_interp += b' -X:Frames' + shebang = self._build_shebang(executable, post_interp) + # Python parser starts to read a script using UTF-8 until + # it gets a #coding:xxx cookie. The shebang has to be the + # first line of a file, the #coding:xxx cookie cannot be + # written before. So the shebang has to be decodable from + # UTF-8. + try: + shebang.decode('utf-8') + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable from utf-8' % shebang) + # If the script is encoded to a custom encoding (use a + # #coding:xxx cookie), the shebang has to be decodable from + # the script encoding too. + if encoding != 'utf-8': + try: + shebang.decode(encoding) + except UnicodeDecodeError: # pragma: no cover + raise ValueError( + 'The shebang (%r) is not decodable ' + 'from the script encoding (%r)' % (shebang, encoding)) + return shebang + + def _get_script_text(self, entry): + return self.script_template % dict(module=entry.prefix, + func=entry.suffix) + + manifest = _DEFAULT_MANIFEST + + def get_manifest(self, exename): + base = os.path.basename(exename) + return self.manifest % base + + def _write_script(self, names, shebang, script_bytes, filenames, ext): + use_launcher = self.add_launchers and self._is_nt + linesep = os.linesep.encode('utf-8') + if not use_launcher: + script_bytes = shebang + linesep + script_bytes + else: # pragma: no cover + if ext == 'py': + launcher = self._get_launcher('t') + else: + launcher = self._get_launcher('w') + stream = BytesIO() + with ZipFile(stream, 'w') as zf: + zf.writestr('__main__.py', script_bytes) + zip_data = stream.getvalue() + script_bytes = launcher + shebang + linesep + zip_data + for name in names: + outname = os.path.join(self.target_dir, name) + if use_launcher: # pragma: no cover + n, e = os.path.splitext(outname) + if e.startswith('.py'): + outname = n + outname = '%s.exe' % outname + try: + self._fileop.write_binary_file(outname, script_bytes) + except Exception: + # Failed writing an executable - it might be in use. + logger.warning('Failed to write executable - trying to ' + 'use .deleteme logic') + dfname = '%s.deleteme' % outname + if os.path.exists(dfname): + os.remove(dfname) # Not allowed to fail here + os.rename(outname, dfname) # nor here + self._fileop.write_binary_file(outname, script_bytes) + logger.debug('Able to replace executable using ' + '.deleteme logic') + try: + os.remove(dfname) + except Exception: + pass # still in use - ignore error + else: + if self._is_nt and not outname.endswith('.' + ext): # pragma: no cover + outname = '%s.%s' % (outname, ext) + if os.path.exists(outname) and not self.clobber: + logger.warning('Skipping existing file %s', outname) + continue + self._fileop.write_binary_file(outname, script_bytes) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + + def _make_script(self, entry, filenames, options=None): + post_interp = b'' + if options: + args = options.get('interpreter_args', []) + if args: + args = ' %s' % ' '.join(args) + post_interp = args.encode('utf-8') + shebang = self._get_shebang('utf-8', post_interp, options=options) + script = self._get_script_text(entry).encode('utf-8') + name = entry.name + scriptnames = set() + if '' in self.variants: + scriptnames.add(name) + if 'X' in self.variants: + scriptnames.add('%s%s' % (name, sys.version[0])) + if 'X.Y' in self.variants: + scriptnames.add('%s-%s' % (name, sys.version[:3])) + if options and options.get('gui', False): + ext = 'pyw' + else: + ext = 'py' + self._write_script(scriptnames, shebang, script, filenames, ext) + + def _copy_script(self, script, filenames): + adjust = False + script = os.path.join(self.source_dir, convert_path(script)) + outname = os.path.join(self.target_dir, os.path.basename(script)) + if not self.force and not self._fileop.newer(script, outname): + logger.debug('not copying %s (up-to-date)', script) + return + + # Always open the file, but ignore failures in dry-run mode -- + # that way, we'll get accurate feedback if we can read the + # script. + try: + f = open(script, 'rb') + except IOError: # pragma: no cover + if not self.dry_run: + raise + f = None + else: + first_line = f.readline() + if not first_line: # pragma: no cover + logger.warning('%s: %s is an empty file (skipping)', + self.get_command_name(), script) + return + + match = FIRST_LINE_RE.match(first_line.replace(b'\r\n', b'\n')) + if match: + adjust = True + post_interp = match.group(1) or b'' + + if not adjust: + if f: + f.close() + self._fileop.copy_file(script, outname) + if self.set_mode: + self._fileop.set_executable_mode([outname]) + filenames.append(outname) + else: + logger.info('copying and adjusting %s -> %s', script, + self.target_dir) + if not self._fileop.dry_run: + encoding, lines = detect_encoding(f.readline) + f.seek(0) + shebang = self._get_shebang(encoding, post_interp) + if b'pythonw' in first_line: # pragma: no cover + ext = 'pyw' + else: + ext = 'py' + n = os.path.basename(outname) + self._write_script([n], shebang, f.read(), filenames, ext) + if f: + f.close() + + @property + def dry_run(self): + return self._fileop.dry_run + + @dry_run.setter + def dry_run(self, value): + self._fileop.dry_run = value + + if os.name == 'nt' or (os.name == 'java' and os._name == 'nt'): # pragma: no cover + # Executable launcher support. + # Launchers are from https://bitbucket.org/vinay.sajip/simple_launcher/ + + def _get_launcher(self, kind): + if struct.calcsize('P') == 8: # 64-bit + bits = '64' + else: + bits = '32' + name = '%s%s.exe' % (kind, bits) + # Issue 31: don't hardcode an absolute package name, but + # determine it relative to the current package + distlib_package = __name__.rsplit('.', 1)[0] + result = finder(distlib_package).find(name).bytes + return result + + # Public API follows + + def make(self, specification, options=None): + """ + Make a script. + + :param specification: The specification, which is either a valid export + entry specification (to make a script from a + callable) or a filename (to make a script by + copying from a source location). + :param options: A dictionary of options controlling script generation. + :return: A list of all absolute pathnames written to. + """ + filenames = [] + entry = get_export_entry(specification) + if entry is None: + self._copy_script(specification, filenames) + else: + self._make_script(entry, filenames, options=options) + return filenames + + def make_multiple(self, specifications, options=None): + """ + Take a list of specifications and make scripts from them, + :param specifications: A list of specifications. + :return: A list of all absolute pathnames written to, + """ + filenames = [] + for specification in specifications: + filenames.extend(self.make(specification, options)) + return filenames diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/t32.exe b/env/lib/python3.7/site-packages/pip/_vendor/distlib/t32.exe new file mode 100644 index 0000000000000000000000000000000000000000..a09d926872d84ae22a617dfe9ebb560d420b37de GIT binary patch literal 92672 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/t64.exe b/env/lib/python3.7/site-packages/pip/_vendor/distlib/t64.exe new file mode 100644 index 0000000000000000000000000000000000000000..9da9b40de922fb203df6b9a1d0ad4139af536850 GIT binary patch literal 102400 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�vlnW`{LoXpTySn$@;x8yoz96jn?+Kk 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�?dYNUd4WaURX_A__M4W}D0!0n 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/util.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/util.py new file mode 100644 index 0000000..0b14a93 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/util.py @@ -0,0 +1,1755 @@ +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +import codecs +from collections import deque +import contextlib +import csv +from glob import iglob as std_iglob +import io +import json +import logging +import os +import py_compile +import re +import socket +try: + import ssl +except ImportError: # pragma: no cover + ssl = None +import subprocess +import sys +import tarfile +import tempfile +import textwrap + +try: + import threading +except ImportError: # pragma: no cover + import dummy_threading as threading +import time + +from . import DistlibException +from .compat import (string_types, text_type, shutil, raw_input, StringIO, + cache_from_source, urlopen, urljoin, httplib, xmlrpclib, + splittype, HTTPHandler, BaseConfigurator, valid_ident, + Container, configparser, URLError, ZipFile, fsdecode, + unquote, urlparse) + +logger = logging.getLogger(__name__) + +# +# Requirement parsing code as per PEP 508 +# + +IDENTIFIER = re.compile(r'^([\w\.-]+)\s*') +VERSION_IDENTIFIER = re.compile(r'^([\w\.*+-]+)\s*') +COMPARE_OP = re.compile(r'^(<=?|>=?|={2,3}|[~!]=)\s*') +MARKER_OP = re.compile(r'^((<=?)|(>=?)|={2,3}|[~!]=|in|not\s+in)\s*') +OR = re.compile(r'^or\b\s*') +AND = re.compile(r'^and\b\s*') +NON_SPACE = re.compile(r'(\S+)\s*') +STRING_CHUNK = re.compile(r'([\s\w\.{}()*+#:;,/?!~`@$%^&=|<>\[\]-]+)') + + +def parse_marker(marker_string): + """ + Parse a marker string and return a dictionary containing a marker expression. + + The dictionary will contain keys "op", "lhs" and "rhs" for non-terminals in + the expression grammar, or strings. A string contained in quotes is to be + interpreted as a literal string, and a string not contained in quotes is a + variable (such as os_name). + """ + def marker_var(remaining): + # either identifier, or literal string + m = IDENTIFIER.match(remaining) + if m: + result = m.groups()[0] + remaining = remaining[m.end():] + elif not remaining: + raise SyntaxError('unexpected end of input') + else: + q = remaining[0] + if q not in '\'"': + raise SyntaxError('invalid expression: %s' % remaining) + oq = '\'"'.replace(q, '') + remaining = remaining[1:] + parts = [q] + while remaining: + # either a string chunk, or oq, or q to terminate + if remaining[0] == q: + break + elif remaining[0] == oq: + parts.append(oq) + remaining = remaining[1:] + else: + m = STRING_CHUNK.match(remaining) + if not m: + raise SyntaxError('error in string literal: %s' % remaining) + parts.append(m.groups()[0]) + remaining = remaining[m.end():] + else: + s = ''.join(parts) + raise SyntaxError('unterminated string: %s' % s) + parts.append(q) + result = ''.join(parts) + remaining = remaining[1:].lstrip() # skip past closing quote + return result, remaining + + def marker_expr(remaining): + if remaining and remaining[0] == '(': + result, remaining = marker(remaining[1:].lstrip()) + if remaining[0] != ')': + raise SyntaxError('unterminated parenthesis: %s' % remaining) + remaining = remaining[1:].lstrip() + else: + lhs, remaining = marker_var(remaining) + while remaining: + m = MARKER_OP.match(remaining) + if not m: + break + op = m.groups()[0] + remaining = remaining[m.end():] + rhs, remaining = marker_var(remaining) + lhs = {'op': op, 'lhs': lhs, 'rhs': rhs} + result = lhs + return result, remaining + + def marker_and(remaining): + lhs, remaining = marker_expr(remaining) + while remaining: + m = AND.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_expr(remaining) + lhs = {'op': 'and', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + def marker(remaining): + lhs, remaining = marker_and(remaining) + while remaining: + m = OR.match(remaining) + if not m: + break + remaining = remaining[m.end():] + rhs, remaining = marker_and(remaining) + lhs = {'op': 'or', 'lhs': lhs, 'rhs': rhs} + return lhs, remaining + + return marker(marker_string) + + +def parse_requirement(req): + """ + Parse a requirement passed in as a string. Return a Container + whose attributes contain the various parts of the requirement. + """ + remaining = req.strip() + if not remaining or remaining.startswith('#'): + return None + m = IDENTIFIER.match(remaining) + if not m: + raise SyntaxError('name expected: %s' % remaining) + distname = m.groups()[0] + remaining = remaining[m.end():] + extras = mark_expr = versions = uri = None + if remaining and remaining[0] == '[': + i = remaining.find(']', 1) + if i < 0: + raise SyntaxError('unterminated extra: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + extras = [] + while s: + m = IDENTIFIER.match(s) + if not m: + raise SyntaxError('malformed extra: %s' % s) + extras.append(m.groups()[0]) + s = s[m.end():] + if not s: + break + if s[0] != ',': + raise SyntaxError('comma expected in extras: %s' % s) + s = s[1:].lstrip() + if not extras: + extras = None + if remaining: + if remaining[0] == '@': + # it's a URI + remaining = remaining[1:].lstrip() + m = NON_SPACE.match(remaining) + if not m: + raise SyntaxError('invalid URI: %s' % remaining) + uri = m.groups()[0] + t = urlparse(uri) + # there are issues with Python and URL parsing, so this test + # is a bit crude. See bpo-20271, bpo-23505. Python doesn't + # always parse invalid URLs correctly - it should raise + # exceptions for malformed URLs + if not (t.scheme and t.netloc): + raise SyntaxError('Invalid URL: %s' % uri) + remaining = remaining[m.end():].lstrip() + else: + + def get_versions(ver_remaining): + """ + Return a list of operator, version tuples if any are + specified, else None. + """ + m = COMPARE_OP.match(ver_remaining) + versions = None + if m: + versions = [] + while True: + op = m.groups()[0] + ver_remaining = ver_remaining[m.end():] + m = VERSION_IDENTIFIER.match(ver_remaining) + if not m: + raise SyntaxError('invalid version: %s' % ver_remaining) + v = m.groups()[0] + versions.append((op, v)) + ver_remaining = ver_remaining[m.end():] + if not ver_remaining or ver_remaining[0] != ',': + break + ver_remaining = ver_remaining[1:].lstrip() + m = COMPARE_OP.match(ver_remaining) + if not m: + raise SyntaxError('invalid constraint: %s' % ver_remaining) + if not versions: + versions = None + return versions, ver_remaining + + if remaining[0] != '(': + versions, remaining = get_versions(remaining) + else: + i = remaining.find(')', 1) + if i < 0: + raise SyntaxError('unterminated parenthesis: %s' % remaining) + s = remaining[1:i] + remaining = remaining[i + 1:].lstrip() + # As a special diversion from PEP 508, allow a version number + # a.b.c in parentheses as a synonym for ~= a.b.c (because this + # is allowed in earlier PEPs) + if COMPARE_OP.match(s): + versions, _ = get_versions(s) + else: + m = VERSION_IDENTIFIER.match(s) + if not m: + raise SyntaxError('invalid constraint: %s' % s) + v = m.groups()[0] + s = s[m.end():].lstrip() + if s: + raise SyntaxError('invalid constraint: %s' % s) + versions = [('~=', v)] + + if remaining: + if remaining[0] != ';': + raise SyntaxError('invalid requirement: %s' % remaining) + remaining = remaining[1:].lstrip() + + mark_expr, remaining = parse_marker(remaining) + + if remaining and remaining[0] != '#': + raise SyntaxError('unexpected trailing data: %s' % remaining) + + if not versions: + rs = distname + else: + rs = '%s %s' % (distname, ', '.join(['%s %s' % con for con in versions])) + return Container(name=distname, extras=extras, constraints=versions, + marker=mark_expr, url=uri, requirement=rs) + + +def get_resources_dests(resources_root, rules): + """Find destinations for resources files""" + + def get_rel_path(root, path): + # normalizes and returns a lstripped-/-separated path + root = root.replace(os.path.sep, '/') + path = path.replace(os.path.sep, '/') + assert path.startswith(root) + return path[len(root):].lstrip('/') + + destinations = {} + for base, suffix, dest in rules: + prefix = os.path.join(resources_root, base) + for abs_base in iglob(prefix): + abs_glob = os.path.join(abs_base, suffix) + for abs_path in iglob(abs_glob): + resource_file = get_rel_path(resources_root, abs_path) + if dest is None: # remove the entry if it was here + destinations.pop(resource_file, None) + else: + rel_path = get_rel_path(abs_base, abs_path) + rel_dest = dest.replace(os.path.sep, '/').rstrip('/') + destinations[resource_file] = rel_dest + '/' + rel_path + return destinations + + +def in_venv(): + if hasattr(sys, 'real_prefix'): + # virtualenv venvs + result = True + else: + # PEP 405 venvs + result = sys.prefix != getattr(sys, 'base_prefix', sys.prefix) + return result + + +def get_executable(): +# The __PYVENV_LAUNCHER__ dance is apparently no longer needed, as +# changes to the stub launcher mean that sys.executable always points +# to the stub on OS X +# if sys.platform == 'darwin' and ('__PYVENV_LAUNCHER__' +# in os.environ): +# result = os.environ['__PYVENV_LAUNCHER__'] +# else: +# result = sys.executable +# return result + result = os.path.normcase(sys.executable) + if not isinstance(result, text_type): + result = fsdecode(result) + return result + + +def proceed(prompt, allowed_chars, error_prompt=None, default=None): + p = prompt + while True: + s = raw_input(p) + p = prompt + if not s and default: + s = default + if s: + c = s[0].lower() + if c in allowed_chars: + break + if error_prompt: + p = '%c: %s\n%s' % (c, error_prompt, prompt) + return c + + +def extract_by_key(d, keys): + if isinstance(keys, string_types): + keys = keys.split() + result = {} + for key in keys: + if key in d: + result[key] = d[key] + return result + +def read_exports(stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + # Try to load as JSON, falling back on legacy format + data = stream.read() + stream = StringIO(data) + try: + jdata = json.load(stream) + result = jdata['extensions']['python.exports']['exports'] + for group, entries in result.items(): + for k, v in entries.items(): + s = '%s = %s' % (k, v) + entry = get_export_entry(s) + assert entry is not None + entries[k] = entry + return result + except Exception: + stream.seek(0, 0) + + def read_stream(cp, stream): + if hasattr(cp, 'read_file'): + cp.read_file(stream) + else: + cp.readfp(stream) + + cp = configparser.ConfigParser() + try: + read_stream(cp, stream) + except configparser.MissingSectionHeaderError: + stream.close() + data = textwrap.dedent(data) + stream = StringIO(data) + read_stream(cp, stream) + + result = {} + for key in cp.sections(): + result[key] = entries = {} + for name, value in cp.items(key): + s = '%s = %s' % (name, value) + entry = get_export_entry(s) + assert entry is not None + #entry.dist = self + entries[name] = entry + return result + + +def write_exports(exports, stream): + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getwriter('utf-8')(stream) + cp = configparser.ConfigParser() + for k, v in exports.items(): + # TODO check k, v for valid values + cp.add_section(k) + for entry in v.values(): + if entry.suffix is None: + s = entry.prefix + else: + s = '%s:%s' % (entry.prefix, entry.suffix) + if entry.flags: + s = '%s [%s]' % (s, ', '.join(entry.flags)) + cp.set(k, entry.name, s) + cp.write(stream) + + +@contextlib.contextmanager +def tempdir(): + td = tempfile.mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + +@contextlib.contextmanager +def chdir(d): + cwd = os.getcwd() + try: + os.chdir(d) + yield + finally: + os.chdir(cwd) + + +@contextlib.contextmanager +def socket_timeout(seconds=15): + cto = socket.getdefaulttimeout() + try: + socket.setdefaulttimeout(seconds) + yield + finally: + socket.setdefaulttimeout(cto) + + +class cached_property(object): + def __init__(self, func): + self.func = func + #for attr in ('__name__', '__module__', '__doc__'): + # setattr(self, attr, getattr(func, attr, None)) + + def __get__(self, obj, cls=None): + if obj is None: + return self + value = self.func(obj) + object.__setattr__(obj, self.func.__name__, value) + #obj.__dict__[self.func.__name__] = value = self.func(obj) + return value + +def convert_path(pathname): + """Return 'pathname' as a name that will work on the native filesystem. + + The path is split on '/' and put back together again using the current + directory separator. Needed because filenames in the setup script are + always supplied in Unix style, and have to be converted to the local + convention before we can actually use them in the filesystem. Raises + ValueError on non-Unix-ish systems if 'pathname' either starts or + ends with a slash. + """ + if os.sep == '/': + return pathname + if not pathname: + return pathname + if pathname[0] == '/': + raise ValueError("path '%s' cannot be absolute" % pathname) + if pathname[-1] == '/': + raise ValueError("path '%s' cannot end with '/'" % pathname) + + paths = pathname.split('/') + while os.curdir in paths: + paths.remove(os.curdir) + if not paths: + return os.curdir + return os.path.join(*paths) + + +class FileOperator(object): + def __init__(self, dry_run=False): + self.dry_run = dry_run + self.ensured = set() + self._init_record() + + def _init_record(self): + self.record = False + self.files_written = set() + self.dirs_created = set() + + def record_as_written(self, path): + if self.record: + self.files_written.add(path) + + def newer(self, source, target): + """Tell if the target is newer than the source. + + Returns true if 'source' exists and is more recently modified than + 'target', or if 'source' exists and 'target' doesn't. + + Returns false if both exist and 'target' is the same age or younger + than 'source'. Raise PackagingFileError if 'source' does not exist. + + Note that this test is not very accurate: files created in the same + second will have the same "age". + """ + if not os.path.exists(source): + raise DistlibException("file '%r' does not exist" % + os.path.abspath(source)) + if not os.path.exists(target): + return True + + return os.stat(source).st_mtime > os.stat(target).st_mtime + + def copy_file(self, infile, outfile, check=True): + """Copy a file respecting dry-run and force flags. + """ + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying %s to %s', infile, outfile) + if not self.dry_run: + msg = None + if check: + if os.path.islink(outfile): + msg = '%s is a symlink' % outfile + elif os.path.exists(outfile) and not os.path.isfile(outfile): + msg = '%s is a non-regular file' % outfile + if msg: + raise ValueError(msg + ' which would be overwritten') + shutil.copyfile(infile, outfile) + self.record_as_written(outfile) + + def copy_stream(self, instream, outfile, encoding=None): + assert not os.path.isdir(outfile) + self.ensure_dir(os.path.dirname(outfile)) + logger.info('Copying stream %s to %s', instream, outfile) + if not self.dry_run: + if encoding is None: + outstream = open(outfile, 'wb') + else: + outstream = codecs.open(outfile, 'w', encoding=encoding) + try: + shutil.copyfileobj(instream, outstream) + finally: + outstream.close() + self.record_as_written(outfile) + + def write_binary_file(self, path, data): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + with open(path, 'wb') as f: + f.write(data) + self.record_as_written(path) + + def write_text_file(self, path, data, encoding): + self.ensure_dir(os.path.dirname(path)) + if not self.dry_run: + with open(path, 'wb') as f: + f.write(data.encode(encoding)) + self.record_as_written(path) + + def set_mode(self, bits, mask, files): + if os.name == 'posix' or (os.name == 'java' and os._name == 'posix'): + # Set the executable bits (owner, group, and world) on + # all the files specified. + for f in files: + if self.dry_run: + logger.info("changing mode of %s", f) + else: + mode = (os.stat(f).st_mode | bits) & mask + logger.info("changing mode of %s to %o", f, mode) + os.chmod(f, mode) + + set_executable_mode = lambda s, f: s.set_mode(0o555, 0o7777, f) + + def ensure_dir(self, path): + path = os.path.abspath(path) + if path not in self.ensured and not os.path.exists(path): + self.ensured.add(path) + d, f = os.path.split(path) + self.ensure_dir(d) + logger.info('Creating %s' % path) + if not self.dry_run: + os.mkdir(path) + if self.record: + self.dirs_created.add(path) + + def byte_compile(self, path, optimize=False, force=False, prefix=None): + dpath = cache_from_source(path, not optimize) + logger.info('Byte-compiling %s to %s', path, dpath) + if not self.dry_run: + if force or self.newer(path, dpath): + if not prefix: + diagpath = None + else: + assert path.startswith(prefix) + diagpath = path[len(prefix):] + py_compile.compile(path, dpath, diagpath, True) # raise error + self.record_as_written(dpath) + return dpath + + def ensure_removed(self, path): + if os.path.exists(path): + if os.path.isdir(path) and not os.path.islink(path): + logger.debug('Removing directory tree at %s', path) + if not self.dry_run: + shutil.rmtree(path) + if self.record: + if path in self.dirs_created: + self.dirs_created.remove(path) + else: + if os.path.islink(path): + s = 'link' + else: + s = 'file' + logger.debug('Removing %s %s', s, path) + if not self.dry_run: + os.remove(path) + if self.record: + if path in self.files_written: + self.files_written.remove(path) + + def is_writable(self, path): + result = False + while not result: + if os.path.exists(path): + result = os.access(path, os.W_OK) + break + parent = os.path.dirname(path) + if parent == path: + break + path = parent + return result + + def commit(self): + """ + Commit recorded changes, turn off recording, return + changes. + """ + assert self.record + result = self.files_written, self.dirs_created + self._init_record() + return result + + def rollback(self): + if not self.dry_run: + for f in list(self.files_written): + if os.path.exists(f): + os.remove(f) + # dirs should all be empty now, except perhaps for + # __pycache__ subdirs + # reverse so that subdirs appear before their parents + dirs = sorted(self.dirs_created, reverse=True) + for d in dirs: + flist = os.listdir(d) + if flist: + assert flist == ['__pycache__'] + sd = os.path.join(d, flist[0]) + os.rmdir(sd) + os.rmdir(d) # should fail if non-empty + self._init_record() + +def resolve(module_name, dotted_path): + if module_name in sys.modules: + mod = sys.modules[module_name] + else: + mod = __import__(module_name) + if dotted_path is None: + result = mod + else: + parts = dotted_path.split('.') + result = getattr(mod, parts.pop(0)) + for p in parts: + result = getattr(result, p) + return result + + +class ExportEntry(object): + def __init__(self, name, prefix, suffix, flags): + self.name = name + self.prefix = prefix + self.suffix = suffix + self.flags = flags + + @cached_property + def value(self): + return resolve(self.prefix, self.suffix) + + def __repr__(self): # pragma: no cover + return '<ExportEntry %s = %s:%s %s>' % (self.name, self.prefix, + self.suffix, self.flags) + + def __eq__(self, other): + if not isinstance(other, ExportEntry): + result = False + else: + result = (self.name == other.name and + self.prefix == other.prefix and + self.suffix == other.suffix and + self.flags == other.flags) + return result + + __hash__ = object.__hash__ + + +ENTRY_RE = re.compile(r'''(?P<name>(\w|[-.+])+) + \s*=\s*(?P<callable>(\w+)([:\.]\w+)*) + \s*(\[\s*(?P<flags>\w+(=\w+)?(,\s*\w+(=\w+)?)*)\s*\])? + ''', re.VERBOSE) + +def get_export_entry(specification): + m = ENTRY_RE.search(specification) + if not m: + result = None + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + else: + d = m.groupdict() + name = d['name'] + path = d['callable'] + colons = path.count(':') + if colons == 0: + prefix, suffix = path, None + else: + if colons != 1: + raise DistlibException("Invalid specification " + "'%s'" % specification) + prefix, suffix = path.split(':') + flags = d['flags'] + if flags is None: + if '[' in specification or ']' in specification: + raise DistlibException("Invalid specification " + "'%s'" % specification) + flags = [] + else: + flags = [f.strip() for f in flags.split(',')] + result = ExportEntry(name, prefix, suffix, flags) + return result + + +def get_cache_base(suffix=None): + """ + Return the default base location for distlib caches. If the directory does + not exist, it is created. Use the suffix provided for the base directory, + and default to '.distlib' if it isn't provided. + + On Windows, if LOCALAPPDATA is defined in the environment, then it is + assumed to be a directory, and will be the parent directory of the result. + On POSIX, and on Windows if LOCALAPPDATA is not defined, the user's home + directory - using os.expanduser('~') - will be the parent directory of + the result. + + The result is just the directory '.distlib' in the parent directory as + determined above, or with the name specified with ``suffix``. + """ + if suffix is None: + suffix = '.distlib' + if os.name == 'nt' and 'LOCALAPPDATA' in os.environ: + result = os.path.expandvars('$localappdata') + else: + # Assume posix, or old Windows + result = os.path.expanduser('~') + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if os.path.isdir(result): + usable = os.access(result, os.W_OK) + if not usable: + logger.warning('Directory exists but is not writable: %s', result) + else: + try: + os.makedirs(result) + usable = True + except OSError: + logger.warning('Unable to create %s', result, exc_info=True) + usable = False + if not usable: + result = tempfile.mkdtemp() + logger.warning('Default location unusable, using %s', result) + return os.path.join(result, suffix) + + +def path_to_cache_dir(path): + """ + Convert an absolute path to a directory name for use in a cache. + + The algorithm used is: + + #. On Windows, any ``':'`` in the drive is replaced with ``'---'``. + #. Any occurrence of ``os.sep`` is replaced with ``'--'``. + #. ``'.cache'`` is appended. + """ + d, p = os.path.splitdrive(os.path.abspath(path)) + if d: + d = d.replace(':', '---') + p = p.replace(os.sep, '--') + return d + p + '.cache' + + +def ensure_slash(s): + if not s.endswith('/'): + return s + '/' + return s + + +def parse_credentials(netloc): + username = password = None + if '@' in netloc: + prefix, netloc = netloc.split('@', 1) + if ':' not in prefix: + username = prefix + else: + username, password = prefix.split(':', 1) + return username, password, netloc + + +def get_process_umask(): + result = os.umask(0o22) + os.umask(result) + return result + +def is_string_sequence(seq): + result = True + i = None + for i, s in enumerate(seq): + if not isinstance(s, string_types): + result = False + break + assert i is not None + return result + +PROJECT_NAME_AND_VERSION = re.compile('([a-z0-9_]+([.-][a-z_][a-z0-9_]*)*)-' + '([a-z0-9_.+-]+)', re.I) +PYTHON_VERSION = re.compile(r'-py(\d\.?\d?)') + + +def split_filename(filename, project_name=None): + """ + Extract name, version, python version from a filename (no extension) + + Return name, version, pyver or None + """ + result = None + pyver = None + filename = unquote(filename).replace(' ', '-') + m = PYTHON_VERSION.search(filename) + if m: + pyver = m.group(1) + filename = filename[:m.start()] + if project_name and len(filename) > len(project_name) + 1: + m = re.match(re.escape(project_name) + r'\b', filename) + if m: + n = m.end() + result = filename[:n], filename[n + 1:], pyver + if result is None: + m = PROJECT_NAME_AND_VERSION.match(filename) + if m: + result = m.group(1), m.group(3), pyver + return result + +# Allow spaces in name because of legacy dists like "Twisted Core" +NAME_VERSION_RE = re.compile(r'(?P<name>[\w .-]+)\s*' + r'\(\s*(?P<ver>[^\s)]+)\)$') + +def parse_name_and_version(p): + """ + A utility method used to get name and version from a string. + + From e.g. a Provides-Dist value. + + :param p: A value in a form 'foo (1.0)' + :return: The name and version as a tuple. + """ + m = NAME_VERSION_RE.match(p) + if not m: + raise DistlibException('Ill-formed name/version string: \'%s\'' % p) + d = m.groupdict() + return d['name'].strip().lower(), d['ver'] + +def get_extras(requested, available): + result = set() + requested = set(requested or []) + available = set(available or []) + if '*' in requested: + requested.remove('*') + result |= available + for r in requested: + if r == '-': + result.add(r) + elif r.startswith('-'): + unwanted = r[1:] + if unwanted not in available: + logger.warning('undeclared extra: %s' % unwanted) + if unwanted in result: + result.remove(unwanted) + else: + if r not in available: + logger.warning('undeclared extra: %s' % r) + result.add(r) + return result +# +# Extended metadata functionality +# + +def _get_external_data(url): + result = {} + try: + # urlopen might fail if it runs into redirections, + # because of Python issue #13696. Fixed in locators + # using a custom redirect handler. + resp = urlopen(url) + headers = resp.info() + ct = headers.get('Content-Type') + if not ct.startswith('application/json'): + logger.debug('Unexpected response for JSON request: %s', ct) + else: + reader = codecs.getreader('utf-8')(resp) + #data = reader.read().decode('utf-8') + #result = json.loads(data) + result = json.load(reader) + except Exception as e: + logger.exception('Failed to get external data for %s: %s', url, e) + return result + +_external_data_base_url = 'https://www.red-dove.com/pypi/projects/' + +def get_project_data(name): + url = '%s/%s/project.json' % (name[0].upper(), name) + url = urljoin(_external_data_base_url, url) + result = _get_external_data(url) + return result + +def get_package_data(name, version): + url = '%s/%s/package-%s.json' % (name[0].upper(), name, version) + url = urljoin(_external_data_base_url, url) + return _get_external_data(url) + + +class Cache(object): + """ + A class implementing a cache for resources that need to live in the file system + e.g. shared libraries. This class was moved from resources to here because it + could be used by other modules, e.g. the wheel module. + """ + + def __init__(self, base): + """ + Initialise an instance. + + :param base: The base directory where the cache should be located. + """ + # we use 'isdir' instead of 'exists', because we want to + # fail if there's a file with that name + if not os.path.isdir(base): # pragma: no cover + os.makedirs(base) + if (os.stat(base).st_mode & 0o77) != 0: + logger.warning('Directory \'%s\' is not private', base) + self.base = os.path.abspath(os.path.normpath(base)) + + def prefix_to_dir(self, prefix): + """ + Converts a resource prefix to a directory name in the cache. + """ + return path_to_cache_dir(prefix) + + def clear(self): + """ + Clear the cache. + """ + not_removed = [] + for fn in os.listdir(self.base): + fn = os.path.join(self.base, fn) + try: + if os.path.islink(fn) or os.path.isfile(fn): + os.remove(fn) + elif os.path.isdir(fn): + shutil.rmtree(fn) + except Exception: + not_removed.append(fn) + return not_removed + + +class EventMixin(object): + """ + A very simple publish/subscribe system. + """ + def __init__(self): + self._subscribers = {} + + def add(self, event, subscriber, append=True): + """ + Add a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be added (and called when the + event is published). + :param append: Whether to append or prepend the subscriber to an + existing subscriber list for the event. + """ + subs = self._subscribers + if event not in subs: + subs[event] = deque([subscriber]) + else: + sq = subs[event] + if append: + sq.append(subscriber) + else: + sq.appendleft(subscriber) + + def remove(self, event, subscriber): + """ + Remove a subscriber for an event. + + :param event: The name of an event. + :param subscriber: The subscriber to be removed. + """ + subs = self._subscribers + if event not in subs: + raise ValueError('No subscribers: %r' % event) + subs[event].remove(subscriber) + + def get_subscribers(self, event): + """ + Return an iterator for the subscribers for an event. + :param event: The event to return subscribers for. + """ + return iter(self._subscribers.get(event, ())) + + def publish(self, event, *args, **kwargs): + """ + Publish a event and return a list of values returned by its + subscribers. + + :param event: The event to publish. + :param args: The positional arguments to pass to the event's + subscribers. + :param kwargs: The keyword arguments to pass to the event's + subscribers. + """ + result = [] + for subscriber in self.get_subscribers(event): + try: + value = subscriber(event, *args, **kwargs) + except Exception: + logger.exception('Exception during event publication') + value = None + result.append(value) + logger.debug('publish %s: args = %s, kwargs = %s, result = %s', + event, args, kwargs, result) + return result + +# +# Simple sequencing +# +class Sequencer(object): + def __init__(self): + self._preds = {} + self._succs = {} + self._nodes = set() # nodes with no preds/succs + + def add_node(self, node): + self._nodes.add(node) + + def remove_node(self, node, edges=False): + if node in self._nodes: + self._nodes.remove(node) + if edges: + for p in set(self._preds.get(node, ())): + self.remove(p, node) + for s in set(self._succs.get(node, ())): + self.remove(node, s) + # Remove empties + for k, v in list(self._preds.items()): + if not v: + del self._preds[k] + for k, v in list(self._succs.items()): + if not v: + del self._succs[k] + + def add(self, pred, succ): + assert pred != succ + self._preds.setdefault(succ, set()).add(pred) + self._succs.setdefault(pred, set()).add(succ) + + def remove(self, pred, succ): + assert pred != succ + try: + preds = self._preds[succ] + succs = self._succs[pred] + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of anything' % succ) + try: + preds.remove(pred) + succs.remove(succ) + except KeyError: # pragma: no cover + raise ValueError('%r not a successor of %r' % (succ, pred)) + + def is_step(self, step): + return (step in self._preds or step in self._succs or + step in self._nodes) + + def get_steps(self, final): + if not self.is_step(final): + raise ValueError('Unknown: %r' % final) + result = [] + todo = [] + seen = set() + todo.append(final) + while todo: + step = todo.pop(0) + if step in seen: + # if a step was already seen, + # move it to the end (so it will appear earlier + # when reversed on return) ... but not for the + # final step, as that would be confusing for + # users + if step != final: + result.remove(step) + result.append(step) + else: + seen.add(step) + result.append(step) + preds = self._preds.get(step, ()) + todo.extend(preds) + return reversed(result) + + @property + def strong_connections(self): + #http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm + index_counter = [0] + stack = [] + lowlinks = {} + index = {} + result = [] + + graph = self._succs + + def strongconnect(node): + # set the depth index for this node to the smallest unused index + index[node] = index_counter[0] + lowlinks[node] = index_counter[0] + index_counter[0] += 1 + stack.append(node) + + # Consider successors + try: + successors = graph[node] + except Exception: + successors = [] + for successor in successors: + if successor not in lowlinks: + # Successor has not yet been visited + strongconnect(successor) + lowlinks[node] = min(lowlinks[node],lowlinks[successor]) + elif successor in stack: + # the successor is in the stack and hence in the current + # strongly connected component (SCC) + lowlinks[node] = min(lowlinks[node],index[successor]) + + # If `node` is a root node, pop the stack and generate an SCC + if lowlinks[node] == index[node]: + connected_component = [] + + while True: + successor = stack.pop() + connected_component.append(successor) + if successor == node: break + component = tuple(connected_component) + # storing the result + result.append(component) + + for node in graph: + if node not in lowlinks: + strongconnect(node) + + return result + + @property + def dot(self): + result = ['digraph G {'] + for succ in self._preds: + preds = self._preds[succ] + for pred in preds: + result.append(' %s -> %s;' % (pred, succ)) + for node in self._nodes: + result.append(' %s;' % node) + result.append('}') + return '\n'.join(result) + +# +# Unarchiving functionality for zip, tar, tgz, tbz, whl +# + +ARCHIVE_EXTENSIONS = ('.tar.gz', '.tar.bz2', '.tar', '.zip', + '.tgz', '.tbz', '.whl') + +def unarchive(archive_filename, dest_dir, format=None, check=True): + + def check_path(path): + if not isinstance(path, text_type): + path = path.decode('utf-8') + p = os.path.abspath(os.path.join(dest_dir, path)) + if not p.startswith(dest_dir) or p[plen] != os.sep: + raise ValueError('path outside destination: %r' % p) + + dest_dir = os.path.abspath(dest_dir) + plen = len(dest_dir) + archive = None + if format is None: + if archive_filename.endswith(('.zip', '.whl')): + format = 'zip' + elif archive_filename.endswith(('.tar.gz', '.tgz')): + format = 'tgz' + mode = 'r:gz' + elif archive_filename.endswith(('.tar.bz2', '.tbz')): + format = 'tbz' + mode = 'r:bz2' + elif archive_filename.endswith('.tar'): + format = 'tar' + mode = 'r' + else: # pragma: no cover + raise ValueError('Unknown format for %r' % archive_filename) + try: + if format == 'zip': + archive = ZipFile(archive_filename, 'r') + if check: + names = archive.namelist() + for name in names: + check_path(name) + else: + archive = tarfile.open(archive_filename, mode) + if check: + names = archive.getnames() + for name in names: + check_path(name) + if format != 'zip' and sys.version_info[0] < 3: + # See Python issue 17153. If the dest path contains Unicode, + # tarfile extraction fails on Python 2.x if a member path name + # contains non-ASCII characters - it leads to an implicit + # bytes -> unicode conversion using ASCII to decode. + for tarinfo in archive.getmembers(): + if not isinstance(tarinfo.name, text_type): + tarinfo.name = tarinfo.name.decode('utf-8') + archive.extractall(dest_dir) + + finally: + if archive: + archive.close() + + +def zip_dir(directory): + """zip a directory tree into a BytesIO object""" + result = io.BytesIO() + dlen = len(directory) + with ZipFile(result, "w") as zf: + for root, dirs, files in os.walk(directory): + for name in files: + full = os.path.join(root, name) + rel = root[dlen:] + dest = os.path.join(rel, name) + zf.write(full, dest) + return result + +# +# Simple progress bar +# + +UNITS = ('', 'K', 'M', 'G','T','P') + + +class Progress(object): + unknown = 'UNKNOWN' + + def __init__(self, minval=0, maxval=100): + assert maxval is None or maxval >= minval + self.min = self.cur = minval + self.max = maxval + self.started = None + self.elapsed = 0 + self.done = False + + def update(self, curval): + assert self.min <= curval + assert self.max is None or curval <= self.max + self.cur = curval + now = time.time() + if self.started is None: + self.started = now + else: + self.elapsed = now - self.started + + def increment(self, incr): + assert incr >= 0 + self.update(self.cur + incr) + + def start(self): + self.update(self.min) + return self + + def stop(self): + if self.max is not None: + self.update(self.max) + self.done = True + + @property + def maximum(self): + return self.unknown if self.max is None else self.max + + @property + def percentage(self): + if self.done: + result = '100 %' + elif self.max is None: + result = ' ?? %' + else: + v = 100.0 * (self.cur - self.min) / (self.max - self.min) + result = '%3d %%' % v + return result + + def format_duration(self, duration): + if (duration <= 0) and self.max is None or self.cur == self.min: + result = '??:??:??' + #elif duration < 1: + # result = '--:--:--' + else: + result = time.strftime('%H:%M:%S', time.gmtime(duration)) + return result + + @property + def ETA(self): + if self.done: + prefix = 'Done' + t = self.elapsed + #import pdb; pdb.set_trace() + else: + prefix = 'ETA ' + if self.max is None: + t = -1 + elif self.elapsed == 0 or (self.cur == self.min): + t = 0 + else: + #import pdb; pdb.set_trace() + t = float(self.max - self.min) + t /= self.cur - self.min + t = (t - 1) * self.elapsed + return '%s: %s' % (prefix, self.format_duration(t)) + + @property + def speed(self): + if self.elapsed == 0: + result = 0.0 + else: + result = (self.cur - self.min) / self.elapsed + for unit in UNITS: + if result < 1000: + break + result /= 1000.0 + return '%d %sB/s' % (result, unit) + +# +# Glob functionality +# + +RICH_GLOB = re.compile(r'\{([^}]*)\}') +_CHECK_RECURSIVE_GLOB = re.compile(r'[^/\\,{]\*\*|\*\*[^/\\,}]') +_CHECK_MISMATCH_SET = re.compile(r'^[^{]*\}|\{[^}]*$') + + +def iglob(path_glob): + """Extended globbing function that supports ** and {opt1,opt2,opt3}.""" + if _CHECK_RECURSIVE_GLOB.search(path_glob): + msg = """invalid glob %r: recursive glob "**" must be used alone""" + raise ValueError(msg % path_glob) + if _CHECK_MISMATCH_SET.search(path_glob): + msg = """invalid glob %r: mismatching set marker '{' or '}'""" + raise ValueError(msg % path_glob) + return _iglob(path_glob) + + +def _iglob(path_glob): + rich_path_glob = RICH_GLOB.split(path_glob, 1) + if len(rich_path_glob) > 1: + assert len(rich_path_glob) == 3, rich_path_glob + prefix, set, suffix = rich_path_glob + for item in set.split(','): + for path in _iglob(''.join((prefix, item, suffix))): + yield path + else: + if '**' not in path_glob: + for item in std_iglob(path_glob): + yield item + else: + prefix, radical = path_glob.split('**', 1) + if prefix == '': + prefix = '.' + if radical == '': + radical = '*' + else: + # we support both + radical = radical.lstrip('/') + radical = radical.lstrip('\\') + for path, dir, files in os.walk(prefix): + path = os.path.normpath(path) + for fn in _iglob(os.path.join(path, radical)): + yield fn + +if ssl: + from .compat import (HTTPSHandler as BaseHTTPSHandler, match_hostname, + CertificateError) + + +# +# HTTPSConnection which verifies certificates/matches domains +# + + class HTTPSConnection(httplib.HTTPSConnection): + ca_certs = None # set this to the path to the certs file (.pem) + check_domain = True # only used if ca_certs is not None + + # noinspection PyPropertyAccess + def connect(self): + sock = socket.create_connection((self.host, self.port), self.timeout) + if getattr(self, '_tunnel_host', False): + self.sock = sock + self._tunnel() + + if not hasattr(ssl, 'SSLContext'): + # For 2.x + if self.ca_certs: + cert_reqs = ssl.CERT_REQUIRED + else: + cert_reqs = ssl.CERT_NONE + self.sock = ssl.wrap_socket(sock, self.key_file, self.cert_file, + cert_reqs=cert_reqs, + ssl_version=ssl.PROTOCOL_SSLv23, + ca_certs=self.ca_certs) + else: # pragma: no cover + context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + context.options |= ssl.OP_NO_SSLv2 + if self.cert_file: + context.load_cert_chain(self.cert_file, self.key_file) + kwargs = {} + if self.ca_certs: + context.verify_mode = ssl.CERT_REQUIRED + context.load_verify_locations(cafile=self.ca_certs) + if getattr(ssl, 'HAS_SNI', False): + kwargs['server_hostname'] = self.host + self.sock = context.wrap_socket(sock, **kwargs) + if self.ca_certs and self.check_domain: + try: + match_hostname(self.sock.getpeercert(), self.host) + logger.debug('Host verified: %s', self.host) + except CertificateError: # pragma: no cover + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise + + class HTTPSHandler(BaseHTTPSHandler): + def __init__(self, ca_certs, check_domain=True): + BaseHTTPSHandler.__init__(self) + self.ca_certs = ca_certs + self.check_domain = check_domain + + def _conn_maker(self, *args, **kwargs): + """ + This is called to create a connection instance. Normally you'd + pass a connection class to do_open, but it doesn't actually check for + a class, and just expects a callable. As long as we behave just as a + constructor would have, we should be OK. If it ever changes so that + we *must* pass a class, we'll create an UnsafeHTTPSConnection class + which just sets check_domain to False in the class definition, and + choose which one to pass to do_open. + """ + result = HTTPSConnection(*args, **kwargs) + if self.ca_certs: + result.ca_certs = self.ca_certs + result.check_domain = self.check_domain + return result + + def https_open(self, req): + try: + return self.do_open(self._conn_maker, req) + except URLError as e: + if 'certificate verify failed' in str(e.reason): + raise CertificateError('Unable to verify server certificate ' + 'for %s' % req.host) + else: + raise + + # + # To prevent against mixing HTTP traffic with HTTPS (examples: A Man-In-The- + # Middle proxy using HTTP listens on port 443, or an index mistakenly serves + # HTML containing a http://xyz link when it should be https://xyz), + # you can use the following handler class, which does not allow HTTP traffic. + # + # It works by inheriting from HTTPHandler - so build_opener won't add a + # handler for HTTP itself. + # + class HTTPSOnlyHandler(HTTPSHandler, HTTPHandler): + def http_open(self, req): + raise URLError('Unexpected HTTP request on what should be a secure ' + 'connection: %s' % req) + +# +# XML-RPC with timeouts +# + +_ver_info = sys.version_info[:2] + +if _ver_info == (2, 6): + class HTTP(httplib.HTTP): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + + if ssl: + class HTTPS(httplib.HTTPS): + def __init__(self, host='', port=None, **kwargs): + if port == 0: # 0 means use port 0, not the default port + port = None + self._setup(self._connection_class(host, port, **kwargs)) + + +class Transport(xmlrpclib.Transport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.Transport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, x509 = self.get_host_info(host) + if _ver_info == (2, 6): + result = HTTP(h, timeout=self.timeout) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPConnection(h) + result = self._connection[1] + return result + +if ssl: + class SafeTransport(xmlrpclib.SafeTransport): + def __init__(self, timeout, use_datetime=0): + self.timeout = timeout + xmlrpclib.SafeTransport.__init__(self, use_datetime) + + def make_connection(self, host): + h, eh, kwargs = self.get_host_info(host) + if not kwargs: + kwargs = {} + kwargs['timeout'] = self.timeout + if _ver_info == (2, 6): + result = HTTPS(host, None, **kwargs) + else: + if not self._connection or host != self._connection[0]: + self._extra_headers = eh + self._connection = host, httplib.HTTPSConnection(h, None, + **kwargs) + result = self._connection[1] + return result + + +class ServerProxy(xmlrpclib.ServerProxy): + def __init__(self, uri, **kwargs): + self.timeout = timeout = kwargs.pop('timeout', None) + # The above classes only come into play if a timeout + # is specified + if timeout is not None: + scheme, _ = splittype(uri) + use_datetime = kwargs.get('use_datetime', 0) + if scheme == 'https': + tcls = SafeTransport + else: + tcls = Transport + kwargs['transport'] = t = tcls(timeout, use_datetime=use_datetime) + self.transport = t + xmlrpclib.ServerProxy.__init__(self, uri, **kwargs) + +# +# CSV functionality. This is provided because on 2.x, the csv module can't +# handle Unicode. However, we need to deal with Unicode in e.g. RECORD files. +# + +def _csv_open(fn, mode, **kwargs): + if sys.version_info[0] < 3: + mode += 'b' + else: + kwargs['newline'] = '' + # Python 3 determines encoding from locale. Force 'utf-8' + # file encoding to match other forced utf-8 encoding + kwargs['encoding'] = 'utf-8' + return open(fn, mode, **kwargs) + + +class CSVBase(object): + defaults = { + 'delimiter': str(','), # The strs are used because we need native + 'quotechar': str('"'), # str in the csv API (2.x won't take + 'lineterminator': str('\n') # Unicode) + } + + def __enter__(self): + return self + + def __exit__(self, *exc_info): + self.stream.close() + + +class CSVReader(CSVBase): + def __init__(self, **kwargs): + if 'stream' in kwargs: + stream = kwargs['stream'] + if sys.version_info[0] >= 3: + # needs to be a text stream + stream = codecs.getreader('utf-8')(stream) + self.stream = stream + else: + self.stream = _csv_open(kwargs['path'], 'r') + self.reader = csv.reader(self.stream, **self.defaults) + + def __iter__(self): + return self + + def next(self): + result = next(self.reader) + if sys.version_info[0] < 3: + for i, item in enumerate(result): + if not isinstance(item, text_type): + result[i] = item.decode('utf-8') + return result + + __next__ = next + +class CSVWriter(CSVBase): + def __init__(self, fn, **kwargs): + self.stream = _csv_open(fn, 'w') + self.writer = csv.writer(self.stream, **self.defaults) + + def writerow(self, row): + if sys.version_info[0] < 3: + r = [] + for item in row: + if isinstance(item, text_type): + item = item.encode('utf-8') + r.append(item) + row = r + self.writer.writerow(row) + +# +# Configurator functionality +# + +class Configurator(BaseConfigurator): + + value_converters = dict(BaseConfigurator.value_converters) + value_converters['inc'] = 'inc_convert' + + def __init__(self, config, base=None): + super(Configurator, self).__init__(config) + self.base = base or os.getcwd() + + def configure_custom(self, config): + def convert(o): + if isinstance(o, (list, tuple)): + result = type(o)([convert(i) for i in o]) + elif isinstance(o, dict): + if '()' in o: + result = self.configure_custom(o) + else: + result = {} + for k in o: + result[k] = convert(o[k]) + else: + result = self.convert(o) + return result + + c = config.pop('()') + if not callable(c): + c = self.resolve(c) + props = config.pop('.', None) + # Check for valid identifiers + args = config.pop('[]', ()) + if args: + args = tuple([convert(o) for o in args]) + items = [(k, convert(config[k])) for k in config if valid_ident(k)] + kwargs = dict(items) + result = c(*args, **kwargs) + if props: + for n, v in props.items(): + setattr(result, n, convert(v)) + return result + + def __getitem__(self, key): + result = self.config[key] + if isinstance(result, dict) and '()' in result: + self.config[key] = result = self.configure_custom(result) + return result + + def inc_convert(self, value): + """Default converter for the inc:// protocol.""" + if not os.path.isabs(value): + value = os.path.join(self.base, value) + with codecs.open(value, 'r', encoding='utf-8') as f: + result = json.load(f) + return result + + +class SubprocessMixin(object): + """ + Mixin for running subprocesses and capturing their output + """ + def __init__(self, verbose=False, progress=None): + self.verbose = verbose + self.progress = progress + + def reader(self, stream, context): + """ + Read lines from a subprocess' output stream and either pass to a progress + callable (if specified) or write progress information to sys.stderr. + """ + progress = self.progress + verbose = self.verbose + while True: + s = stream.readline() + if not s: + break + if progress is not None: + progress(s, context) + else: + if not verbose: + sys.stderr.write('.') + else: + sys.stderr.write(s.decode('utf-8')) + sys.stderr.flush() + stream.close() + + def run_command(self, cmd, **kwargs): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, **kwargs) + t1 = threading.Thread(target=self.reader, args=(p.stdout, 'stdout')) + t1.start() + t2 = threading.Thread(target=self.reader, args=(p.stderr, 'stderr')) + t2.start() + p.wait() + t1.join() + t2.join() + if self.progress is not None: + self.progress('done.', 'main') + elif self.verbose: + sys.stderr.write('done.\n') + return p + + +def normalize_name(name): + """Normalize a python package name a la PEP 503""" + # https://www.python.org/dev/peps/pep-0503/#normalized-names + return re.sub('[-_.]+', '-', name).lower() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/version.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/version.py new file mode 100644 index 0000000..3eebe18 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/version.py @@ -0,0 +1,736 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2012-2017 The Python Software Foundation. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +""" +Implementation of a flexible versioning scheme providing support for PEP-440, +setuptools-compatible and semantic versioning. +""" + +import logging +import re + +from .compat import string_types +from .util import parse_requirement + +__all__ = ['NormalizedVersion', 'NormalizedMatcher', + 'LegacyVersion', 'LegacyMatcher', + 'SemanticVersion', 'SemanticMatcher', + 'UnsupportedVersionError', 'get_scheme'] + +logger = logging.getLogger(__name__) + + +class UnsupportedVersionError(ValueError): + """This is an unsupported version.""" + pass + + +class Version(object): + def __init__(self, s): + self._string = s = s.strip() + self._parts = parts = self.parse(s) + assert isinstance(parts, tuple) + assert len(parts) > 0 + + def parse(self, s): + raise NotImplementedError('please implement in a subclass') + + def _check_compatible(self, other): + if type(self) != type(other): + raise TypeError('cannot compare %r and %r' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + def __lt__(self, other): + self._check_compatible(other) + return self._parts < other._parts + + def __gt__(self, other): + return not (self.__lt__(other) or self.__eq__(other)) + + def __le__(self, other): + return self.__lt__(other) or self.__eq__(other) + + def __ge__(self, other): + return self.__gt__(other) or self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self._parts) + + def __repr__(self): + return "%s('%s')" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + @property + def is_prerelease(self): + raise NotImplementedError('Please implement in subclasses.') + + +class Matcher(object): + version_class = None + + # value is either a callable or the name of a method + _operators = { + '<': lambda v, c, p: v < c, + '>': lambda v, c, p: v > c, + '<=': lambda v, c, p: v == c or v < c, + '>=': lambda v, c, p: v == c or v > c, + '==': lambda v, c, p: v == c, + '===': lambda v, c, p: v == c, + # by default, compatible => >=. + '~=': lambda v, c, p: v == c or v > c, + '!=': lambda v, c, p: v != c, + } + + # this is a method only to support alternative implementations + # via overriding + def parse_requirement(self, s): + return parse_requirement(s) + + def __init__(self, s): + if self.version_class is None: + raise ValueError('Please specify a version class') + self._string = s = s.strip() + r = self.parse_requirement(s) + if not r: + raise ValueError('Not valid: %r' % s) + self.name = r.name + self.key = self.name.lower() # for case-insensitive comparisons + clist = [] + if r.constraints: + # import pdb; pdb.set_trace() + for op, s in r.constraints: + if s.endswith('.*'): + if op not in ('==', '!='): + raise ValueError('\'.*\' not allowed for ' + '%r constraints' % op) + # Could be a partial version (e.g. for '2.*') which + # won't parse as a version, so keep it as a string + vn, prefix = s[:-2], True + # Just to check that vn is a valid version + self.version_class(vn) + else: + # Should parse as a version, so we can create an + # instance for the comparison + vn, prefix = self.version_class(s), False + clist.append((op, vn, prefix)) + self._parts = tuple(clist) + + def match(self, version): + """ + Check if the provided version matches the constraints. + + :param version: The version to match against this instance. + :type version: String or :class:`Version` instance. + """ + if isinstance(version, string_types): + version = self.version_class(version) + for operator, constraint, prefix in self._parts: + f = self._operators.get(operator) + if isinstance(f, string_types): + f = getattr(self, f) + if not f: + msg = ('%r not implemented ' + 'for %s' % (operator, self.__class__.__name__)) + raise NotImplementedError(msg) + if not f(version, constraint, prefix): + return False + return True + + @property + def exact_version(self): + result = None + if len(self._parts) == 1 and self._parts[0][0] in ('==', '==='): + result = self._parts[0][1] + return result + + def _check_compatible(self, other): + if type(self) != type(other) or self.name != other.name: + raise TypeError('cannot compare %s and %s' % (self, other)) + + def __eq__(self, other): + self._check_compatible(other) + return self.key == other.key and self._parts == other._parts + + def __ne__(self, other): + return not self.__eq__(other) + + # See http://docs.python.org/reference/datamodel#object.__hash__ + def __hash__(self): + return hash(self.key) + hash(self._parts) + + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self._string) + + def __str__(self): + return self._string + + +PEP440_VERSION_RE = re.compile(r'^v?(\d+!)?(\d+(\.\d+)*)((a|b|c|rc)(\d+))?' + r'(\.(post)(\d+))?(\.(dev)(\d+))?' + r'(\+([a-zA-Z\d]+(\.[a-zA-Z\d]+)?))?$') + + +def _pep_440_key(s): + s = s.strip() + m = PEP440_VERSION_RE.match(s) + if not m: + raise UnsupportedVersionError('Not a valid version: %s' % s) + groups = m.groups() + nums = tuple(int(v) for v in groups[1].split('.')) + while len(nums) > 1 and nums[-1] == 0: + nums = nums[:-1] + + if not groups[0]: + epoch = 0 + else: + epoch = int(groups[0]) + pre = groups[4:6] + post = groups[7:9] + dev = groups[10:12] + local = groups[13] + if pre == (None, None): + pre = () + else: + pre = pre[0], int(pre[1]) + if post == (None, None): + post = () + else: + post = post[0], int(post[1]) + if dev == (None, None): + dev = () + else: + dev = dev[0], int(dev[1]) + if local is None: + local = () + else: + parts = [] + for part in local.split('.'): + # to ensure that numeric compares as > lexicographic, avoid + # comparing them directly, but encode a tuple which ensures + # correct sorting + if part.isdigit(): + part = (1, int(part)) + else: + part = (0, part) + parts.append(part) + local = tuple(parts) + if not pre: + # either before pre-release, or final release and after + if not post and dev: + # before pre-release + pre = ('a', -1) # to sort before a0 + else: + pre = ('z',) # to sort after all pre-releases + # now look at the state of post and dev. + if not post: + post = ('_',) # sort before 'a' + if not dev: + dev = ('final',) + + #print('%s -> %s' % (s, m.groups())) + return epoch, nums, pre, post, dev, local + + +_normalized_key = _pep_440_key + + +class NormalizedVersion(Version): + """A rational version. + + Good: + 1.2 # equivalent to "1.2.0" + 1.2.0 + 1.2a1 + 1.2.3a2 + 1.2.3b1 + 1.2.3c1 + 1.2.3.4 + TODO: fill this out + + Bad: + 1 # minimum two numbers + 1.2a # release level must have a release serial + 1.2.3b + """ + def parse(self, s): + result = _normalized_key(s) + # _normalized_key loses trailing zeroes in the release + # clause, since that's needed to ensure that X.Y == X.Y.0 == X.Y.0.0 + # However, PEP 440 prefix matching needs it: for example, + # (~= 1.4.5.0) matches differently to (~= 1.4.5.0.0). + m = PEP440_VERSION_RE.match(s) # must succeed + groups = m.groups() + self._release_clause = tuple(int(v) for v in groups[1].split('.')) + return result + + PREREL_TAGS = set(['a', 'b', 'c', 'rc', 'dev']) + + @property + def is_prerelease(self): + return any(t[0] in self.PREREL_TAGS for t in self._parts if t) + + +def _match_prefix(x, y): + x = str(x) + y = str(y) + if x == y: + return True + if not x.startswith(y): + return False + n = len(y) + return x[n] == '.' + + +class NormalizedMatcher(Matcher): + version_class = NormalizedVersion + + # value is either a callable or the name of a method + _operators = { + '~=': '_match_compatible', + '<': '_match_lt', + '>': '_match_gt', + '<=': '_match_le', + '>=': '_match_ge', + '==': '_match_eq', + '===': '_match_arbitrary', + '!=': '_match_ne', + } + + def _adjust_local(self, version, constraint, prefix): + if prefix: + strip_local = '+' not in constraint and version._parts[-1] + else: + # both constraint and version are + # NormalizedVersion instances. + # If constraint does not have a local component, + # ensure the version doesn't, either. + strip_local = not constraint._parts[-1] and version._parts[-1] + if strip_local: + s = version._string.split('+', 1)[0] + version = self.version_class(s) + return version, constraint + + def _match_lt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version >= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_gt(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version <= constraint: + return False + release_clause = constraint._release_clause + pfx = '.'.join([str(i) for i in release_clause]) + return not _match_prefix(version, pfx) + + def _match_le(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version <= constraint + + def _match_ge(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + return version >= constraint + + def _match_eq(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version == constraint) + else: + result = _match_prefix(version, constraint) + return result + + def _match_arbitrary(self, version, constraint, prefix): + return str(version) == str(constraint) + + def _match_ne(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if not prefix: + result = (version != constraint) + else: + result = not _match_prefix(version, constraint) + return result + + def _match_compatible(self, version, constraint, prefix): + version, constraint = self._adjust_local(version, constraint, prefix) + if version == constraint: + return True + if version < constraint: + return False +# if not prefix: +# return True + release_clause = constraint._release_clause + if len(release_clause) > 1: + release_clause = release_clause[:-1] + pfx = '.'.join([str(i) for i in release_clause]) + return _match_prefix(version, pfx) + +_REPLACEMENTS = ( + (re.compile('[.+-]$'), ''), # remove trailing puncts + (re.compile(r'^[.](\d)'), r'0.\1'), # .N -> 0.N at start + (re.compile('^[.-]'), ''), # remove leading puncts + (re.compile(r'^\((.*)\)$'), r'\1'), # remove parentheses + (re.compile(r'^v(ersion)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile(r'^r(ev)?\s*(\d+)'), r'\2'), # remove leading v(ersion) + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\b(alfa|apha)\b'), 'alpha'), # misspelt alpha + (re.compile(r'\b(pre-alpha|prealpha)\b'), + 'pre.alpha'), # standardise + (re.compile(r'\(beta\)$'), 'beta'), # remove parentheses +) + +_SUFFIX_REPLACEMENTS = ( + (re.compile('^[:~._+-]+'), ''), # remove leading puncts + (re.compile('[,*")([\\]]'), ''), # remove unwanted chars + (re.compile('[~:+_ -]'), '.'), # replace illegal chars + (re.compile('[.]{2,}'), '.'), # multiple runs of '.' + (re.compile(r'\.$'), ''), # trailing '.' +) + +_NUMERIC_PREFIX = re.compile(r'(\d+(\.\d+)*)') + + +def _suggest_semantic_version(s): + """ + Try to suggest a semantic form for a version for which + _suggest_normalized_version couldn't come up with anything. + """ + result = s.strip().lower() + for pat, repl in _REPLACEMENTS: + result = pat.sub(repl, result) + if not result: + result = '0.0.0' + + # Now look for numeric prefix, and separate it out from + # the rest. + #import pdb; pdb.set_trace() + m = _NUMERIC_PREFIX.match(result) + if not m: + prefix = '0.0.0' + suffix = result + else: + prefix = m.groups()[0].split('.') + prefix = [int(i) for i in prefix] + while len(prefix) < 3: + prefix.append(0) + if len(prefix) == 3: + suffix = result[m.end():] + else: + suffix = '.'.join([str(i) for i in prefix[3:]]) + result[m.end():] + prefix = prefix[:3] + prefix = '.'.join([str(i) for i in prefix]) + suffix = suffix.strip() + if suffix: + #import pdb; pdb.set_trace() + # massage the suffix. + for pat, repl in _SUFFIX_REPLACEMENTS: + suffix = pat.sub(repl, suffix) + + if not suffix: + result = prefix + else: + sep = '-' if 'dev' in suffix else '+' + result = prefix + sep + suffix + if not is_semver(result): + result = None + return result + + +def _suggest_normalized_version(s): + """Suggest a normalized version close to the given version string. + + If you have a version string that isn't rational (i.e. NormalizedVersion + doesn't like it) then you might be able to get an equivalent (or close) + rational version from this function. + + This does a number of simple normalizations to the given string, based + on observation of versions currently in use on PyPI. Given a dump of + those version during PyCon 2009, 4287 of them: + - 2312 (53.93%) match NormalizedVersion without change + with the automatic suggestion + - 3474 (81.04%) match when using this suggestion method + + @param s {str} An irrational version string. + @returns A rational version string, or None, if couldn't determine one. + """ + try: + _normalized_key(s) + return s # already rational + except UnsupportedVersionError: + pass + + rs = s.lower() + + # part of this could use maketrans + for orig, repl in (('-alpha', 'a'), ('-beta', 'b'), ('alpha', 'a'), + ('beta', 'b'), ('rc', 'c'), ('-final', ''), + ('-pre', 'c'), + ('-release', ''), ('.release', ''), ('-stable', ''), + ('+', '.'), ('_', '.'), (' ', ''), ('.final', ''), + ('final', '')): + rs = rs.replace(orig, repl) + + # if something ends with dev or pre, we add a 0 + rs = re.sub(r"pre$", r"pre0", rs) + rs = re.sub(r"dev$", r"dev0", rs) + + # if we have something like "b-2" or "a.2" at the end of the + # version, that is probably beta, alpha, etc + # let's remove the dash or dot + rs = re.sub(r"([abc]|rc)[\-\.](\d+)$", r"\1\2", rs) + + # 1.0-dev-r371 -> 1.0.dev371 + # 0.1-dev-r79 -> 0.1.dev79 + rs = re.sub(r"[\-\.](dev)[\-\.]?r?(\d+)$", r".\1\2", rs) + + # Clean: 2.0.a.3, 2.0.b1, 0.9.0~c1 + rs = re.sub(r"[.~]?([abc])\.?", r"\1", rs) + + # Clean: v0.3, v1.0 + if rs.startswith('v'): + rs = rs[1:] + + # Clean leading '0's on numbers. + #TODO: unintended side-effect on, e.g., "2003.05.09" + # PyPI stats: 77 (~2%) better + rs = re.sub(r"\b0+(\d+)(?!\d)", r"\1", rs) + + # Clean a/b/c with no version. E.g. "1.0a" -> "1.0a0". Setuptools infers + # zero. + # PyPI stats: 245 (7.56%) better + rs = re.sub(r"(\d+[abc])$", r"\g<1>0", rs) + + # the 'dev-rNNN' tag is a dev tag + rs = re.sub(r"\.?(dev-r|dev\.r)\.?(\d+)$", r".dev\2", rs) + + # clean the - when used as a pre delimiter + rs = re.sub(r"-(a|b|c)(\d+)$", r"\1\2", rs) + + # a terminal "dev" or "devel" can be changed into ".dev0" + rs = re.sub(r"[\.\-](dev|devel)$", r".dev0", rs) + + # a terminal "dev" can be changed into ".dev0" + rs = re.sub(r"(?![\.\-])dev$", r".dev0", rs) + + # a terminal "final" or "stable" can be removed + rs = re.sub(r"(final|stable)$", "", rs) + + # The 'r' and the '-' tags are post release tags + # 0.4a1.r10 -> 0.4a1.post10 + # 0.9.33-17222 -> 0.9.33.post17222 + # 0.9.33-r17222 -> 0.9.33.post17222 + rs = re.sub(r"\.?(r|-|-r)\.?(\d+)$", r".post\2", rs) + + # Clean 'r' instead of 'dev' usage: + # 0.9.33+r17222 -> 0.9.33.dev17222 + # 1.0dev123 -> 1.0.dev123 + # 1.0.git123 -> 1.0.dev123 + # 1.0.bzr123 -> 1.0.dev123 + # 0.1a0dev.123 -> 0.1a0.dev123 + # PyPI stats: ~150 (~4%) better + rs = re.sub(r"\.?(dev|git|bzr)\.?(\d+)$", r".dev\2", rs) + + # Clean '.pre' (normalized from '-pre' above) instead of 'c' usage: + # 0.2.pre1 -> 0.2c1 + # 0.2-c1 -> 0.2c1 + # 1.0preview123 -> 1.0c123 + # PyPI stats: ~21 (0.62%) better + rs = re.sub(r"\.?(pre|preview|-c)(\d+)$", r"c\g<2>", rs) + + # Tcl/Tk uses "px" for their post release markers + rs = re.sub(r"p(\d+)$", r".post\1", rs) + + try: + _normalized_key(rs) + except UnsupportedVersionError: + rs = None + return rs + +# +# Legacy version processing (distribute-compatible) +# + +_VERSION_PART = re.compile(r'([a-z]+|\d+|[\.-])', re.I) +_VERSION_REPLACE = { + 'pre': 'c', + 'preview': 'c', + '-': 'final-', + 'rc': 'c', + 'dev': '@', + '': None, + '.': None, +} + + +def _legacy_key(s): + def get_parts(s): + result = [] + for p in _VERSION_PART.split(s.lower()): + p = _VERSION_REPLACE.get(p, p) + if p: + if '0' <= p[:1] <= '9': + p = p.zfill(8) + else: + p = '*' + p + result.append(p) + result.append('*final') + return result + + result = [] + for p in get_parts(s): + if p.startswith('*'): + if p < '*final': + while result and result[-1] == '*final-': + result.pop() + while result and result[-1] == '00000000': + result.pop() + result.append(p) + return tuple(result) + + +class LegacyVersion(Version): + def parse(self, s): + return _legacy_key(s) + + @property + def is_prerelease(self): + result = False + for x in self._parts: + if (isinstance(x, string_types) and x.startswith('*') and + x < '*final'): + result = True + break + return result + + +class LegacyMatcher(Matcher): + version_class = LegacyVersion + + _operators = dict(Matcher._operators) + _operators['~='] = '_match_compatible' + + numeric_re = re.compile(r'^(\d+(\.\d+)*)') + + def _match_compatible(self, version, constraint, prefix): + if version < constraint: + return False + m = self.numeric_re.match(str(constraint)) + if not m: + logger.warning('Cannot compute compatible match for version %s ' + ' and constraint %s', version, constraint) + return True + s = m.groups()[0] + if '.' in s: + s = s.rsplit('.', 1)[0] + return _match_prefix(version, s) + +# +# Semantic versioning +# + +_SEMVER_RE = re.compile(r'^(\d+)\.(\d+)\.(\d+)' + r'(-[a-z0-9]+(\.[a-z0-9-]+)*)?' + r'(\+[a-z0-9]+(\.[a-z0-9-]+)*)?$', re.I) + + +def is_semver(s): + return _SEMVER_RE.match(s) + + +def _semantic_key(s): + def make_tuple(s, absent): + if s is None: + result = (absent,) + else: + parts = s[1:].split('.') + # We can't compare ints and strings on Python 3, so fudge it + # by zero-filling numeric values so simulate a numeric comparison + result = tuple([p.zfill(8) if p.isdigit() else p for p in parts]) + return result + + m = is_semver(s) + if not m: + raise UnsupportedVersionError(s) + groups = m.groups() + major, minor, patch = [int(i) for i in groups[:3]] + # choose the '|' and '*' so that versions sort correctly + pre, build = make_tuple(groups[3], '|'), make_tuple(groups[5], '*') + return (major, minor, patch), pre, build + + +class SemanticVersion(Version): + def parse(self, s): + return _semantic_key(s) + + @property + def is_prerelease(self): + return self._parts[1][0] != '|' + + +class SemanticMatcher(Matcher): + version_class = SemanticVersion + + +class VersionScheme(object): + def __init__(self, key, matcher, suggester=None): + self.key = key + self.matcher = matcher + self.suggester = suggester + + def is_valid_version(self, s): + try: + self.matcher.version_class(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_matcher(self, s): + try: + self.matcher(s) + result = True + except UnsupportedVersionError: + result = False + return result + + def is_valid_constraint_list(self, s): + """ + Used for processing some metadata fields + """ + return self.is_valid_matcher('dummy_name (%s)' % s) + + def suggest(self, s): + if self.suggester is None: + result = None + else: + result = self.suggester(s) + return result + +_SCHEMES = { + 'normalized': VersionScheme(_normalized_key, NormalizedMatcher, + _suggest_normalized_version), + 'legacy': VersionScheme(_legacy_key, LegacyMatcher, lambda self, s: s), + 'semantic': VersionScheme(_semantic_key, SemanticMatcher, + _suggest_semantic_version), +} + +_SCHEMES['default'] = _SCHEMES['normalized'] + + +def get_scheme(name): + if name not in _SCHEMES: + raise ValueError('unknown scheme name: %r' % name) + return _SCHEMES[name] diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/w32.exe b/env/lib/python3.7/site-packages/pip/_vendor/distlib/w32.exe new file mode 100644 index 0000000000000000000000000000000000000000..732215a9d34ccb7b417d637a7646d9b843ecafa8 GIT binary patch literal 89088 zcmeFae|S?>wm*FGqitH!CO`{C3REl(SahnPNDYM`O{q#T7)Xdvz$<hz5gjb&0FD$| zPs=nt#$jgk-tk`NUb*PJIy$3wMg@OiORy=5PEkZ0P^;6cyPm2=Y8#~Xyq~pC(iU~@ z_dd`2ywCg3TS)e=wSTX@_S$Q$y;FJf9>F9Cf*Bu86NCeB>CeT#|L3nblC!40kR?2m z{>H@z3`^g*ct!B1Tk<#8{Ol(+x7?n8>n(TO@iQ_1pEl;#NO$D_^p5<p8@>6r|7^p? zD>5@P3KB)%InlPUc<U{5lb_$uJ2!U@!dIxT&CTYnHuoCtzCL#`-1%8w%`JjkymkHD zpYr&>Cg9H}+(GW%^wV2|ROUbGfyXTfOART)i?<!WISJD#7!6|#8G`TvV*Xu^z32+K zc6>T0?9%;4K}Zn{6fx`yPa}*$9C+R!7zI~72c&$InY+UdMGBkF3c`HyxD3K09`bzW z?_q;rO&5ec#{?noJ4vI19bbHBt~vx^h2FH$V8i|^#EsiUg#JboP3@w-(&Uf&%NK<8 zSJZ5{MZ852W)~s>WeT(LIf&1wKNqULLI)GN_(-E-D)X~ZK=1;t<%*guHMhdg`-(mb zHzDv1KBN9zR9?--O+N$ReOXAr81V9z!X5SJ5`=3<1^<8V|AP@&sr2}Qvp;hQT24iW zOHg|EiZd1ojV;oo#(r^ba2`^8T22{~_UQ@YMZp7O1R*2@?SerFE~TuJB_wDaYC0h8 zfONF1t%{=H`W`bdYp+>YBsg9Ty9ec3iy+O3xa}TIvPK#Q&udyx1MvwG0(#iaGC|N| zJ#3?<Y4YLRkU`54s9BYRjyISA>){9$tW;Y34lPnX=&>D4X~|k7c$TwEfOzs@Yh#Nz z`FV;`(w!E`sKg@`2E}bDY>ku^4XS@tV(WO*<eu67;0Clk;vRHp!Qf<+5w0B!*Y>g? zYH=KK#%%Yu1~&m>IlB^#2^syGG|2AB1(}4aOcaC%!)}%`I7AIC2(Ro3yW`GSttng^ z_xb=ECor!L{-PNO>_ulJ3%fm=O0X!s%)$GZ?~I94l-^KEAX0n$?4wGpr7&i4#~)OB zQD%2NrWUKtZuYT1Vnu}AeF`cSgx>Rkk@}Lg{WltgT76VeA2aic`cTnpXrt2WXmJkM z9%u<Rp-*9{$HQ)>Xm?McyDyZ28Ux7mpxy?mnmvzMMr-85vkRrJLaDRx>|I7je+cM+ zj{RJ(3Vrgke;W@#D!y%U%fQLtlPKTAzWtVuOQdXpwsy6eRjt^cZ%0D4bF7$F;f!th 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ð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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/w64.exe b/env/lib/python3.7/site-packages/pip/_vendor/distlib/w64.exe new file mode 100644 index 0000000000000000000000000000000000000000..c41bd0a011fd760ce20ba795d9e535e0d2c39876 GIT binary patch literal 99328 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 B=L-M; literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py b/env/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py new file mode 100644 index 0000000..7737223 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distlib/wheel.py @@ -0,0 +1,984 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2013-2017 Vinay Sajip. +# Licensed to the Python Software Foundation under a contributor agreement. +# See LICENSE.txt and CONTRIBUTORS.txt. +# +from __future__ import unicode_literals + +import base64 +import codecs +import datetime +import distutils.util +from email import message_from_file +import hashlib +import imp +import json +import logging +import os +import posixpath +import re +import shutil +import sys +import tempfile +import zipfile + +from . import __version__, DistlibException +from .compat import sysconfig, ZipFile, fsdecode, text_type, filter +from .database import InstalledDistribution +from .metadata import Metadata, METADATA_FILENAME, WHEEL_METADATA_FILENAME +from .util import (FileOperator, convert_path, CSVReader, CSVWriter, Cache, + cached_property, get_cache_base, read_exports, tempdir) +from .version import NormalizedVersion, UnsupportedVersionError + +logger = logging.getLogger(__name__) + +cache = None # created when needed + +if hasattr(sys, 'pypy_version_info'): # pragma: no cover + IMP_PREFIX = 'pp' +elif sys.platform.startswith('java'): # pragma: no cover + IMP_PREFIX = 'jy' +elif sys.platform == 'cli': # pragma: no cover + IMP_PREFIX = 'ip' +else: + IMP_PREFIX = 'cp' + +VER_SUFFIX = sysconfig.get_config_var('py_version_nodot') +if not VER_SUFFIX: # pragma: no cover + VER_SUFFIX = '%s%s' % sys.version_info[:2] +PYVER = 'py' + VER_SUFFIX +IMPVER = IMP_PREFIX + VER_SUFFIX + +ARCH = distutils.util.get_platform().replace('-', '_').replace('.', '_') + +ABI = sysconfig.get_config_var('SOABI') +if ABI and ABI.startswith('cpython-'): + ABI = ABI.replace('cpython-', 'cp') +else: + def _derive_abi(): + parts = ['cp', VER_SUFFIX] + if sysconfig.get_config_var('Py_DEBUG'): + parts.append('d') + if sysconfig.get_config_var('WITH_PYMALLOC'): + parts.append('m') + if sysconfig.get_config_var('Py_UNICODE_SIZE') == 4: + parts.append('u') + return ''.join(parts) + ABI = _derive_abi() + del _derive_abi + +FILENAME_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))? +-(?P<py>\w+\d+(\.\w+\d+)*) +-(?P<bi>\w+) +-(?P<ar>\w+(\.\w+)*) +\.whl$ +''', re.IGNORECASE | re.VERBOSE) + +NAME_VERSION_RE = re.compile(r''' +(?P<nm>[^-]+) +-(?P<vn>\d+[^-]*) +(-(?P<bn>\d+[^-]*))?$ +''', re.IGNORECASE | re.VERBOSE) + +SHEBANG_RE = re.compile(br'\s*#![^\r\n]*') +SHEBANG_DETAIL_RE = re.compile(br'^(\s*#!("[^"]+"|\S+))\s+(.*)$') +SHEBANG_PYTHON = b'#!python' +SHEBANG_PYTHONW = b'#!pythonw' + +if os.sep == '/': + to_posix = lambda o: o +else: + to_posix = lambda o: o.replace(os.sep, '/') + + +class Mounter(object): + def __init__(self): + self.impure_wheels = {} + self.libs = {} + + def add(self, pathname, extensions): + self.impure_wheels[pathname] = extensions + self.libs.update(extensions) + + def remove(self, pathname): + extensions = self.impure_wheels.pop(pathname) + for k, v in extensions: + if k in self.libs: + del self.libs[k] + + def find_module(self, fullname, path=None): + if fullname in self.libs: + result = self + else: + result = None + return result + + def load_module(self, fullname): + if fullname in sys.modules: + result = sys.modules[fullname] + else: + if fullname not in self.libs: + raise ImportError('unable to find extension for %s' % fullname) + result = imp.load_dynamic(fullname, self.libs[fullname]) + result.__loader__ = self + parts = fullname.rsplit('.', 1) + if len(parts) > 1: + result.__package__ = parts[0] + return result + +_hook = Mounter() + + +class Wheel(object): + """ + Class to build and install from Wheel files (PEP 427). + """ + + wheel_version = (1, 1) + hash_kind = 'sha256' + + def __init__(self, filename=None, sign=False, verify=False): + """ + Initialise an instance using a (valid) filename. + """ + self.sign = sign + self.should_verify = verify + self.buildver = '' + self.pyver = [PYVER] + self.abi = ['none'] + self.arch = ['any'] + self.dirname = os.getcwd() + if filename is None: + self.name = 'dummy' + self.version = '0.1' + self._filename = self.filename + else: + m = NAME_VERSION_RE.match(filename) + if m: + info = m.groupdict('') + self.name = info['nm'] + # Reinstate the local version separator + self.version = info['vn'].replace('_', '-') + self.buildver = info['bn'] + self._filename = self.filename + else: + dirname, filename = os.path.split(filename) + m = FILENAME_RE.match(filename) + if not m: + raise DistlibException('Invalid name or ' + 'filename: %r' % filename) + if dirname: + self.dirname = os.path.abspath(dirname) + self._filename = filename + info = m.groupdict('') + self.name = info['nm'] + self.version = info['vn'] + self.buildver = info['bn'] + self.pyver = info['py'].split('.') + self.abi = info['bi'].split('.') + self.arch = info['ar'].split('.') + + @property + def filename(self): + """ + Build and return a filename from the various components. + """ + if self.buildver: + buildver = '-' + self.buildver + else: + buildver = '' + pyver = '.'.join(self.pyver) + abi = '.'.join(self.abi) + arch = '.'.join(self.arch) + # replace - with _ as a local version separator + version = self.version.replace('-', '_') + return '%s-%s%s-%s-%s-%s.whl' % (self.name, version, buildver, + pyver, abi, arch) + + @property + def exists(self): + path = os.path.join(self.dirname, self.filename) + return os.path.isfile(path) + + @property + def tags(self): + for pyver in self.pyver: + for abi in self.abi: + for arch in self.arch: + yield pyver, abi, arch + + @cached_property + def metadata(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + wrapper = codecs.getreader('utf-8') + with ZipFile(pathname, 'r') as zf: + wheel_metadata = self.get_wheel_metadata(zf) + wv = wheel_metadata['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if file_version < (1, 1): + fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME, 'METADATA'] + else: + fns = [WHEEL_METADATA_FILENAME, METADATA_FILENAME] + result = None + for fn in fns: + try: + metadata_filename = posixpath.join(info_dir, fn) + with zf.open(metadata_filename) as bf: + wf = wrapper(bf) + result = Metadata(fileobj=wf) + if result: + break + except KeyError: + pass + if not result: + raise ValueError('Invalid wheel, because metadata is ' + 'missing: looked in %s' % ', '.join(fns)) + return result + + def get_wheel_metadata(self, zf): + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + metadata_filename = posixpath.join(info_dir, 'WHEEL') + with zf.open(metadata_filename) as bf: + wf = codecs.getreader('utf-8')(bf) + message = message_from_file(wf) + return dict(message) + + @cached_property + def info(self): + pathname = os.path.join(self.dirname, self.filename) + with ZipFile(pathname, 'r') as zf: + result = self.get_wheel_metadata(zf) + return result + + def process_shebang(self, data): + m = SHEBANG_RE.match(data) + if m: + end = m.end() + shebang, data_after_shebang = data[:end], data[end:] + # Preserve any arguments after the interpreter + if b'pythonw' in shebang.lower(): + shebang_python = SHEBANG_PYTHONW + else: + shebang_python = SHEBANG_PYTHON + m = SHEBANG_DETAIL_RE.match(shebang) + if m: + args = b' ' + m.groups()[-1] + else: + args = b'' + shebang = shebang_python + args + data = shebang + data_after_shebang + else: + cr = data.find(b'\r') + lf = data.find(b'\n') + if cr < 0 or cr > lf: + term = b'\n' + else: + if data[cr:cr + 2] == b'\r\n': + term = b'\r\n' + else: + term = b'\r' + data = SHEBANG_PYTHON + term + data + return data + + def get_hash(self, data, hash_kind=None): + if hash_kind is None: + hash_kind = self.hash_kind + try: + hasher = getattr(hashlib, hash_kind) + except AttributeError: + raise DistlibException('Unsupported hash algorithm: %r' % hash_kind) + result = hasher(data).digest() + result = base64.urlsafe_b64encode(result).rstrip(b'=').decode('ascii') + return hash_kind, result + + def write_record(self, records, record_path, base): + records = list(records) # make a copy for sorting + p = to_posix(os.path.relpath(record_path, base)) + records.append((p, '', '')) + records.sort() + with CSVWriter(record_path) as writer: + for row in records: + writer.writerow(row) + + def write_records(self, info, libdir, archive_paths): + records = [] + distinfo, info_dir = info + hasher = getattr(hashlib, self.hash_kind) + for ap, p in archive_paths: + with open(p, 'rb') as f: + data = f.read() + digest = '%s=%s' % self.get_hash(data) + size = os.path.getsize(p) + records.append((ap, digest, size)) + + p = os.path.join(distinfo, 'RECORD') + self.write_record(records, p, libdir) + ap = to_posix(os.path.join(info_dir, 'RECORD')) + archive_paths.append((ap, p)) + + def build_zip(self, pathname, archive_paths): + with ZipFile(pathname, 'w', zipfile.ZIP_DEFLATED) as zf: + for ap, p in archive_paths: + logger.debug('Wrote %s to %s in wheel', p, ap) + zf.write(p, ap) + + def build(self, paths, tags=None, wheel_version=None): + """ + Build a wheel from files in specified paths, and use any specified tags + when determining the name of the wheel. + """ + if tags is None: + tags = {} + + libkey = list(filter(lambda o: o in paths, ('purelib', 'platlib')))[0] + if libkey == 'platlib': + is_pure = 'false' + default_pyver = [IMPVER] + default_abi = [ABI] + default_arch = [ARCH] + else: + is_pure = 'true' + default_pyver = [PYVER] + default_abi = ['none'] + default_arch = ['any'] + + self.pyver = tags.get('pyver', default_pyver) + self.abi = tags.get('abi', default_abi) + self.arch = tags.get('arch', default_arch) + + libdir = paths[libkey] + + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + archive_paths = [] + + # First, stuff which is not in site-packages + for key in ('data', 'headers', 'scripts'): + if key not in paths: + continue + path = paths[key] + if os.path.isdir(path): + for root, dirs, files in os.walk(path): + for fn in files: + p = fsdecode(os.path.join(root, fn)) + rp = os.path.relpath(p, path) + ap = to_posix(os.path.join(data_dir, key, rp)) + archive_paths.append((ap, p)) + if key == 'scripts' and not p.endswith('.exe'): + with open(p, 'rb') as f: + data = f.read() + data = self.process_shebang(data) + with open(p, 'wb') as f: + f.write(data) + + # Now, stuff which is in site-packages, other than the + # distinfo stuff. + path = libdir + distinfo = None + for root, dirs, files in os.walk(path): + if root == path: + # At the top level only, save distinfo for later + # and skip it for now + for i, dn in enumerate(dirs): + dn = fsdecode(dn) + if dn.endswith('.dist-info'): + distinfo = os.path.join(root, dn) + del dirs[i] + break + assert distinfo, '.dist-info directory expected, not found' + + for fn in files: + # comment out next suite to leave .pyc files in + if fsdecode(fn).endswith(('.pyc', '.pyo')): + continue + p = os.path.join(root, fn) + rp = to_posix(os.path.relpath(p, path)) + archive_paths.append((rp, p)) + + # Now distinfo. Assumed to be flat, i.e. os.listdir is enough. + files = os.listdir(distinfo) + for fn in files: + if fn not in ('RECORD', 'INSTALLER', 'SHARED', 'WHEEL'): + p = fsdecode(os.path.join(distinfo, fn)) + ap = to_posix(os.path.join(info_dir, fn)) + archive_paths.append((ap, p)) + + wheel_metadata = [ + 'Wheel-Version: %d.%d' % (wheel_version or self.wheel_version), + 'Generator: distlib %s' % __version__, + 'Root-Is-Purelib: %s' % is_pure, + ] + for pyver, abi, arch in self.tags: + wheel_metadata.append('Tag: %s-%s-%s' % (pyver, abi, arch)) + p = os.path.join(distinfo, 'WHEEL') + with open(p, 'w') as f: + f.write('\n'.join(wheel_metadata)) + ap = to_posix(os.path.join(info_dir, 'WHEEL')) + archive_paths.append((ap, p)) + + # Now, at last, RECORD. + # Paths in here are archive paths - nothing else makes sense. + self.write_records((distinfo, info_dir), libdir, archive_paths) + # Now, ready to build the zip file + pathname = os.path.join(self.dirname, self.filename) + self.build_zip(pathname, archive_paths) + return pathname + + def install(self, paths, maker, **kwargs): + """ + Install a wheel to the specified paths. If kwarg ``warner`` is + specified, it should be a callable, which will be called with two + tuples indicating the wheel version of this software and the wheel + version in the file, if there is a discrepancy in the versions. + This can be used to issue any warnings to raise any exceptions. + If kwarg ``lib_only`` is True, only the purelib/platlib files are + installed, and the headers, scripts, data and dist-info metadata are + not written. + + The return value is a :class:`InstalledDistribution` instance unless + ``options.lib_only`` is True, in which case the return value is ``None``. + """ + + dry_run = maker.dry_run + warner = kwargs.get('warner') + lib_only = kwargs.get('lib_only', False) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + if (file_version != self.wheel_version) and warner: + warner(self.wheel_version, file_version) + + if message['Root-Is-Purelib'] == 'true': + libdir = paths['purelib'] + else: + libdir = paths['platlib'] + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + data_pfx = posixpath.join(data_dir, '') + info_pfx = posixpath.join(info_dir, '') + script_pfx = posixpath.join(data_dir, 'scripts', '') + + # make a new instance rather than a copy of maker's, + # as we mutate it + fileop = FileOperator(dry_run=dry_run) + fileop.record = True # so we can rollback if needed + + bc = not sys.dont_write_bytecode # Double negatives. Lovely! + + outfiles = [] # for RECORD writing + + # for script copying/shebang processing + workdir = tempfile.mkdtemp() + # set target dir later + # we default add_launchers to False, as the + # Python Launcher should be used instead + maker.source_dir = workdir + maker.target_dir = None + try: + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + if lib_only and u_arcname.startswith((info_pfx, data_pfx)): + logger.debug('lib_only: skipping %s', u_arcname) + continue + is_script = (u_arcname.startswith(script_pfx) + and not u_arcname.endswith('.exe')) + + if u_arcname.startswith(data_pfx): + _, where, rp = u_arcname.split('/', 2) + outfile = os.path.join(paths[where], convert_path(rp)) + else: + # meant for site-packages. + if u_arcname in (wheel_metadata_name, record_name): + continue + outfile = os.path.join(libdir, convert_path(u_arcname)) + if not is_script: + with zf.open(arcname) as bf: + fileop.copy_stream(bf, outfile) + outfiles.append(outfile) + # Double check the digest of the written file + if not dry_run and row[1]: + with open(outfile, 'rb') as bf: + data = bf.read() + _, newdigest = self.get_hash(data, kind) + if newdigest != digest: + raise DistlibException('digest mismatch ' + 'on write for ' + '%s' % outfile) + if bc and outfile.endswith('.py'): + try: + pyc = fileop.byte_compile(outfile) + outfiles.append(pyc) + except Exception: + # Don't give up if byte-compilation fails, + # but log it and perhaps warn the user + logger.warning('Byte-compilation failed', + exc_info=True) + else: + fn = os.path.basename(convert_path(arcname)) + workname = os.path.join(workdir, fn) + with zf.open(arcname) as bf: + fileop.copy_stream(bf, workname) + + dn, fn = os.path.split(outfile) + maker.target_dir = dn + filenames = maker.make(fn) + fileop.set_executable_mode(filenames) + outfiles.extend(filenames) + + if lib_only: + logger.debug('lib_only: returning None') + dist = None + else: + # Generate scripts + + # Try to get pydist.json so we can see if there are + # any commands to generate. If this fails (e.g. because + # of a legacy wheel), log a warning but don't give up. + commands = None + file_version = self.info['Wheel-Version'] + if file_version == '1.0': + # Use legacy info + ep = posixpath.join(info_dir, 'entry_points.txt') + try: + with zf.open(ep) as bwf: + epdata = read_exports(bwf) + commands = {} + for key in ('console', 'gui'): + k = '%s_scripts' % key + if k in epdata: + commands['wrap_%s' % key] = d = {} + for v in epdata[k].values(): + s = '%s:%s' % (v.prefix, v.suffix) + if v.flags: + s += ' %s' % v.flags + d[v.name] = s + except Exception: + logger.warning('Unable to read legacy script ' + 'metadata, so cannot generate ' + 'scripts') + else: + try: + with zf.open(metadata_name) as bwf: + wf = wrapper(bwf) + commands = json.load(wf).get('extensions') + if commands: + commands = commands.get('python.commands') + except Exception: + logger.warning('Unable to read JSON metadata, so ' + 'cannot generate scripts') + if commands: + console_scripts = commands.get('wrap_console', {}) + gui_scripts = commands.get('wrap_gui', {}) + if console_scripts or gui_scripts: + script_dir = paths.get('scripts', '') + if not os.path.isdir(script_dir): + raise ValueError('Valid script path not ' + 'specified') + maker.target_dir = script_dir + for k, v in console_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script) + fileop.set_executable_mode(filenames) + + if gui_scripts: + options = {'gui': True } + for k, v in gui_scripts.items(): + script = '%s = %s' % (k, v) + filenames = maker.make(script, options) + fileop.set_executable_mode(filenames) + + p = os.path.join(libdir, info_dir) + dist = InstalledDistribution(p) + + # Write SHARED + paths = dict(paths) # don't change passed in dict + del paths['purelib'] + del paths['platlib'] + paths['lib'] = libdir + p = dist.write_shared_locations(paths, dry_run) + if p: + outfiles.append(p) + + # Write RECORD + dist.write_installed_files(outfiles, paths['prefix'], + dry_run) + return dist + except Exception: # pragma: no cover + logger.exception('installation failed.') + fileop.rollback() + raise + finally: + shutil.rmtree(workdir) + + def _get_dylib_cache(self): + global cache + if cache is None: + # Use native string to avoid issues on 2.x: see Python #20140. + base = os.path.join(get_cache_base(), str('dylib-cache'), + sys.version[:3]) + cache = Cache(base) + return cache + + def _get_extensions(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + arcname = posixpath.join(info_dir, 'EXTENSIONS') + wrapper = codecs.getreader('utf-8') + result = [] + with ZipFile(pathname, 'r') as zf: + try: + with zf.open(arcname) as bf: + wf = wrapper(bf) + extensions = json.load(wf) + cache = self._get_dylib_cache() + prefix = cache.prefix_to_dir(pathname) + cache_base = os.path.join(cache.base, prefix) + if not os.path.isdir(cache_base): + os.makedirs(cache_base) + for name, relpath in extensions.items(): + dest = os.path.join(cache_base, convert_path(relpath)) + if not os.path.exists(dest): + extract = True + else: + file_time = os.stat(dest).st_mtime + file_time = datetime.datetime.fromtimestamp(file_time) + info = zf.getinfo(relpath) + wheel_time = datetime.datetime(*info.date_time) + extract = wheel_time > file_time + if extract: + zf.extract(relpath, cache_base) + result.append((name, dest)) + except KeyError: + pass + return result + + def is_compatible(self): + """ + Determine if a wheel is compatible with the running system. + """ + return is_compatible(self) + + def is_mountable(self): + """ + Determine if a wheel is asserted as mountable by its metadata. + """ + return True # for now - metadata details TBD + + def mount(self, append=False): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if not self.is_compatible(): + msg = 'Wheel %s not compatible with this Python.' % pathname + raise DistlibException(msg) + if not self.is_mountable(): + msg = 'Wheel %s is marked as not mountable.' % pathname + raise DistlibException(msg) + if pathname in sys.path: + logger.debug('%s already in path', pathname) + else: + if append: + sys.path.append(pathname) + else: + sys.path.insert(0, pathname) + extensions = self._get_extensions() + if extensions: + if _hook not in sys.meta_path: + sys.meta_path.append(_hook) + _hook.add(pathname, extensions) + + def unmount(self): + pathname = os.path.abspath(os.path.join(self.dirname, self.filename)) + if pathname not in sys.path: + logger.debug('%s not in path', pathname) + else: + sys.path.remove(pathname) + if pathname in _hook.impure_wheels: + _hook.remove(pathname) + if not _hook.impure_wheels: + if _hook in sys.meta_path: + sys.meta_path.remove(_hook) + + def verify(self): + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + data_dir = '%s.data' % name_ver + info_dir = '%s.dist-info' % name_ver + + metadata_name = posixpath.join(info_dir, METADATA_FILENAME) + wheel_metadata_name = posixpath.join(info_dir, 'WHEEL') + record_name = posixpath.join(info_dir, 'RECORD') + + wrapper = codecs.getreader('utf-8') + + with ZipFile(pathname, 'r') as zf: + with zf.open(wheel_metadata_name) as bwf: + wf = wrapper(bwf) + message = message_from_file(wf) + wv = message['Wheel-Version'].split('.', 1) + file_version = tuple([int(i) for i in wv]) + # TODO version verification + + records = {} + with zf.open(record_name) as bf: + with CSVReader(stream=bf) as reader: + for row in reader: + p = row[0] + records[p] = row + + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + + # The signature file won't be in RECORD, + # and we don't currently don't do anything with it + if u_arcname.endswith('/RECORD.jws'): + continue + row = records[u_arcname] + if row[2] and str(zinfo.file_size) != row[2]: + raise DistlibException('size mismatch for ' + '%s' % u_arcname) + if row[1]: + kind, value = row[1].split('=', 1) + with zf.open(arcname) as bf: + data = bf.read() + _, digest = self.get_hash(data, kind) + if digest != value: + raise DistlibException('digest mismatch for ' + '%s' % arcname) + + def update(self, modifier, dest_dir=None, **kwargs): + """ + Update the contents of a wheel in a generic way. The modifier should + be a callable which expects a dictionary argument: its keys are + archive-entry paths, and its values are absolute filesystem paths + where the contents the corresponding archive entries can be found. The + modifier is free to change the contents of the files pointed to, add + new entries and remove entries, before returning. This method will + extract the entire contents of the wheel to a temporary location, call + the modifier, and then use the passed (and possibly updated) + dictionary to write a new wheel. If ``dest_dir`` is specified, the new + wheel is written there -- otherwise, the original wheel is overwritten. + + The modifier should return True if it updated the wheel, else False. + This method returns the same value the modifier returns. + """ + + def get_version(path_map, info_dir): + version = path = None + key = '%s/%s' % (info_dir, METADATA_FILENAME) + if key not in path_map: + key = '%s/PKG-INFO' % info_dir + if key in path_map: + path = path_map[key] + version = Metadata(path=path).version + return version, path + + def update_version(version, path): + updated = None + try: + v = NormalizedVersion(version) + i = version.find('-') + if i < 0: + updated = '%s+1' % version + else: + parts = [int(s) for s in version[i + 1:].split('.')] + parts[-1] += 1 + updated = '%s+%s' % (version[:i], + '.'.join(str(i) for i in parts)) + except UnsupportedVersionError: + logger.debug('Cannot update non-compliant (PEP-440) ' + 'version %r', version) + if updated: + md = Metadata(path=path) + md.version = updated + legacy = not path.endswith(METADATA_FILENAME) + md.write(path=path, legacy=legacy) + logger.debug('Version updated from %r to %r', version, + updated) + + pathname = os.path.join(self.dirname, self.filename) + name_ver = '%s-%s' % (self.name, self.version) + info_dir = '%s.dist-info' % name_ver + record_name = posixpath.join(info_dir, 'RECORD') + with tempdir() as workdir: + with ZipFile(pathname, 'r') as zf: + path_map = {} + for zinfo in zf.infolist(): + arcname = zinfo.filename + if isinstance(arcname, text_type): + u_arcname = arcname + else: + u_arcname = arcname.decode('utf-8') + if u_arcname == record_name: + continue + if '..' in u_arcname: + raise DistlibException('invalid entry in ' + 'wheel: %r' % u_arcname) + zf.extract(zinfo, workdir) + path = os.path.join(workdir, convert_path(u_arcname)) + path_map[u_arcname] = path + + # Remember the version. + original_version, _ = get_version(path_map, info_dir) + # Files extracted. Call the modifier. + modified = modifier(path_map, **kwargs) + if modified: + # Something changed - need to build a new wheel. + current_version, path = get_version(path_map, info_dir) + if current_version and (current_version == original_version): + # Add or update local version to signify changes. + update_version(current_version, path) + # Decide where the new wheel goes. + if dest_dir is None: + fd, newpath = tempfile.mkstemp(suffix='.whl', + prefix='wheel-update-', + dir=workdir) + os.close(fd) + else: + if not os.path.isdir(dest_dir): + raise DistlibException('Not a directory: %r' % dest_dir) + newpath = os.path.join(dest_dir, self.filename) + archive_paths = list(path_map.items()) + distinfo = os.path.join(workdir, info_dir) + info = distinfo, info_dir + self.write_records(info, workdir, archive_paths) + self.build_zip(newpath, archive_paths) + if dest_dir is None: + shutil.copyfile(newpath, pathname) + return modified + +def compatible_tags(): + """ + Return (pyver, abi, arch) tuples compatible with this Python. + """ + versions = [VER_SUFFIX] + major = VER_SUFFIX[0] + for minor in range(sys.version_info[1] - 1, - 1, -1): + versions.append(''.join([major, str(minor)])) + + abis = [] + for suffix, _, _ in imp.get_suffixes(): + if suffix.startswith('.abi'): + abis.append(suffix.split('.', 2)[1]) + abis.sort() + if ABI != 'none': + abis.insert(0, ABI) + abis.append('none') + result = [] + + arches = [ARCH] + if sys.platform == 'darwin': + m = re.match(r'(\w+)_(\d+)_(\d+)_(\w+)$', ARCH) + if m: + name, major, minor, arch = m.groups() + minor = int(minor) + matches = [arch] + if arch in ('i386', 'ppc'): + matches.append('fat') + if arch in ('i386', 'ppc', 'x86_64'): + matches.append('fat3') + if arch in ('ppc64', 'x86_64'): + matches.append('fat64') + if arch in ('i386', 'x86_64'): + matches.append('intel') + if arch in ('i386', 'x86_64', 'intel', 'ppc', 'ppc64'): + matches.append('universal') + while minor >= 0: + for match in matches: + s = '%s_%s_%s_%s' % (name, major, minor, match) + if s != ARCH: # already there + arches.append(s) + minor -= 1 + + # Most specific - our Python version, ABI and arch + for abi in abis: + for arch in arches: + result.append((''.join((IMP_PREFIX, versions[0])), abi, arch)) + + # where no ABI / arch dependency, but IMP_PREFIX dependency + for i, version in enumerate(versions): + result.append((''.join((IMP_PREFIX, version)), 'none', 'any')) + if i == 0: + result.append((''.join((IMP_PREFIX, version[0])), 'none', 'any')) + + # no IMP_PREFIX, ABI or arch dependency + for i, version in enumerate(versions): + result.append((''.join(('py', version)), 'none', 'any')) + if i == 0: + result.append((''.join(('py', version[0])), 'none', 'any')) + return set(result) + + +COMPATIBLE_TAGS = compatible_tags() + +del compatible_tags + + +def is_compatible(wheel, tags=None): + if not isinstance(wheel, Wheel): + wheel = Wheel(wheel) # assume it's a filename + result = False + if tags is None: + tags = COMPATIBLE_TAGS + for ver, abi, arch in tags: + if ver in wheel.pyver and abi in wheel.abi and arch in wheel.arch: + result = True + break + return result diff --git a/env/lib/python3.7/site-packages/pip/_vendor/distro.py b/env/lib/python3.7/site-packages/pip/_vendor/distro.py new file mode 100644 index 0000000..aa4defc --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/distro.py @@ -0,0 +1,1197 @@ +# Copyright 2015,2016,2017 Nir Cohen +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" +The ``distro`` package (``distro`` stands for Linux Distribution) provides +information about the Linux distribution it runs on, such as a reliable +machine-readable distro ID, or version information. + +It is a renewed alternative implementation for Python's original +:py:func:`platform.linux_distribution` function, but it provides much more +functionality. An alternative implementation became necessary because Python +3.5 deprecated this function, and Python 3.7 is expected to remove it +altogether. Its predecessor function :py:func:`platform.dist` was already +deprecated since Python 2.6 and is also expected to be removed in Python 3.7. +Still, there are many cases in which access to OS distribution information +is needed. See `Python issue 1322 <https://bugs.python.org/issue1322>`_ for +more information. +""" + +import os +import re +import sys +import json +import shlex +import logging +import argparse +import subprocess + + +_UNIXCONFDIR = os.environ.get('UNIXCONFDIR', '/etc') +_OS_RELEASE_BASENAME = 'os-release' + +#: Translation table for normalizing the "ID" attribute defined in os-release +#: files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as defined in the os-release file, translated to lower case, +#: with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_OS_ID = {} + +#: Translation table for normalizing the "Distributor ID" attribute returned by +#: the lsb_release command, for use by the :func:`distro.id` method. +#: +#: * Key: Value as returned by the lsb_release command, translated to lower +#: case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_LSB_ID = { + 'enterpriseenterprise': 'oracle', # Oracle Enterprise Linux + 'redhatenterpriseworkstation': 'rhel', # RHEL 6, 7 Workstation + 'redhatenterpriseserver': 'rhel', # RHEL 6, 7 Server +} + +#: Translation table for normalizing the distro ID derived from the file name +#: of distro release files, for use by the :func:`distro.id` method. +#: +#: * Key: Value as derived from the file name of a distro release file, +#: translated to lower case, with blanks translated to underscores. +#: +#: * Value: Normalized value. +NORMALIZED_DISTRO_ID = { + 'redhat': 'rhel', # RHEL 6.x, 7.x +} + +# Pattern for content of distro release file (reversed) +_DISTRO_RELEASE_CONTENT_REVERSED_PATTERN = re.compile( + r'(?:[^)]*\)(.*)\()? *(?:STL )?([\d.+\-a-z]*\d) *(?:esaeler *)?(.+)') + +# Pattern for base file name of distro release file +_DISTRO_RELEASE_BASENAME_PATTERN = re.compile( + r'(\w+)[-_](release|version)$') + +# Base file names to be ignored when searching for distro release file +_DISTRO_RELEASE_IGNORE_BASENAMES = ( + 'debian_version', + 'lsb-release', + 'oem-release', + _OS_RELEASE_BASENAME, + 'system-release' +) + + +def linux_distribution(full_distribution_name=True): + """ + Return information about the current OS distribution as a tuple + ``(id_name, version, codename)`` with items as follows: + + * ``id_name``: If *full_distribution_name* is false, the result of + :func:`distro.id`. Otherwise, the result of :func:`distro.name`. + + * ``version``: The result of :func:`distro.version`. + + * ``codename``: The result of :func:`distro.codename`. + + The interface of this function is compatible with the original + :py:func:`platform.linux_distribution` function, supporting a subset of + its parameters. + + The data it returns may not exactly be the same, because it uses more data + sources than the original function, and that may lead to different data if + the OS distribution is not consistent across multiple data sources it + provides (there are indeed such distributions ...). + + Another reason for differences is the fact that the :func:`distro.id` + method normalizes the distro ID string to a reliable machine-readable value + for a number of popular OS distributions. + """ + return _distro.linux_distribution(full_distribution_name) + + +def id(): + """ + Return the distro ID of the current distribution, as a + machine-readable string. + + For a number of OS distributions, the returned distro ID value is + *reliable*, in the sense that it is documented and that it does not change + across releases of the distribution. + + This package maintains the following reliable distro ID values: + + ============== ========================================= + Distro ID Distribution + ============== ========================================= + "ubuntu" Ubuntu + "debian" Debian + "rhel" RedHat Enterprise Linux + "centos" CentOS + "fedora" Fedora + "sles" SUSE Linux Enterprise Server + "opensuse" openSUSE + "amazon" Amazon Linux + "arch" Arch Linux + "cloudlinux" CloudLinux OS + "exherbo" Exherbo Linux + "gentoo" GenToo Linux + "ibm_powerkvm" IBM PowerKVM + "kvmibm" KVM for IBM z Systems + "linuxmint" Linux Mint + "mageia" Mageia + "mandriva" Mandriva Linux + "parallels" Parallels + "pidora" Pidora + "raspbian" Raspbian + "oracle" Oracle Linux (and Oracle Enterprise Linux) + "scientific" Scientific Linux + "slackware" Slackware + "xenserver" XenServer + "openbsd" OpenBSD + "netbsd" NetBSD + "freebsd" FreeBSD + ============== ========================================= + + If you have a need to get distros for reliable IDs added into this set, + or if you find that the :func:`distro.id` function returns a different + distro ID for one of the listed distros, please create an issue in the + `distro issue tracker`_. + + **Lookup hierarchy and transformations:** + + First, the ID is obtained from the following sources, in the specified + order. The first available and non-empty value is used: + + * the value of the "ID" attribute of the os-release file, + + * the value of the "Distributor ID" attribute returned by the lsb_release + command, + + * the first part of the file name of the distro release file, + + The so determined ID value then passes the following transformations, + before it is returned by this method: + + * it is translated to lower case, + + * blanks (which should not be there anyway) are translated to underscores, + + * a normalization of the ID is performed, based upon + `normalization tables`_. The purpose of this normalization is to ensure + that the ID is as reliable as possible, even across incompatible changes + in the OS distributions. A common reason for an incompatible change is + the addition of an os-release file, or the addition of the lsb_release + command, with ID values that differ from what was previously determined + from the distro release file name. + """ + return _distro.id() + + +def name(pretty=False): + """ + Return the name of the current OS distribution, as a human-readable + string. + + If *pretty* is false, the name is returned without version or codename. + (e.g. "CentOS Linux") + + If *pretty* is true, the version and codename are appended. + (e.g. "CentOS Linux 7.1.1503 (Core)") + + **Lookup hierarchy:** + + The name is obtained from the following sources, in the specified order. + The first available and non-empty value is used: + + * If *pretty* is false: + + - the value of the "NAME" attribute of the os-release file, + + - the value of the "Distributor ID" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file. + + * If *pretty* is true: + + - the value of the "PRETTY_NAME" attribute of the os-release file, + + - the value of the "Description" attribute returned by the lsb_release + command, + + - the value of the "<name>" field of the distro release file, appended + with the value of the pretty version ("<version_id>" and "<codename>" + fields) of the distro release file, if available. + """ + return _distro.name(pretty) + + +def version(pretty=False, best=False): + """ + Return the version of the current OS distribution, as a human-readable + string. + + If *pretty* is false, the version is returned without codename (e.g. + "7.0"). + + If *pretty* is true, the codename in parenthesis is appended, if the + codename is non-empty (e.g. "7.0 (Maipo)"). + + Some distributions provide version numbers with different precisions in + the different sources of distribution information. Examining the different + sources in a fixed priority order does not always yield the most precise + version (e.g. for Debian 8.2, or CentOS 7.1). + + The *best* parameter can be used to control the approach for the returned + version: + + If *best* is false, the first non-empty version number in priority order of + the examined sources is returned. + + If *best* is true, the most precise version number out of all examined + sources is returned. + + **Lookup hierarchy:** + + In all cases, the version number is obtained from the following sources. + If *best* is false, this order represents the priority order: + + * the value of the "VERSION_ID" attribute of the os-release file, + * the value of the "Release" attribute returned by the lsb_release + command, + * the version number parsed from the "<version_id>" field of the first line + of the distro release file, + * the version number parsed from the "PRETTY_NAME" attribute of the + os-release file, if it follows the format of the distro release files. + * the version number parsed from the "Description" attribute returned by + the lsb_release command, if it follows the format of the distro release + files. + """ + return _distro.version(pretty, best) + + +def version_parts(best=False): + """ + Return the version of the current OS distribution as a tuple + ``(major, minor, build_number)`` with items as follows: + + * ``major``: The result of :func:`distro.major_version`. + + * ``minor``: The result of :func:`distro.minor_version`. + + * ``build_number``: The result of :func:`distro.build_number`. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.version_parts(best) + + +def major_version(best=False): + """ + Return the major version of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The major version is the first + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.major_version(best) + + +def minor_version(best=False): + """ + Return the minor version of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The minor version is the second + part of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.minor_version(best) + + +def build_number(best=False): + """ + Return the build number of the current OS distribution, as a string, + if provided. + Otherwise, the empty string is returned. The build number is the third part + of the dot-separated version string. + + For a description of the *best* parameter, see the :func:`distro.version` + method. + """ + return _distro.build_number(best) + + +def like(): + """ + Return a space-separated list of distro IDs of distributions that are + closely related to the current OS distribution in regards to packaging + and programming interfaces, for example distributions the current + distribution is a derivative from. + + **Lookup hierarchy:** + + This information item is only provided by the os-release file. + For details, see the description of the "ID_LIKE" attribute in the + `os-release man page + <http://www.freedesktop.org/software/systemd/man/os-release.html>`_. + """ + return _distro.like() + + +def codename(): + """ + Return the codename for the release of the current OS distribution, + as a string. + + If the distribution does not have a codename, an empty string is returned. + + Note that the returned codename is not always really a codename. For + example, openSUSE returns "x86_64". This function does not handle such + cases in any special way and just returns the string it finds, if any. + + **Lookup hierarchy:** + + * the codename within the "VERSION" attribute of the os-release file, if + provided, + + * the value of the "Codename" attribute returned by the lsb_release + command, + + * the value of the "<codename>" field of the distro release file. + """ + return _distro.codename() + + +def info(pretty=False, best=False): + """ + Return certain machine-readable information items about the current OS + distribution in a dictionary, as shown in the following example: + + .. sourcecode:: python + + { + 'id': 'rhel', + 'version': '7.0', + 'version_parts': { + 'major': '7', + 'minor': '0', + 'build_number': '' + }, + 'like': 'fedora', + 'codename': 'Maipo' + } + + The dictionary structure and keys are always the same, regardless of which + information items are available in the underlying data sources. The values + for the various keys are as follows: + + * ``id``: The result of :func:`distro.id`. + + * ``version``: The result of :func:`distro.version`. + + * ``version_parts -> major``: The result of :func:`distro.major_version`. + + * ``version_parts -> minor``: The result of :func:`distro.minor_version`. + + * ``version_parts -> build_number``: The result of + :func:`distro.build_number`. + + * ``like``: The result of :func:`distro.like`. + + * ``codename``: The result of :func:`distro.codename`. + + For a description of the *pretty* and *best* parameters, see the + :func:`distro.version` method. + """ + return _distro.info(pretty, best) + + +def os_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the os-release file data source of the current OS distribution. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_info() + + +def lsb_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the lsb_release command data source of the current OS distribution. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_info() + + +def distro_release_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current OS distribution. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_info() + + +def uname_info(): + """ + Return a dictionary containing key-value pairs for the information items + from the distro release file data source of the current OS distribution. + """ + return _distro.uname_info() + + +def os_release_attr(attribute): + """ + Return a single named information item from the os-release file data source + of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `os-release file`_ for details about these information items. + """ + return _distro.os_release_attr(attribute) + + +def lsb_release_attr(attribute): + """ + Return a single named information item from the lsb_release command output + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `lsb_release command output`_ for details about these information + items. + """ + return _distro.lsb_release_attr(attribute) + + +def distro_release_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + + See `distro release file`_ for details about these information items. + """ + return _distro.distro_release_attr(attribute) + + +def uname_attr(attribute): + """ + Return a single named information item from the distro release file + data source of the current OS distribution. + + Parameters: + + * ``attribute`` (string): Key of the information item. + + Returns: + + * (string): Value of the information item, if the item exists. + The empty string, if the item does not exist. + """ + return _distro.uname_attr(attribute) + + +class cached_property(object): + """A version of @property which caches the value. On access, it calls the + underlying function and sets the value in `__dict__` so future accesses + will not re-call the property. + """ + def __init__(self, f): + self._fname = f.__name__ + self._f = f + + def __get__(self, obj, owner): + assert obj is not None, 'call {} on an instance'.format(self._fname) + ret = obj.__dict__[self._fname] = self._f(obj) + return ret + + +class LinuxDistribution(object): + """ + Provides information about a OS distribution. + + This package creates a private module-global instance of this class with + default initialization arguments, that is used by the + `consolidated accessor functions`_ and `single source accessor functions`_. + By using default initialization arguments, that module-global instance + returns data about the current OS distribution (i.e. the distro this + package runs on). + + Normally, it is not necessary to create additional instances of this class. + However, in situations where control is needed over the exact data sources + that are used, instances of this class can be created with a specific + distro release file, or a specific os-release file, or without invoking the + lsb_release command. + """ + + def __init__(self, + include_lsb=True, + os_release_file='', + distro_release_file='', + include_uname=True): + """ + The initialization method of this class gathers information from the + available data sources, and stores that in private instance attributes. + Subsequent access to the information items uses these private instance + attributes, so that the data sources are read only once. + + Parameters: + + * ``include_lsb`` (bool): Controls whether the + `lsb_release command output`_ is included as a data source. + + If the lsb_release command is not available in the program execution + path, the data source for the lsb_release command will be empty. + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is to be used as a data source. + + An empty string (the default) will cause the default path name to + be used (see `os-release file`_ for details). + + If the specified or defaulted os-release file does not exist, the + data source for the os-release file will be empty. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is to be used as a data source. + + An empty string (the default) will cause a default search algorithm + to be used (see `distro release file`_ for details). + + If the specified distro release file does not exist, or if no default + distro release file can be found, the data source for the distro + release file will be empty. + + * ``include_name`` (bool): Controls whether uname command output is + included as a data source. If the uname command is not available in + the program execution path the data source for the uname command will + be empty. + + Public instance attributes: + + * ``os_release_file`` (string): The path name of the + `os-release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``distro_release_file`` (string): The path name of the + `distro release file`_ that is actually used as a data source. The + empty string if no distro release file is used as a data source. + + * ``include_lsb`` (bool): The result of the ``include_lsb`` parameter. + This controls whether the lsb information will be loaded. + + * ``include_uname`` (bool): The result of the ``include_uname`` + parameter. This controls whether the uname information will + be loaded. + + Raises: + + * :py:exc:`IOError`: Some I/O issue with an os-release file or distro + release file. + + * :py:exc:`subprocess.CalledProcessError`: The lsb_release command had + some issue (other than not being available in the program execution + path). + + * :py:exc:`UnicodeError`: A data source has unexpected characters or + uses an unexpected encoding. + """ + self.os_release_file = os_release_file or \ + os.path.join(_UNIXCONFDIR, _OS_RELEASE_BASENAME) + self.distro_release_file = distro_release_file or '' # updated later + self.include_lsb = include_lsb + self.include_uname = include_uname + + def __repr__(self): + """Return repr of all info + """ + return \ + "LinuxDistribution(" \ + "os_release_file={self.os_release_file!r}, " \ + "distro_release_file={self.distro_release_file!r}, " \ + "include_lsb={self.include_lsb!r}, " \ + "include_uname={self.include_uname!r}, " \ + "_os_release_info={self._os_release_info!r}, " \ + "_lsb_release_info={self._lsb_release_info!r}, " \ + "_distro_release_info={self._distro_release_info!r}, " \ + "_uname_info={self._uname_info!r})".format( + self=self) + + def linux_distribution(self, full_distribution_name=True): + """ + Return information about the OS distribution that is compatible + with Python's :func:`platform.linux_distribution`, supporting a subset + of its parameters. + + For details, see :func:`distro.linux_distribution`. + """ + return ( + self.name() if full_distribution_name else self.id(), + self.version(), + self.codename() + ) + + def id(self): + """Return the distro ID of the OS distribution, as a string. + + For details, see :func:`distro.id`. + """ + def normalize(distro_id, table): + distro_id = distro_id.lower().replace(' ', '_') + return table.get(distro_id, distro_id) + + distro_id = self.os_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_OS_ID) + + distro_id = self.lsb_release_attr('distributor_id') + if distro_id: + return normalize(distro_id, NORMALIZED_LSB_ID) + + distro_id = self.distro_release_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + distro_id = self.uname_attr('id') + if distro_id: + return normalize(distro_id, NORMALIZED_DISTRO_ID) + + return '' + + def name(self, pretty=False): + """ + Return the name of the OS distribution, as a string. + + For details, see :func:`distro.name`. + """ + name = self.os_release_attr('name') \ + or self.lsb_release_attr('distributor_id') \ + or self.distro_release_attr('name') \ + or self.uname_attr('name') + if pretty: + name = self.os_release_attr('pretty_name') \ + or self.lsb_release_attr('description') + if not name: + name = self.distro_release_attr('name') \ + or self.uname_attr('name') + version = self.version(pretty=True) + if version: + name = name + ' ' + version + return name or '' + + def version(self, pretty=False, best=False): + """ + Return the version of the OS distribution, as a string. + + For details, see :func:`distro.version`. + """ + versions = [ + self.os_release_attr('version_id'), + self.lsb_release_attr('release'), + self.distro_release_attr('version_id'), + self._parse_distro_release_content( + self.os_release_attr('pretty_name')).get('version_id', ''), + self._parse_distro_release_content( + self.lsb_release_attr('description')).get('version_id', ''), + self.uname_attr('release') + ] + version = '' + if best: + # This algorithm uses the last version in priority order that has + # the best precision. If the versions are not in conflict, that + # does not matter; otherwise, using the last one instead of the + # first one might be considered a surprise. + for v in versions: + if v.count(".") > version.count(".") or version == '': + version = v + else: + for v in versions: + if v != '': + version = v + break + if pretty and version and self.codename(): + version = u'{0} ({1})'.format(version, self.codename()) + return version + + def version_parts(self, best=False): + """ + Return the version of the OS distribution, as a tuple of version + numbers. + + For details, see :func:`distro.version_parts`. + """ + version_str = self.version(best=best) + if version_str: + version_regex = re.compile(r'(\d+)\.?(\d+)?\.?(\d+)?') + matches = version_regex.match(version_str) + if matches: + major, minor, build_number = matches.groups() + return major, minor or '', build_number or '' + return '', '', '' + + def major_version(self, best=False): + """ + Return the major version number of the current distribution. + + For details, see :func:`distro.major_version`. + """ + return self.version_parts(best)[0] + + def minor_version(self, best=False): + """ + Return the minor version number of the current distribution. + + For details, see :func:`distro.minor_version`. + """ + return self.version_parts(best)[1] + + def build_number(self, best=False): + """ + Return the build number of the current distribution. + + For details, see :func:`distro.build_number`. + """ + return self.version_parts(best)[2] + + def like(self): + """ + Return the IDs of distributions that are like the OS distribution. + + For details, see :func:`distro.like`. + """ + return self.os_release_attr('id_like') or '' + + def codename(self): + """ + Return the codename of the OS distribution. + + For details, see :func:`distro.codename`. + """ + return self.os_release_attr('codename') \ + or self.lsb_release_attr('codename') \ + or self.distro_release_attr('codename') \ + or '' + + def info(self, pretty=False, best=False): + """ + Return certain machine-readable information about the OS + distribution. + + For details, see :func:`distro.info`. + """ + return dict( + id=self.id(), + version=self.version(pretty, best), + version_parts=dict( + major=self.major_version(best), + minor=self.minor_version(best), + build_number=self.build_number(best) + ), + like=self.like(), + codename=self.codename(), + ) + + def os_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the os-release file data source of the OS distribution. + + For details, see :func:`distro.os_release_info`. + """ + return self._os_release_info + + def lsb_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the lsb_release command data source of the OS + distribution. + + For details, see :func:`distro.lsb_release_info`. + """ + return self._lsb_release_info + + def distro_release_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the distro release file data source of the OS + distribution. + + For details, see :func:`distro.distro_release_info`. + """ + return self._distro_release_info + + def uname_info(self): + """ + Return a dictionary containing key-value pairs for the information + items from the uname command data source of the OS distribution. + + For details, see :func:`distro.uname_info`. + """ + + def os_release_attr(self, attribute): + """ + Return a single named information item from the os-release file data + source of the OS distribution. + + For details, see :func:`distro.os_release_attr`. + """ + return self._os_release_info.get(attribute, '') + + def lsb_release_attr(self, attribute): + """ + Return a single named information item from the lsb_release command + output data source of the OS distribution. + + For details, see :func:`distro.lsb_release_attr`. + """ + return self._lsb_release_info.get(attribute, '') + + def distro_release_attr(self, attribute): + """ + Return a single named information item from the distro release file + data source of the OS distribution. + + For details, see :func:`distro.distro_release_attr`. + """ + return self._distro_release_info.get(attribute, '') + + def uname_attr(self, attribute): + """ + Return a single named information item from the uname command + output data source of the OS distribution. + + For details, see :func:`distro.uname_release_attr`. + """ + return self._uname_info.get(attribute, '') + + @cached_property + def _os_release_info(self): + """ + Get the information items from the specified os-release file. + + Returns: + A dictionary containing all information items. + """ + if os.path.isfile(self.os_release_file): + with open(self.os_release_file) as release_file: + return self._parse_os_release_content(release_file) + return {} + + @staticmethod + def _parse_os_release_content(lines): + """ + Parse the lines of an os-release file. + + Parameters: + + * lines: Iterable through the lines in the os-release file. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + lexer = shlex.shlex(lines, posix=True) + lexer.whitespace_split = True + + # The shlex module defines its `wordchars` variable using literals, + # making it dependent on the encoding of the Python source file. + # In Python 2.6 and 2.7, the shlex source file is encoded in + # 'iso-8859-1', and the `wordchars` variable is defined as a byte + # string. This causes a UnicodeDecodeError to be raised when the + # parsed content is a unicode object. The following fix resolves that + # (... but it should be fixed in shlex...): + if sys.version_info[0] == 2 and isinstance(lexer.wordchars, bytes): + lexer.wordchars = lexer.wordchars.decode('iso-8859-1') + + tokens = list(lexer) + for token in tokens: + # At this point, all shell-like parsing has been done (i.e. + # comments processed, quotes and backslash escape sequences + # processed, multi-line values assembled, trailing newlines + # stripped, etc.), so the tokens are now either: + # * variable assignments: var=value + # * commands or their arguments (not allowed in os-release) + if '=' in token: + k, v = token.split('=', 1) + if isinstance(v, bytes): + v = v.decode('utf-8') + props[k.lower()] = v + if k == 'VERSION': + # this handles cases in which the codename is in + # the `(CODENAME)` (rhel, centos, fedora) format + # or in the `, CODENAME` format (Ubuntu). + codename = re.search(r'(\(\D+\))|,(\s+)?\D+', v) + if codename: + codename = codename.group() + codename = codename.strip('()') + codename = codename.strip(',') + codename = codename.strip() + # codename appears within paranthese. + props['codename'] = codename + else: + props['codename'] = '' + else: + # Ignore any tokens that are not variable assignments + pass + return props + + @cached_property + def _lsb_release_info(self): + """ + Get the information items from the lsb_release command output. + + Returns: + A dictionary containing all information items. + """ + if not self.include_lsb: + return {} + with open(os.devnull, 'w') as devnull: + try: + cmd = ('lsb_release', '-a') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: # Command not found + return {} + content = stdout.decode(sys.getfilesystemencoding()).splitlines() + return self._parse_lsb_release_content(content) + + @staticmethod + def _parse_lsb_release_content(lines): + """ + Parse the output of the lsb_release command. + + Parameters: + + * lines: Iterable through the lines of the lsb_release output. + Each line must be a unicode string or a UTF-8 encoded byte + string. + + Returns: + A dictionary containing all information items. + """ + props = {} + for line in lines: + kv = line.strip('\n').split(':', 1) + if len(kv) != 2: + # Ignore lines without colon. + continue + k, v = kv + props.update({k.replace(' ', '_').lower(): v.strip()}) + return props + + @cached_property + def _uname_info(self): + with open(os.devnull, 'w') as devnull: + try: + cmd = ('uname', '-rs') + stdout = subprocess.check_output(cmd, stderr=devnull) + except OSError: + return {} + content = stdout.decode(sys.getfilesystemencoding()).splitlines() + return self._parse_uname_content(content) + + @staticmethod + def _parse_uname_content(lines): + props = {} + match = re.search(r'^([^\s]+)\s+([\d\.]+)', lines[0].strip()) + if match: + name, version = match.groups() + + # This is to prevent the Linux kernel version from + # appearing as the 'best' version on otherwise + # identifiable distributions. + if name == 'Linux': + return {} + props['id'] = name.lower() + props['name'] = name + props['release'] = version + return props + + @cached_property + def _distro_release_info(self): + """ + Get the information items from the specified distro release file. + + Returns: + A dictionary containing all information items. + """ + if self.distro_release_file: + # If it was specified, we use it and parse what we can, even if + # its file name or content does not match the expected pattern. + distro_info = self._parse_distro_release_file( + self.distro_release_file) + basename = os.path.basename(self.distro_release_file) + # The file name pattern for user-specified distro release files + # is somewhat more tolerant (compared to when searching for the + # file), because we want to use what was specified as best as + # possible. + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + distro_info['id'] = match.group(1) + return distro_info + else: + try: + basenames = os.listdir(_UNIXCONFDIR) + # We sort for repeatability in cases where there are multiple + # distro specific files; e.g. CentOS, Oracle, Enterprise all + # containing `redhat-release` on top of their own. + basenames.sort() + except OSError: + # This may occur when /etc is not readable but we can't be + # sure about the *-release files. Check common entries of + # /etc for information. If they turn out to not be there the + # error is handled in `_parse_distro_release_file()`. + basenames = ['SuSE-release', + 'arch-release', + 'base-release', + 'centos-release', + 'fedora-release', + 'gentoo-release', + 'mageia-release', + 'mandrake-release', + 'mandriva-release', + 'mandrivalinux-release', + 'manjaro-release', + 'oracle-release', + 'redhat-release', + 'sl-release', + 'slackware-version'] + for basename in basenames: + if basename in _DISTRO_RELEASE_IGNORE_BASENAMES: + continue + match = _DISTRO_RELEASE_BASENAME_PATTERN.match(basename) + if match: + filepath = os.path.join(_UNIXCONFDIR, basename) + distro_info = self._parse_distro_release_file(filepath) + if 'name' in distro_info: + # The name is always present if the pattern matches + self.distro_release_file = filepath + distro_info['id'] = match.group(1) + return distro_info + return {} + + def _parse_distro_release_file(self, filepath): + """ + Parse a distro release file. + + Parameters: + + * filepath: Path name of the distro release file. + + Returns: + A dictionary containing all information items. + """ + try: + with open(filepath) as fp: + # Only parse the first line. For instance, on SLES there + # are multiple lines. We don't want them... + return self._parse_distro_release_content(fp.readline()) + except (OSError, IOError): + # Ignore not being able to read a specific, seemingly version + # related file. + # See https://github.com/nir0s/distro/issues/162 + return {} + + @staticmethod + def _parse_distro_release_content(line): + """ + Parse a line from a distro release file. + + Parameters: + * line: Line from the distro release file. Must be a unicode string + or a UTF-8 encoded byte string. + + Returns: + A dictionary containing all information items. + """ + if isinstance(line, bytes): + line = line.decode('utf-8') + matches = _DISTRO_RELEASE_CONTENT_REVERSED_PATTERN.match( + line.strip()[::-1]) + distro_info = {} + if matches: + # regexp ensures non-None + distro_info['name'] = matches.group(3)[::-1] + if matches.group(2): + distro_info['version_id'] = matches.group(2)[::-1] + if matches.group(1): + distro_info['codename'] = matches.group(1)[::-1] + elif line: + distro_info['name'] = line.strip() + return distro_info + + +_distro = LinuxDistribution() + + +def main(): + logger = logging.getLogger(__name__) + logger.setLevel(logging.DEBUG) + logger.addHandler(logging.StreamHandler(sys.stdout)) + + parser = argparse.ArgumentParser(description="OS distro info tool") + parser.add_argument( + '--json', + '-j', + help="Output in machine readable format", + action="store_true") + args = parser.parse_args() + + if args.json: + logger.info(json.dumps(info(), indent=4, sort_keys=True)) + else: + logger.info('Name: %s', name(pretty=True)) + distribution_version = version(pretty=True) + logger.info('Version: %s', distribution_version) + distribution_codename = codename() + logger.info('Codename: %s', distribution_codename) + + +if __name__ == '__main__': + main() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py new file mode 100644 index 0000000..0491234 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__init__.py @@ -0,0 +1,35 @@ +""" +HTML parsing library based on the `WHATWG HTML specification +<https://whatwg.org/html>`_. The parser is designed to be compatible with +existing HTML found in the wild and implements well-defined error recovery that +is largely compatible with modern desktop web browsers. + +Example usage:: + + from pip._vendor import html5lib + with open("my_document.html", "rb") as f: + tree = html5lib.parse(f) + +For convenience, this module re-exports the following names: + +* :func:`~.html5parser.parse` +* :func:`~.html5parser.parseFragment` +* :class:`~.html5parser.HTMLParser` +* :func:`~.treebuilders.getTreeBuilder` +* :func:`~.treewalkers.getTreeWalker` +* :func:`~.serializer.serialize` +""" + +from __future__ import absolute_import, division, unicode_literals + +from .html5parser import HTMLParser, parse, parseFragment +from .treebuilders import getTreeBuilder +from .treewalkers import getTreeWalker +from .serializer import serialize + +__all__ = ["HTMLParser", "parse", "parseFragment", "getTreeBuilder", + "getTreeWalker", "serialize"] + +# this has to be at the top level, see how setup.py parses this +#: Distribution version number. +__version__ = "1.0.1" diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd125abb63e36123b7e664fb9968952afae24430 GIT binary patch literal 1269 zcmaJ>%WfMt6dgS*$&_TffU_sO2%;h$H9)fwQlkyfB#R^{Py+@A1t`vtGh)NXl;n8q zEcyZYiLMLui)Ncuexa*gavV2yfl`<&^6Jhxhxei9%Oy%+Wq&;U<-<5hK8C~RHG$3d z@VFfqmShPVu%R5NVK!8wY^287c#yCW8_PX4$tG%=P1P)$Mc<y>S13bqKaq2_$QE%w zl}mMy9l(CZ_8DSxwqVO@k{z;x?1&xyoUD%MU&ACpug>4R#x=E0=n6}bTWYUyP9101 zXzX_!Z!cc`aDMR;$4FQ6LX@JQUKov@?YytuX1#8A)VEb?Y_;BbCC|1b#pm#D0Ol48 zhZ%RG(tzp>&N(iOssSUH9Jj*n5Wf=62MLj-G>v9h^!%-m4AXE{wd9Ix?{LedJY~ET z0g+p4EVjHbmmI`<(1L(bQd@C(eV+;|!?@K!&^vExfXZ=hO$$0*iqMZ&G|=G2(TZ<2 z2w_;IH44|FPRS+L49Gx=u^xxJK82*kpl}atYOWuhsB6MZ(FCn&h&g$TPi%g&!qnk% z6QcvHx18heZc);htw-ewp%=hW7!7QK>w-UqOTmpmc>~fcKjl|}-^KcrMoQC$+-a(~ z1Ib_GP1)#Tv;94?Kkci~!*Boh*B6#nL3NBOBz5jSNT|<Gv8s2F!d3DHDiyL=aeofy z=l%IVaV?eaz6iUB$2(C_3qhrL&ux0U-J(x09?5Fd9n#zx*?3O+GITR0E`@`J?2Z~O z3aBrU!gEWd`!wj^iGAMd?)G9nx@G+OeB;%iJGiSGJj)wTFA*I3w{mQlT00G97R-Jy zVaDwo%=^73={M<<x2vzZDG9wmNQVe18{b$?h=s{Z>?j!cGf295Y^12i-UIFyU#2$F zbo1c4$ztT}(7(DOe_*9j0_&VW&%$&YO~{{#Jr10~{C&3es$N4=p9<|f1fLddrGNFm weH)zdx#{*e(xJ`Qga|D>A!&Wx&7Sq`c=iC$+!2`Z@OXGUScK1THkgh70k2Vx00000 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_ihatexml.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..feda7af7f96e3aa4e484ddcc2c633886029e7bd8 GIT binary patch literal 13716 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 Lwf@>bZQ$Pky#&(z literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_inputstream.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..789fb992b0140d1d6f0c604422ab392d2d3b90bb GIT binary patch literal 22607 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_tokenizer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c332caa7967b2b3a15ba5f02f83c56907164a05 GIT binary patch literal 41508 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 W_q6Pb=lCBS*aN=AS~2;ZN&G(&gjtOM literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f67cc54b474c825334685e180eb4c671fc3013c GIT binary patch literal 3261 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 F{{cJ@8t(uA literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/constants.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e8ac242fe5d950350f0427f0bbb64257b662adc GIT binary patch literal 66173 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≈FcKiuAQfor-Nb<TmAcn@UTY zN>7hUTfeH<UgiESEI?Nu&AaGm-t|&piy7e)#<=TzHJX;y7VO?>jEZVe|7NM7-`En< zq-s^WHr=WDJGG*Ao$z)Qq$V{FovPg}Dj>Z n1ZuiCjb)%M;EI$eFvbTz4rbgC@1 zZ;~#yZ<eW0(P~k9wNb5Kmx_FYigKg&xIstMsYf<K4yz(GYkzuWGqYcfo?h+NHoD$4 zMo;B^mw0f8bfVftO5W0*x649&M0vPTdA0H0qj~3=2~q`aRlc`qZ(DTY+O(mK%HNF} z&BV#Vd_>Fd72|zCt7+E`?|4&q)-C-!qP6VNh1ckks+fvj>kek{TRL^Eat?PywMHeW z)wwZX^z;EKrIw~oEoR^S(t|#=c$@c1yiqM~pAMi;T#Eym+@jW?LDjs$#6_b9RKXhV zNwF$BUY54nZrGysv{$@_gW^LRdj4qMwbG4N<w&pceXmMStM;Qy8QCbV)j<)Dx71bX zmrCy0cQo%T?#L1C?k+Jo@9z`e=ly*q-e?3!I`;m)b(#F?6;jPEk>L0Dse12_PQPt9 zZ5E|=m5qL7X^$AP{i<>s<RoCfs?7#v#Rkp2L1%e`*0Mond;c5Ki48ix8+L14=Wm1B zqzx+S8&sIr>4-NP%eYmITAz3!pI5i-S*fnCNhVAW@x?biEbi+8mGwRq%RXV+dwt4} zzDBVT?GHLOqR;H#%tF)nqRfMlE>*ogoz^}z8m*=YRr@|QPwnO|gIV|*O$IeSeQHJe zRE&Gol(#F}x|Q3#%Ka`q_G#s1h-CGM*4U*@HmTieRJ)`--KDfaJ&d-OjpXQsPD3?A zv#NTF^1n%k*ktY{7@wn|!<Z0p>JR8p)~)}5cY#j`5u0#WcLU<l?|1g)x?@y#qDL3a z79Go86`saknQfh4*<Kw`m1>izdi!~ijK&Q@TU4<2s-U$ghkKO6J>p3pxlgJ#H|F4B zQST4F%)Q@l4E0tO>-LwW_I7QpT`haNc1=2ZL@l2v`vDQ%!w%=gQ~1J*%D)b08~rA? zeMF9ej%=5nyu##=tRx3yu!mnUvnXdG2ZX&x<Y4!RvnMlwZK?vDs<fR(4AuU1$=2zB z@~B(3a0gWcx^*?^+aOF)bJeLfuTwePWYU#KU8<{1#<H91YC-y*5IyXB!qLM{6@Z7H z$>e?VXx?qY>~8I4w>lTyx`e#JoH-y9d00E!sh&fZier}+ZhA&4YgN^4Zq}L9>wUW5 z^s4;#sSnh*UaiFgPA~h^Dzxh=(e;{{4Py?JVO@RF#*Rkr=@A`xmoj3fOznV9&Zeie zhi2((m3W`&scPsR)s|*8)O*xMG--ObvpLj>=}~p+QDJRS71-H!G;gA`(XB)3(yR?C zAZ^Nx1|z)N3|sEi&gq;qh~5ks8>@ZoHTt4s>C)NhHKL^~+$js(dtJt=bqm*9dmOH} zydu)49^@`<Y4;=2ksVJ8?GY6`tW0TeEW6G{<6fyo6}VrS-l7)1N3-=mDAlz&mfW0{ zY!hGMpf=E^_Z8ZAnWOpEe&=YuS-I4_NzN?V?{_lwWiu%Y+jL}YVloGGnQD22a`Ii0 zUb-P5_e<IlB11KxjNPTf?^VY}ZV(PMX~8FuT^|0B-XB)kY0!CZR*~rJ)cT$K6rDXr zxK(PKw55JksCH#UyGZkq2egK6(`1t_`3>d-qGOLt!9K~^{<0ZW`}3wu`-{@uc9oZQ zV}D;4x#)kLHs8#O7UwookGdjF56YF!XHCUT4<RHcY1>rN+8QNO{|3`$+XhW(diN#n z;9KhLy?!+B9O+J@ife<aWSgo>r_NRDz0Rz*?NbTvq9kg2nsaThu1%fyXr4}!=Nbyg z4W8$m?44?Y+Mai=w!G$CZPq?@iYxeDrwI64&&n9YlphvbIiQBAN2Q@#Z0CSVLAP1% zu)inadgno@LuY!g>VCKCPPa}<w<_~qxzjx$=J`-7*KtrSNVjtXR28;cr?^{9M2j)N zYPA}l<Hq;*3DKpgO$DM?N8PJ}+pAsGfwkQ)J=dQ0ydY66yzzCZQ=|RQ%Ix;*>ExS7 z^UllUl}ciR8i<C^7(I9*MZ7sA9_XPC$#(xHNfj0x(%v<0I+}N(Wa!c9>Cx4&NByo| zWp0mJ%pP60dW?J3@u+lG%lBz#`;>is%Dz4wYP+(rLF?V9>bh~O^kbvWb(=YI-zHAO zp%xvlIpyDO4!g~v(K@r)-`1o<+Ho}RItg~}7TTruqviE?MR^94Ki%5xZtX^QmyAk9 zr%QX^slw5z**jHJy40)d(j}}(xzVJ;(y2D4MW^(kXES+sAI<x?^r~CkitbGsmqVEW zz00tZr|yU@!=1|5E?vx<v@1JQ*SlUff}r-gOO)l%I*|Z%OPkd&x6A(J9b*L5*l*Ho z{W?8+wDxABQ|2)&bClPk8GEqloTS50d)K2pZ7^QpHsdkqYPv&ZWUr3DOJ$_-VeayP zu62FN+&*1e9+j)I#~M&h_bG?_R3Y1yO+DL$i)tg<b;5d8teZt4_wPNLH&uGysRef% z!?0a7ZI`&sN5p;{Y59QEZNF-rEN_Q&@$c2ux=+QVPsOLtbas!l)oLVGoxd(sjvk%c zy_&w!D4D5Ojd<Taazm&eM>ZbKn=F;?Z4|oESWR<kyXz4(;oGQ`So7@^)D=iI?SAc4 zn+~R5S=RTu)Z4#asj{?RJ=Hdy)jqYXT{^q{I_v$aa{b$+{4TYix~0(*NF8~<cA`(^ zu3z`*{W`ckD#rb4XS-Bk`%R}+wc50E{i;R%I>>&N(SEgv&AX&iozkhdbb>bSVD26g zM|nVRw>>T_*QPcai@06aWf9Xu_pyMy^@b4bXOHSvj|$aB72AGe#?6s-zfnvT{vB$G zTGgWMRIj>6<-Nz~lDc+1%8<?G;9{G~t*j469^^3$s8#QJTzaX#lIq_RlK3iTJ)$0* z4xsA|V{Y_NP}|?3jNYjI+^B|Srz)>(k_XIlLb$`gtCq@Gvrf-ORg{ggd=02c+v&Lb zDr@bs{T%3(o~p~&t)uE!d(y8e-Mw3-zRgj9{&pwWmJRlAq*UtIVb#bsWoN5SOS@Tx zwmTy+9{DyExo+Kh=*0CJomWX~G&lKivqBUQcQI5G%_-=1JzY{IXn)n@>@_*>m4S<g za74~n24pjSq@AzrH}36rIYT{SmP_2+(B_26M>a`avfCdJQ5X;h?XXliAb#0F$23av zVHM(L^Ee9b>uA+F`wc3U4I3xEh(ANgSkucQ;ZWMgWNOAUecr;f7e7-ozUhG~d}k!> z7djPz$~gY&U@FQ~h2vEyLj=#FPp?`_ztwRngui&Kr$S7pA`|_Y5z*Q}Rh+U#ZHmQ0 zu_&HgpB}5Lo|+yt9e<a+c2+9Ne^^Ql(5vr}iwNbyADB`5cnfzZN{!%8er#%l>C}vO zdI~R-vFLYdy66V{2}B}-_W+^f4S{$)N`l~(cWC_v>T1Cacr^+B0CZ}4_zn1TM!dQW ze+)vI@n^D>2LnNbd*-`=hm5Fn;f7RgU2qjH&zOUnGTs>r7A`{szi4F!GYmD%2;kxT z6Y(3y-=@sOUz^f*bCO|%(fEu2{t$I7+Vjt-3gAzhF`gOtAW%3$2}Hr38N%6u8Ti8t z{5dGKXX6on6s8Oj^s;CMY7E9_QmS_b_1HV3CQRv=lSq)$M@V>HIGRFp!zH#bLJ_^h ze^oj)ed-MQ<LK34{+rk&{*(lt<q2W}(Up^M3CZ{)rnNKqbyYXhmp7)S$7Itr#W#cA z3`fHviY!Gl@ORsB{P`}rh(sC47zA=#ux2o)ksE(+XycnPQ`5yW=&#Fy@#A;PHzOWP z(45WSdGXFjf#ZJsGV47v!RW%7U_v}lgK4*B-bnLq&8!fzoQQvBAQTGHRL=~=L3}eI zG9)ZBWm?kSnUu{tGe|RnUlxv;#Okp#!w_ctbr=3JX*wy%)bwaq5;OngoCJE&m*#XA zo=wV<TOa;-)J9SPir2<SS4IsIAZsS`%ge3!@ymfi{Fc!R(J*B)QO7X4NYXj`7!zI{ zosKseuEvB)N_nt4sVOIBQx?&m6KnFQZ1UnDdU}G!G1;!dr{<=*D=_t<fIE4tlyE1F zb|rCJ+V+w<?aMgHu%vD#-T{@HwiKVBqWOX9Llj-tM>=7?gl4s<Q!D3I#mDGYM`>K# zuciE_wo}t+S5na{lZMVpnn`dnNdmVvo-%P&u99HACYqwzY_75el#SWILqJGJ%>50> zG+HyoP|c**Cai?`md&3HvtG7%4uXs4z}S?jSr-a<FH<vQm66p+`<PHkR+ciGO-vbE z_cFEaLLsGP@-7f4NSWC8v1PS&$+Z>q3Wo}aV;ll<A}3)!a+7^!x(1Z7JQtMJCBke# zd@9GonW{dFKm_kHt&E3LwNTkI9wkT^F>e`EGvh7eMSy;3Q1nd+7>JSPuef1-%aC;z z>+~$r;&HR+WtetOUr&;>V>)Zi;!gT!#p2T=sDJn@SjjL%ERN;NnkBuNO;#q8KYMZ7 zGkY;uGCP2`N1!iEp~?Q)vVbCB4E=0kIl48Qc|BWrJ)3&xnN2I-Y;JbsY<`(kTp2Ug z9WBQn%fW(Z(k!fHnrpNsDS^$`kdzpwu?qZYr?DKS9p$+-o5$suO$L0<^hInBeRJ>! zs3cf(0!a4F(E-e%K98Iej^Mj-$qM=-RrG!i_kQ#oyv#ohvmc0*<9!B{E;2etWpv~m ztg0m3M4_xibP(2DmO|g$8{ws(<lF_sV&7bqVWDss=8EVtLEq*wJLd{J=d$R|RnZj+ z{?3Ku_~we#4hN+#X~fsgg;39xcUDn7w00F{SHqDMjOz<9VD$0PExdgLwtWV@D8!wh zE30p=3i(`Sg*6v%Orc>21LlhVf^MW%(zv{HS%m2qeY;Uv%WIeSMq;paqf~RFl)o_% zjMGScH*)#3brX3dAY8<E6JGa1@^_O;oA)NV>b;3;x=CufiEFaTMRdy{y5$gEe>pRl z1GSYlb-5gW0Svh>5Acg>MefUCbSRH5m<Wjf;w`6!#`1DNe<y!~ykZqo>sld3I$^eq zCpb~}3NV6FX9W2z#?V-biOF}W)HJq?#(a*Je5<1-!O7$@r`(rWkys2v-~#S;$50J9 zCcl7E#QJJTt?wv}nzndci{oMND*|EXnoN{O%AGMOMy06|S;kB~TyRO9Yn|Ylm(&f) z;2P3!s>NL9ez`94cy*QF@y2OU*96Q}BEfxe%mvCP5-xj!sYoQ8tA!LJF!K@#w;4f8 ziG<n^Z#hYur<`nNc?8|l2L0u=VOGyk<++Z-coTO|$7o7)CvYiObzF+#?m=-WcY;+e z2C1C>7MpmbQ#ghb-1S@KtQX#L+C})w)lhlLVGg|W$h-H>BM~1l4+5X6ReM)75AU)I z<1eYPCV1!3xQp2L7MI(aCmJ`8Yxc}bL8<1mqWb3>ZJTd2X}-~<`P9q_^YK;AWVk+< z)7*HIiZ7s4t<*k@b0tPK?Ie>%%NjD9^b_afwZ=hP=hT_n(UP2<;DY(V)nd85^J!EC z^JDOi0$2pb&W}Yoh<%zd`ty01-udJ<jKr^N7f?h|_0dm6SX4R3QyY$C$Ehf!h&Z*Q zOi<;DsxoUlm2rAMCL7VBCuCDx;yf;!>XaRwO%u_kPU=;+fV<kz?odkZDn>(hEo78| zB+lsl)b#j4DQp|4L3cJC0yvIjQZ}lVLVAIEOi^bDBQ!yB(;zA2?!2i%dwvSC3@ry# zc(5o?^$YQ4&mdmx#nbP^v_mJkGPql%$`;}D0E?$Hy^tQUv00|jT(KUSB<2cLnv<%H z5mUv>tVmVjbv*Dj2c>96YTabS3pF_F$;YH=W)dw^AMsbhdXX4Vk*cbqFUSc4OiVLS zUrmym0W?^XuB?~3On)SU#I!Dwf6Yts&q2LJBjUJAq@6rkhB}|4T-JQDJsIEpq@14! zg?XM2W8_;vCqcNnK%Fb0aIO}JbHxOfja;y_e}P?z4;fPwCIN-iy%I{biDv~0+Xb7k z0I!ax(~h*YfDOcn3-E4<W6u>vJIQ*i;8_5RV=a)5FG$e24jN}l&FV;mQn&ccJ#eKK zuq#Es)Hno>C8>x*a7VB*k1%1p{T=Hx#TH`262<$<5_BF^h?pMQco))`y$i|uc^A?- zi)SGnwvc7l<CReh@p3DeZ~DG7JGl#an4X0wQkYelQ6{MKINrqFvf^aYiS#YR>#xw` z0=xiCPDq9$MBm)S`(<DgvJu+<TMK3FT9^of4>vDausCheFS>p+4Zylt7NVOun{N>q zgBkQJDx015;s;Dzr0bEjh@CzV_Vb7&(SU!ES*8}5Woi-e$Fm5196eae$D0KA2JS>n zTtbe1c3<aR#2j8!6N9rS>v4|%INZHPkIF`PZcoU@U2FSDPIX+!@f;oGLz=`KCvuGD z%zBa8Y%aG-x}<(&A(vq<QF@o%q>nb29RExb97l0%PMk+14H{EuG@tY3`ifFE$61v2 zv)-b~;_CVcuF3RAI_SDABg352@sPEMg=XX;oXpwI25H2ixXX#O7Kz|3BByD@q7;rH zgLu6R9lZK0=J1JW+N$6!ioasPti^0cDpb}y6)+}#yey541Oj>#TA{ljKDzT(kbI1; zsDbFyhH<)dP7+*`K8ADf@HERvPH~QSd==pkZP-Te?tccKnPQL?q8Syd;;;yQbAT~k z0=av?k!C%Sg=d^Qsxvj(q!|-`LT-X)8zHGnqO8nT1vAmAfTs+N#o|Lf(dBJK&RSGx z))O2OnxNJ>-o$gvib+(nLgi}~<I|Yj4jrUa&@n2KO@~o!&Vq!F)Y0OZu@=u+uxNhT z#{|}X@uKN7%ZSSKT8m}676;IK@8STK7yn{2wTq3>U;*$hrYS92j8}Z~mtv@r8a{|0 z?)Gbu!SP#t+W+B94YN7oS`Fo@X0;ac%oahH@FJs`<eOTHnbH2m;@oF^OLW~6iVRC2 z`(Ou=7^DzATT;pUZ9k~o30WdbBNL2t35)a+votQj&`_@~jY6pwSsDxJt1_}I4VR#- zOCy~KFHB=OnzJ(bR91?Z%J#yyL{A!)@JI_BQ6H`$wkTsY;!>UwIj5(i23ceu8x?Hc zn5r_Na^eZh0t(yELye7Ig0G9`Y^*rJt%ueU9P?o%BO<4LOY|ns5}A%ANj?D2c$e@3 zPQPH;QaYT+lq{`etyoHY_ARAvJ3z9SBA0h5ok#oO@^CJTd>?d?h;tG=(!^v#GtNXS zf*4W&?@@#<nKYFhio3T>-lZh5)>5$*OQqXO>!mZkTf|=ZZlRZoqEEMQ=36B5Eu7hV zE2VjE1s|+i<-)Ce!CJ<*(yV22ezlCmDdStFaw!z!UM5X=mk}4d%eaAMQqMB2hq-1g z7hAhrO{{;ps-Tx|fLP0U13r3rFdpN#f|?!Na=8z-oGV@~6)&fXGroZKMJSjZ5KTyX z*cS{`!3cN*RW>X{KvaVXN9kswPrHIV7@8Fb^36vk;7EWr&H*%whE!>ULSXO`&FaKj zI<rHl4$}@QcNPQcX@W-Jzk2X$EYw0LiC(;okNOz3Ibh)z@j{S91g|y&`w_$~ALOIM zMf@Vorw2DE7OG81ehLJzT%afiVbx3!tCk76@}eG-iZPiW8Zkj00B(;#KnqZ5JXx=G zQb;--O2{yyp@im2L(iy#s_6lq8V?^w1nR(fe*g!sWT?CW8C_i%Rq0#8a1l4y)=(EX zfZLdu0J+i1gmQ{}2B<+F-T_BUEMQ8xeK>>Q`>sOaTn1Q2>6fZqU8Ohqd;xrz3RPH@ z*n!|mCGN=L8iqfDf<dGEMHH)3-<HCBoX@EU(S24wG`XI&8UenAi^?cKGi6m)#&HNy zNF>QYU!^qTtz-jHY2(dkR0-ej#ZV-Gq6pD_3e3H)lDfm0=vFY*%HmH1lZ1@P)%X@M zcv?yN;K%E$tBB(T6yU>qPNIdAlJLD&9x+07e5bXD5@l0@o`yq-RaGW0y+{@t4<shl z3nW_#1LR8K1sU;_)JAPFKd35YgTHbmoF*9Kk+dUQ8HuIwl3<K+1V<Bk7iJX4Oha(5 zbK=r)ZW<I0Lm8iwkKH|D8a6p#J?P3QmngkV=%qq&Lz#F+TcHB{!pjG<t;#4by_GDv zcn>!k@Z&cbgJL7FIvGZOAKtz>vs~#SrL+oAIyh#5&XMSxnM#)^g}hU?Ikce#U82=2 z(Q1}xHA}RbrIKx_R<~5MFV*ZzNlj7BQZ2R=#n8<)_%9c1EnsT_TQk~Pzm~7jZq{fw z>83Q*TZ3*Eg4W6{`T_)Ho+(j<hVrGfnUpq@(q>ZH49jtBO}!4IUbEM0_Im9`y%wuS zF@L2ho=<%l(0b?=E-)oFvo-L+!L6mGs*<%6QQnIp8sq9f$aGP(CPCh+Rf(HW)Bp(W ztPv+Wf_JUswvJNFGOo+B6nGoG+(Y-WV$sX#*<2SQ0Dp@#fYO|cP714<g>-DzeOTJ4 zF`~35_Ekx`A5<Q)z?ls{WFeGuu=*k=oLWdJ(*y+3s-l`RmK4Cd;rXGAf+{r`885vp z9=Z6*h9V-tIQPX{#Y<*Y4O<_6H6~nJrt~Im=tC8q9eCMBTlfV#h|tc52wA)_6o}ya zHc)BNz_G3r)xSbXBB?XM3ixQ6%I157Mu@-`XiS_GY7;X+MXTkp3~C++^2CL3JOL1Y zBG`3ME~2S0Gglw+z#H=U5f6G*J_6{rk6)Ef<DffXH0$(oRf*SCV?u^g+}tfLlE@l5 zL_|hf8R#9PA?6~g(1%{|x>Bs3h-2Y`OM$Nj)UBobb?|#Ab!~$C8JA@d$4mT3NR{|N zRV<7?A{eU$N<v5kQD0S(+bXC^*(eQh)eu*h!q<x^58lnqQ$z0uM*^}?0M&R|1`F{E z0j1Tzk6<<+BAbG1%uGw+q=tIHVuqa3U(`kc$lC~nB5Q-I>Ts}{jU{l(NZhAuZ1RV5 zP>g;Cox?j`qtq}_Y>E-6cZ<!KY=W`cRVl6rWo0R?%C6W|vSRzI)<*CVGW6D-PD8fr zIkZOkZGBb-0q8W$iA8K<LN2(E<O)Wpz&2}<PxnB6+xVO|DTRj|umamu=R=4&YlBq@ z@-aMiFqFn;BOnnzTb{Wou+3WSx2wa68t~L>lcM=-d^3e?5K-<7o|&QQ&7(6TG^El? zF$kO&FX`u8A-O;A!&_~`;2_fL;pE^KFPX)VnPN4T0PbJYJHd$;;rdt<_TREs(2)Fg z1RttHc?#fEjsh_}qs1MPbxz~}zoaRJOgV{y#`Gho4g*4F(H?E{Ggn!cr^vnAqOcQ3 z&&E&$tf-6ORlB@+k9DOO(_zQW9Qp0I={dbJ8a=mc(H#($0XFe|TW^2)Y*8A^h8sa_ z2Z4V2Y&_?|(~&~s#M#yALR)s4>M69-VYu_0CrD3ap&{ObXM923PY4C;f-qk6P?jGq zn;aJh$r@!WB6v83311dd<PCC9gJ2q@i#$bNu$r6j21!OdkR&vty9uF~>R^aw62Dpw zQdEe&2;beO%d~*umor5qlP{?I43<X9PaY)SO7J@ZidQYyO}Uh+rod%1Pz0zh-eKUy z=!p1&>c9tCJS^IJQW1~@i8GFn=@~tw^H$k$mvJFMUX(w$ikJaTBOq+>1y}LvJRFoB z=zvEFOQMko-#J1l`d%g%r|+3kL*kX88hB^?%v^9)z0-?0v(XonnX_OEQKv5`+(48c zy&+#Y<AF)Q5MdWG-XL!Y=$A&2io^f5f@`XHT=Yy1b&Ef8giQn=UYqy6;{hGa-l%Fk zIfT23m>04KX>T>_ST&eWm;KfFA^|-K;;XJ^iUj0Gg14GYf^&HVr&{<NER9q%fhMEG z+G>3MgorFK_*Ms6<v6X<_-adhCHP!e4PM~;8t?^t_*hESluOV)Q|br>E;Uy!(*(@8 zT)Er?t}uZsHE;=u2bI3$axHzSmL|`cuUu+MUup_nW>PLU^<8c*eGCEW9*a&jyat#e ztC}av6Dk8^LS-15Kcr5UPpuvjuu#Jqdqcc{g>)nD(_M`>#EK<LvWJf{Li8l0H$>B7 z;g@U~2+JF%gR#C4#DvyNP*$x12|x;vmy*b7L}}_RWrA!{Syt5$O=F0DeIeLd&d4U# z6XJ&X0j>}|{pt-xR?u%0<Fi6h8bBct+2A4_qJnhlsgH<ImRJiLGcsCi5h#~fybxdX z5kXm|5j@KkO3M4Ttx%GN<pW{gC?uB9A4*0Rvds%6`6Iz__n>;FBe*QeLjh(7T@9`h zg&fXdjT9iFdWsNtrU*N|cv5<Ah3a{%HPgw8`fCF4(#T%d1R~@i)dXtsbs7%Dd7Z@t z%2+@|dQ2fY$FIR+f`QbC1@YtCJaKwXu1Esx<{=R}h3XN&3PDR_4NXvC%}TtUowu44 zTrELgO^n;}*Tia*v^bBdiN#jZ`h#TJmX4-4uRfY!)ri{R6rVd|)$knnYamK|pjV>{ zj=yHD?j>sQjU9M7_zsdT7(!v+!&O)u!Zez+j|qAkX3-7P(tvAZeQ-^TkQYy5Qx1#= zmFcn|lq#cxfH3~i>4i@z5~BF{Hz)ApTfVRu7hhOc1W;0tLZUEUCP>zUO2Ho{k11SB zHV09>gP+<WmqBhBQmQmj$dq@%xF&}QUhWN|Nj%O<tzebHgUgsS4#EM|RQMb<Fkc18 zzz#E-j1eb%VO?*+vfhMs6yjC;!YsMyi%Kv)4?vb4L<S8~Mzw;n4ErdA*7?Iz3D`+a z0QJxw!H>tH`3YuUSRZP`12T9xpMH^bg~*+k_1e3FZT1Rf&<g3^3Xz5t=Ha##@^G7P zCDaPK?`MkU{433k1bTQb?OjQg`B#SGd|YF#<XxDxl3TJ?O5H2DZeL_Ni>wuy&gvAI zPG9yy@91e^RN`Sv6DflwvLbVMamL9CKj&Q-2{?;AzBG<c&!EjnKp&FB(o5Eh2&Ne6 z@(dWh-BAZgj0A8TMOXP$3Q=kc(RduY<^rbG#8(PA0h&=xiI76lr8@MKbF-D;B)Th$ zMu`3R<*}f8dM+K+C&|S6B2YDMP7cld5&G^qGDv_{J*2EeLIKf4g#2^~;f%r`QEv<Z zy)TCVvCN88(VpKMVU>%(+oziJ+>I$3Er{50^3fr&2&M3S2m~#BDh+Dkp=G_uWiCcJ zVHwC6ilYR1wdBsiz_?Oqt2LV9PALqQ6WkVu>&PY`%Q(u<DOxqsPH@uTe}_Zh7n?6i z#kcT+LEQj&BeXlgFRg?4rF9U*tb@Fw`S8o@AgHW^5}<WZL(GC;0#*5uf~639WCRjs z@hG5(EE*IFuEM&YS<og&I7>F9@}PSpf23L-ZuCY-F+4aMN2kdn@I^3Y%r8@(UBvlF zDN=(2JsOoPyW|u3Xe)#Ag%RH7ux}o5Dv0n-z#q|v`4EWV%Vg9|4g_%aL9O!I6_ItC zh_2HSUZ?R(>oXCdJPuzZrphGC3*vmlI|>I5c(Br0UB;Vuc6zCKWWqO25=k(8G)3H3 zQAG^48M90Ea0ZQYF6s-#i4U?+fv`tj5HTmYetgb_k69?di<lSZt|aN^^c7{(F!xr3 zYw{DJ71|dOkDxHZdoN-qlE8lw1EQE0Z-h<-kgUv27=yva%NrrJu_DSP5U|)sQA{wB zS3w;Sm6LC#T({ok%#XmMp^jJ)@n}HUqlu_T6Jb%O-kAMvBq<V55HUUuuF<11TnX<4 zNes9bpcr&vBo&8pQ;q@zWm{Mjak(=Qc4vIGyc@&^3i0POX-ig95Hblw(9HrOLHb)Q zWFiY_W)<JpqUjZjpb?qQLb<|+F!BLBD#qthR12?&wQ>+PsuufAd<PEqhxlP#Z!M{c zw-(QzWGsGQDeYrIiF7>X$FIyg0>n6ccoSd3!FS5(iY$-1qelY%?h2D30kWr@VngGs z+DH`!140MI{@SR>m!H0hMq4zimIcp4CukPF-ou#^N&ec4rxq0y@;7;yBfi=cQ*V_1 zVgSE1x%kBjIXqgPRg^ItaqEFMT2AXmw46(nQ;8ALMXm=r{87E{ihwZ87sdB~Xc3O; zdT2#iOTDbyi0}z72r&zpxyJ>dqVY(<XZOGfrtG(9D1ohGv@%hLuH%==%BiuRDaivK zuA=#;XROF2ML<`gs2m^`GUX{iUYdO`J{(CkN!LAOY<&1oB3Uy(zTn2r5)#<F6)+`x zj})#1S!8>R0J*(<g_RBovXez2{WBA9lm#cs8!o>4V&Rv}84=JTqPj%TB}_6dadlpN z`;o@ShTInw7ax@S1<D4*6QzUWDF2-ze#uHi`Ho7IO|>s7u8cQIt_xyZ*ov}zArV6# z&SyeMr$LV4h+7ztSNba}S`kH^{$c^*TKOOWwQIlGpha~JV9FB(O`!3R2;-}x&<%Xs z6(jWFmz`dw=w=}YnA!LUDX!H+vNS{<k)+YK3n3amrC`*W3n9&g5OP^j=2Q_8Z0BkJ z=%+Amj46OV6h!M{bj(BSqcdJ)z#RteHBMitB{_seK6=WPCon#p9jB;n<(SeImjmGC zh^U*7zNngQrl`^z<wIorYC{SB+Ze>reo+*kVT<Ds5F8sV;cV|Md`6EJ0wSo$&y>5A z-~zaS%rvOPDmmqr5a0Wa%JDamGOmM<!I429B|^&_qA?D4!cse*JX2QOD?tkSLF$C& zQlj2+hE5syX&@Q}hfH0R%2IFPBnsPTAI?ts#<5VUF-h*oC_F14X45N{drVH8Y8&mO zFpu%XZEgbP@kC(|z4(YCu_#rGrx~cPDL!}eN9$+Go-$fLM|GlJ?1(<FVMXitUNQ*F zN4@UEP*PM18F)Pckqo-nA%jRp0Rp=IMeB9OR<q3bqu3*p1Mi~%&lFKoKwKh=gWks~ zz@V6JYlVVAF<xaXe(os41p8ZxLGrw^tBZ+U`+x17TaP10701VR-|X>vW;Y>$C_<yW z?Hk#^0~aB3*+8TupzK1V708;ky*rcajJ@4%+hZjX3HN)#{TBErNPLX`2K$5r5`s5= z|8uHsk2aSF$P*rG>YO@VU0rpm>eM->s;kp+aJ9!{Jkz?>#n*U<_f}GPtW6ezw```5 z`0%e%=>=>a986$`%3Ewm#_lGF#z$~9)@NHqbg2Tgj544vxj-?iHyWEn7zeX>9Jc<B zS6hF<C{YTqSCV7&FzHCHZSl3Xkrr2grfu=vJVkuiMSMihVr-eB#}lKSkuRd(A_qc` zoLEGCVN91XFW)#<PTUiAeQ=NQNh7dI#^!Y(xj~giUT^53&pK3oK_O~8a;Pb5Y__dJ z6;A7?uuy}tQh2zG6(Z>bf=B}OP9lWclmzZZ6HQhrEEtH{LXKJVG6d(2(iwL$03X<- zQ$-V-b0%6+j0vezIyv&yw`6i;3v{gs7dyO%J~)z7Q#W}!Oj9k;XWFeicol^*6(+A| z?A+(`&t>7eNfMzFwSw04BrdT{>@E<-pQYh!0D~v2ODV+(^R(S$6*g=-=dRX-_VKR) zThEFoHdg@3(;-<2D3vkO7D*@g)btP+){)8T*hTfOK&@bO6=C5^%V{cI5aLE&X(4Tq z-P&+86c1`>8Q+q^?Fe3}W0PDK438%d%hn|`bTtu~jB#75?F|hsAW`)VV7uSeg`iAi zk&ux+hzFp2THCs6?>kW@9E4zt26t_w-gO?`wXu@2N@%k|eAjO2;?!rsM0-amXr`DC z*5J&6qL+MFS&Og;ShZG23G(0paS@j0wFgA|5vfO<BP|8oM*uMIN1`uWBZ1oa$_qjg z^LYqpgbHf15=3rRT<4LZn?*v@^e+KxQX%SF2Ici2B|b~bA-F+AFgJ)0bAt#mH;52t zr7*cc>~;xQcJsMY$G&OHC@{#kz3myn8<GcaNM3tG43WeJF>i>VdqW(fucx@&TnA;z z-Vba5u`x>jq%x815{+@iN>#~+cij1r<iRgu(AaA(keHXLD7ik88M=-z7Ym6{bwN5O z>kzG6%cBG;MQ!NkwV|J@za+tmG-#zolazHI<=R#s6EezoH+7c1b;Nmg(FokPcDi_) zK$1GJZ)r4f!};-?GG1CyLNaKc(>i}he&eQ##VMOUme@CiUdZKZTrCDAd6<E6IUrP{ zI}-GH?R0R&oeoKU>Pk``{0KnP<8t>SB#cGx;y$j3BC*s8wVaQ0OOOg^Qf%jwT6s+9 zyxxs#+nh}kRv@#@b2q{Pw*AZ?SJS+<tyxua!Q#4NQtJ<bvY!QAt<GpVx1U@2f-Dfp zJ`#(YmU&CcWmIV2Wz46KC7l4)JCmSsa#aJ8(EF-HI5&~pgc=~+=0dGq3|7@FTp*GI zb5rczs6>EHZjg+VBA8S%l1$kVLUr{mS5tPXNN-GYzq+u1wiBhrNGk|b7G*K$17tPT zoI#QWDWgLDIVCi=Um}l!Rq)7n*u;goc-w0gx@Rcu<&$mIDvr*`=168BXUEvv_y%Ee zY6wFiasfhUic<_?)dEQQB`WPnz?gh&b3IYBw1BcJGhpaHVBR?r6bkX7$Jci6@ZspX zmMQV#h>Em}lX}fJ4jMf`%4SrY7^hCmg-b-UP+E*{P1O*QEz8G*Gy_z*c2!XC$k+t- za$d&~ThY;Hqe+sm`Ow>1kSs+oKZ!vnnB9=p7Dd|-3XjOBQL%+P(fRdwL5ge%-5jul zZUd;WcO`@f?Jx*OG$%p<B!x38E^Gj$I6AEhfH*5a5HNOwZI?_!bRUP-p?npq<?(J! zF^!0Hxu(R(>Jt;vdMO|@vYSK1-P+H<<Wo_J%9}ngfY!9-&AMqzrU@JOq%oef9T7)5 zHM+*lvAOGX*EduEI*6A9yhh+8MU=;w<l4H1s=#pXDza8*YJ<$kYjsBCpw1X-51>MW zdi2_n8AZuFUBQmY<9gQQagSWF$Q6$~VUZ_{YhEPVR!nN+8hK8JR%&J7ykRj*3WY8m zS-*5lRTJhzK-h}Alfd0c;4WuBN$|oN?>_Lf?mY0+QRk`fnx_Hhg54N+I;nXILIsi{ z7-AANE}McOCW0Gc#azZ2ib}D>PU02;a;3N3R=1C)dVMAK4aO;Ja6a`<gE)<BNXEf? zIvw3%qSj3&x_Ff^AAOR(VF(&HJWIfJ2t?bUZD~&pMHF?XdX>9weNqtf?gHw2N2W(y zSMgYZrP5VA#es0DTx}Cl;;V0vHN!ymi6%8jo3tH~G;kU^8);>7#MAMJaz%U;To=a^ z-<}I%IzN|XtYrdbN<b(`pR(BK5|aU`ql?<LQO}O#8g)1AD(dF`UVT+j8$vaKR_)ce z=?-WO=i*A8Lh->25}q3-k_?LXsszkz7oe(c#pC<-EJv!wCUgWeLri@>NvG~BhcG|Z zJaiGGh2`<#O4mWv38b}RLvH1hk_~bBC3UBy3?{up(M@zD$Plyifc_3qsrh)B7=Zny zmBqFtQpYkF_etqGWLgHTFDmI_JSEug4ylBc1*yS;68WVs>7-@YrPg-D)^R{>+gF0% zGe16_WZA?mS+$WHwPjd4F1__jCK4MrUCD&in?F59|K`TCy;VFkUlKO3#|&s@f1<@P zR%a&2`V4ZfoP@k33(BxFt?h`HHf&N$N>>hnR_Yj|)M^^WU>O#mV?OL|j{<0>DXjsj zs5F~hp`O3mt2Xo2n_&QvSbzbU)b67h=8Vkr-I-qT4P|Z<39Hhg<DF!bN_G(ONl1t+ zaKT{w#o#<aX-pwkCP6p3Ak=0SlXAVyC>`D}uY{mqUdusc6lBZ3&~vV}iyM^CB+<-z zTJVEK{+b1$X%h*E4YFCi7lhRt*E6(?LqDCFv4K;}m^{M;h<Hf^HFM0YyCgH!TIA4F zGoR&WB-SjD8p5CyV)KF{P_h}D2A79Yz2>g4rfgdEviTm^r3mI^2jMIxo)gVgsCaG< zZ_S~!=Hm4nE6Vm@%zeNwObtpFK@(n>5|k`_Ut_eenk|AOe&GYDwNPJLxK9vhjTkR% z=_Ov6V?J59>n&c`^HYG&Yzs3fbbIh6FM`suaCR(eHEa<^NwV<18!x<77GC2jISWF? zAyoyD=sNS7L}$dR))^avBLWz5W(+y=9WiHCuK3KEa3)DpMQ1h~6vC)wFfY<&nCBwf z!5J@2(56ck!A%!i+7uQoE%&9V;n`}FXT0?1EbTeba?W0@csW0P#SixV+h4-z+Hd%= zn0|8RU&Ggy-g4qQmmkX;9Q%3if`V@<ctgRP3cjV_+X}v;;JXUGr{MbvexTro3Vx*E z#|nO;;HL_Hrr<3FZ!7q@f?p{3rGj56__c!HDEO^{-zoULf<Gwuqk?x7{7J!|6<A4i zO6fhFp?^<DZr;<`^Y?VN@4b}Za#nFxA6u&@qpI^XUFvY4lccJ>YdR}ygOKUP-|6+k z+f{P)bSRiz)kafcoT7Mg!s`ZA=PL+`(N!dIo`0I>=ATjUS%QIzqCXWx<#?L^;-dt& zcV651#{SovuQy(AzSexLajW@u^KNu)C;vMaEx6pu{{db#UacClH97y668xLsY?r)L z&19!yId*z90AKy-$zR~V*e4k6+-MAUZZwCD8?9mU+Ro)xwf77jndjM~|1zQyIk|l5 zr9+OK93ITs+I4{BIzZFa`3nc^ksBQx7YC(Q8%GDz@c}Y7XBAG@NOycXDW?ZRvU~Az zRAv4C>EX$!->*9TJ}aoacMjg|_qE?OTuJ-=;ds#RZ`8`FZB=`cD!s0%iC<YGYUHB4 zd)>O{>PEeq)y4ixX2y-KE(W8CcD23;C!ZpV{AmTxC|EJsF?;T_TzIo)Y1YUUzx)Z+ z;#SErDYeL<?Br_7TxF|d)WA8;^ZW9%RpV;aQT4Fx2BV^CV<z+F7b<eKSMYKK>B31X zMRf^{jrKy%ThsQ637e@o70+MFD5^(~rYCov)8;bwl<7c=`YfKJdQ9zoa_2gh`Fo~$ z;Bfc~+dr;-?Tb%NDd<f+6-D)s6JOx=7oOjsKkW2pQHnX$b>jm2@CVZ>KAy65y80M> zz%so*9Thk~bRM3nyF3RA^63k#q_1kW$9s*($9=YH;9Wl~Mpe%UcIuPGLxNJTFK;BU zx0fw`A>=Tc+NkaN{UOFH1GkT-w7}75v4KA0)O|~9SzWOwR(nz=H=Ck68y^o>rM)mv z&t64)`T6+8o8vL>2W@if0R{%z?WlNJTlD6|<5xa)rP^KKp$POUt5Z}Tu@g#omkG*- z*y&8iuZ~WyBc6)t!u0U=^>s93=-oQzU7c$8tFShVUK=A-d)4Qy_r6;<ud>hip!~c9 zMDfoDcXl3ZX3Z#SuK!xi);bcf`ziM&`5zPNC$6E&RmYkEb6QOmtZ`u;uhaOI%{<N( zIg6T&`j@qujm`)B_TM+n`(OQ_yx-$`>pkcnP}2MFT9<B(bsGB{9H=>Q9!ALH59ily zbz7Gj^=}_c{|X;zbsN2AbM@Q~e6N4mnj_6_qZ=ieUx`*J>Xd>}qtoh=)8;RWdd9t8 zL%$CH4~6(8qkNoruW>0!9(%O);naMa>y`ss4s1EF<-nE$TMleFu;sv(16vMkIk4rx imIGT3Y&r1%$$?(<-`Bf~KWj4=d6;^wNALnY6#oa8merjA literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/html5parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8ef42cf13c0d49ac1f4e2504d151d3c9aaefedb7 GIT binary patch literal 97770 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%0Dx zM^HVqrXUVgINe&73bvy@#B?=lM28%ThS(oJAw;l%4-;@<^8<ha1=a~3C#q8fPk4ev zhu~n*pmkDivZ!wsqLOodo!^{-s9i+OHbjMrUcossyvp>O1uQv{H?#oTMYY-n>?v8x zJqfn<5K2<7;ei~NHW<ke=fKr&Jw!CUBLv$>D;P+{+h#g<*su-udv_5=A`;A)X|N7@ zw{jfSmw@SWcwqmCcl@ip4To2jNoX}?f;?=E+@JhR#po~FjgXwXg=Lt>MVMu<zAFJE zq%jXN+<~#POD^iAxtk!pUa*^>$b&hU9AQ!c!$EIwnpOIYRUXpHXYn;?cUx?KpGIou zm3xv|#GIVA9B#;HI1p(x9QBl7GGM)MpkE{$zCq9I>15ha`JCpLnUCD@I=Q8%i8fj) zV&EFeM1eh)I$MB(z1Pk?aq6&qOHe^Y4(k1heh_9lp8CzFr9==sPSp}O87O~(*I_2c z-K^J7=}~2XILA5&?dwFAL(oQ)5IyISl>m+y+oO*7AdD&$=0AsLXkwX|h0%DC36U_% z&^{l4F<NE|!MN5`7i?4Tmhhvwp{L?@z(`Zpn%pV@=%Oic6m${O8cB=o_yf3M`>n>c zUc>Xx&06)^BZ})z6}Bi54Mk>wgA5iJy|Ma`n)goSfSq?9vvDQD4T(7g)a>vSO*Y z=wUE{KNQLShUytL5~FAE4fMx)^hQ?#{Sh5fDH6^uI-?&$-8HXS<8o5*Rnk^3dMnWj z4Lp<H!-BdZuJl4K`^-d<6J3#?>MfT<igt>=a8h(d_Fle}HCicXibOP`FI3Lxj{0gJ zuJ=djj>No8L|E^dXkUXQv1ky#U9d*zNq05UuM@ju3>Wad^(mD85breENjvch!?L$3 zlyFa#(mFa%D`-rATI~9^3?%hOY>F_&mAT~uf$@Vmg09USG?^j1)K!yt%vOwanlrp` z>})+vA;c$Ai~`yl@|Dz={gc3GiWW2?ppMX(u}=i-4UBfOkKL#*r|KUJz!$9_j)2c7 zu?8a9N<n?jNLqhI5~!I6;%$Ii;Mb+U+ZoKkFo!lp7&#$AGc^Jo6#vm%ZUmaBr1}bq zox?->$EM<6?O7bYIV>hvh|x%IVE|q&uPjx>gQ}gqv>K_m0<>?Ky(F0gduf<Z`n8d@ z%o(;4JkDqF74b|HV>LG969v}*Q~#2OFYzE6#V_*8XYtH7p4L;W*ANQqyt`2*?}yoW zL|UlCgvs-Kw1zuHVQX!{Xco`PT;Tzsqp+cWytry?15DULi?6Yk$CwbwEV-k>x!kM# zPX$Iubm;3gfTN1BY#sr(Y|2U8kO&1_%o5^a22Y9F?s{7LTw(Iez`Ym31Gh49u-T=! zjl^q5>7Xs-3YJLgl_kAB<%Qv}mDUX76x)D~%IZ%z9>2=N*Kq3*iYPM7(fn~XgH}l~ ztV#;341MrAcv`eINd!}wM5(qR_TWbI2vl6IQn~2`&QH{K2RStQU7$l-pbt7KM^%BG z=%-nQEH3DVCBVNrnh$Fk!VzBf>_q<Y%z6lE-ir%%CRfK9zaB9vizSo+1rmt&OYtK) zY2u5eG+w@p7uUDeii7nfRzoY9#UnmiBhc0Z9z%%-c0&A?b^*!DziI1&4lI9b7kJRO zvzhDyY5t?Q&?qE6jBv1mpMO#qJb3r96Dr)T6fW_aVZ?PDQPZ`nReYw`6R&<2<sd+b zAehKl{*bwjM*&hIR(i|5c_S!7!7Ib;-?8pm5WqwRLp^x3=xzJj`p%MHaon}t$EsWZ z8LcI?ekmr{h*T;y*~nE8dPQ46wKFQU1%Oy8$ZB<i{*RIOw+OwUeMio+wa+Zn7T|9w zzLCNB?KXT{=V;Ne8%C!;lF<<a@fjVNM`a2Xn#wloW_ufHXBGY_f#r0DwPZu!Z*pRL z%Rr%)RDX)%=J3e=u_^giyNts(hs#-OO#mp_u5MO2yGSl%l|v=9itQpU*5-j){rnf; zp#vqFzig~mRBlwkLB%HF)am8V=k)T|DmUNDUypLwx;~4qi%&if-#Y0-@)x}j2Zwg> z6CK>YVqPxD$Gj6x(0&G4t$=HJRlZ=0*54Y6V!>Rycl;FA#e0-aM3)oAa@lvpmn6YS z^+kf@Gi;kRzDfqq%`U)ef0?;C9z4~B414lKZOpd-`1{1fU3eUHv~SbSMeC9T2HW*( zFmI>viS;<yqc?pXiCZ2VM+&T)wd1XR=`aVibdmG}5AFWxLcqf`z5{ExtIe~XRWwfe zf9X@1(bO<qZK5|TZfTlsMOt<dnCKfrx@iSv+S-6t@V^mgL(roo(-v?eSUA3(#BUAB zv<);`jk--Ze9mzB9(>V!cQkz6tV%Zn>w0vU$pEZfjC1~|Fl`y3#SAqm)ghXtF<#=L zY?bRsS87H*1`Ydjk}r{XUPeMdQC#5jE^Fid3tr5yE}FgMQvMDbv9+|lC0hP!epbXP zTkgRP$FO#q4LT>GdU|sRFUTcz$yjn4jBPLnDrj8>$7i_^=@={aDIV%LV9;AeMzInh zktT{E`!i(fV@>fh@&FvN*VT8nu5{-lfwt@ot8DqP3T`~IrA-gD1Lhw3PKog8-AlMP zc+yR=F^s+%e#DX+;UO8K%oF*<s@$`ft-Y<@E39n~V{{r%OY9#awC|VjY0$A7YzT=X zBNG_q!;puYpvl*~)(XVk3{yn47JK-AqlisxOY$x;M9ttoZchNO1u7z=wcVXCh^^Yr z<=@Q6U5~c=Hp0z*gUfL=YuEwKb`UMHQ(n+L?Rf;Sw`I3i)4Sr~C?W~+K_HO;fYeR* zXx+5z<`@b=Cwx3Cg~w2K$hncUHRN?{xcu;V@st4{Wp7KrUt>Z3{AZ<@HG7)~vxlwL zj}l_&V^Rr3w23#OrRkRTi(pj#zdn9wLA}?G9~nKN@e{4c@7%7T_Ow{J6TL;OY$w4+ zC$Tmb3HD+Bu(Y<@Tter=hgqwX;0f>}dW+P^dfc1_yp7Lz0iW&$BU$3Z0Sd5zmNuf{ zaHMD`BTPg?axz*GF4GdH9YuPnd3Pbcz5$)!bWn+VJ{OjS_)lct*r(7Xj6zh@YVkBg z#z9>7GT4av3w&q}S?nLFDF15jz~S2?G&;Mk$EJs!TQSS;ZZOiAXvu57bKjW?1ekW! zIjVazVxtiN>77B55G(3LTx{{oXcHT?km-w!Ss5cnYy?JGu?{jti`ds9eF%>t2bq;y z1xURA8Pu$`kk2yB|45|RsC;DlBD4F_VAc>>rA0u&GVul8s2q5VV<RjF2BkplvC$#E zw%3c%5}+kZCjq*NnJw;fqQKWNvSk&rIMG<y&xR{O%4(X7k6nUoG~nnQX>GP(Bj_5g zUBVqt3+B&{s(MKiwqQ_+V{B1N=ejN3zNJl!L(Pp~_(rxLerBE=jW-_Yit+91xBaq0 z5+P}7o6r?@aPe_&-3~5;LBqwAdQ*ThM$7uPkHas9KqYe}puUpA>r4Q&=&gq>Xy0P7 zbv6K5w05@@vTujLS`0uLJ?XVVxt6H<5W0CiqAG}RoErFgmL?J*t8lydDZC9H^{+5t zbrf9n_SJUDbGLb&l<^#^h#$rtIaEk@YgDweT*qnCj<`Lz(G^|GQpFJnh1*}VQh&*V z*xA;yRFONV1YxJyv;*&CJ1GQvyJ*4+w2_Oj?^YY{v>xecC4ffJ3t-wHYzNK~h{tTp z)+W%x#&e6Ys<inAs6$yv8*Hqs1X=iyk%iL%Sr|wqi=F#)`}>%64PS{Ad?>bQ%jk7n zbwe+9=4Do0i$IJ*0uhL!?w#GqyEiXe4*gq-S!6Vy3t?6gm=ztM-S%5RUb9fM$Lx4` z05|9v4C|1zdna`nSdfwmX)ds=)@m!fjRJz&3K=qH9u`^EjvIe6?$$G8b>8b&ag=7> zL<hk>s)|Sx*NsqBEw8e+2o>DK6fLJ0dYYBL<H}<+HXuQLkd<LulZtf+LeWx@Z=vk; zPY4~c0os#w;gOM=HbqKJGDd}3wunwXqboeF;Dks`K4;rSbjtY>#di>1^0Oi|G2)^Y zo4C%6_BKXkOsT&C63wwv-XBLP|7vf;;hQTqK`h$Z*d0klsA_DNi-???3EMmlYn#)) zjUMY5x4uM^?kM(j3xyr&wXWsqFQWPZ5ojntx7cv97Sc7bs3gS0hCP`+Oyr@J-7|^> zMIm@IMMWlrk=N_BXgSD|(c>srlTjTL7z)F@A)&?*rh;8*#0qBA$J|FKNMePT0#TJl z4ieQ*qG)KyzXK<6Z&&{n2(FotXg?^%39pH2`zKjv{7`4D*6k2g%de$<b>l+7&k@cI zSg?MUz;&fQK3F#|1++o69)r-o41gA`_G$yI1A}c5<TP3*j36~2NC+YJ5h28W03!;X z(TVI~I+5`@us*&clJo?S<nM?iA_1?TF(U8!NmgAmM#c_6#wc31?l;0W&cL?y(|Q=# zUk>zBw20ddVwi*F++Z1mPuM;R@j@SAKXIW1c~|Qh2HuFi?>ZI!@7$d&4gYs;3nn>D zfNJo<VlU`15k9>)urmWfP(S%hOoFu8m<jT&px?XRT-Ex$;|qu{75svy+d2m5L$-x0 zNN8*eEU%vfG4m8Cvc+mtOo5P%=@Z1FYb;nw4{KD^uk)!jJ$TLuKg8^x<Kb?57~>V` z*1utokrAWm0U`Lo77b$I5F?M$tBS$(JD4o}o@|*LZkE}5CE_W3K7fGH5>zYL5$v6% z5ff+@!Im&D4muI03tFC%e)nSV2PO;?K~2vUJ{h=<!n^U_e~aGvT~-G_=^dB=lO0&r zwn{O?WT+oFuAahAjEcHW96eo^8@+)1T_MEtF9sSsD*kS8#@2XZc-CldcWEABS2-;N zRQoc=>HrKx@-F--!in4F_(4KPMHz5;lQ5-ZOOpry4wrZJb(A!RhxU(+#J_L16Iecy zVb%K@x3jFhfOs>ZeisgFv#hNiV6vRD$M||-ndJgD<bg+6FOY;j@VzsAqT;7_JUqbU z?E##r@*lJwVMDkZ#&2k*Plf?Z=br^MdIv>^Jw{p%iZspZH}ddS9-wiKjctnb;u`ek zFzlX<-Cq5Os<;=wO&z1Y!D4!O_#!{(Ywb-$bMv-w!S~+vBB$y$-7xR^hr}zR$cH+~ zkDKaw<0CF*qJsz*=*DOs)(+JJs1VxJYU^cL7l;oPIO~fiI$+|7*08_sT)o|4%b!0i zQxfg4B?}+F&RTPFHUUMW32d-_9oR%mVE3|yGC8*|^Y<oq!Kap`{=$2I0WWtWPoy9* z3=Zqu4ed;H5QPYkJFt(oZ~Uo&aO!0e%19JCm@RwGhSmh_wM!_-$$N9cHGrt6@<F2T z%WG8W?~y5OtAy?4zzRmIVS`l)52Wa6ftb*OYl-&y*mV{389c1>cc?8ULh?I41-Qv7 z{{yPr$13Mg8WE52_BwLF9je{#=WS7t!EB_ffQFiv6d};W95l$+xFx`~)nqWy;H9rL zX$!hc{UiJGYbdxIdcG5xMp!X|B7xJ_-;=tUp`NrAI?`4l*`5I5mc?y`s$kg(C!|P( zDHm$r9vhRmu`^I%8*wjKUt<Mp+m}GpjJ5&Rw*-?ke5>Ebv@VFEG1`w(S6=492@kcq z1m2?;m5<p$hUf3_BqSiOCE{?J*-bc&l)QlslYKQp9cHDR|EITWkCE#->oc>nyR%QP z?MWOvsj=f%HuX9WH^B*R<#qhp)ZSXPF~KcaX7}D%kG(rHK6lo#jnhCK+Bz~K|A15x zAVE~>TWx9n015Gu5P~9sKnO;PBASALKLV6L5P~-Re&0Fw-g9TpotfQix~n;J?qlx# z&iTG`zQ_5__jNaeZnuyjEe;K#1|idINRL)fGRU1V*})3hdoL$dHFiSeo~PHV61++* zE<B@Wh$^GLGw%-+H7{pv4K*vxGE*e7pIa7RyP<9C$})9EtgO?R`vDNRhm8j(Gh7TE z;NGZdlbMlRMG#3KF=~Gq&x@(d@PkLq8Kwq-#DqE1oQdbmXh!ALv-<v){$hG@lUO8_ zt)iLrUw`=SyYDIrSnqSs{SdF%&z>7+&w=w`5=P0iY&~$GsQ;1^F}Z0pZ*dQ2*n_m$ z!D4qzjuA&xlA$r3I^rEewSUq+e|5WTREMfhQ;pe-J{X*B6wGGyp=gN&QiO=1X6_oc z%rnA>g^)Oyw4r8!wMa11o_zLl<Dc^SLs2ow8fU(zqJF|erekMHP{Lm6OjBNh&Q>v5 zJYY>0DI=)Ise($@F}6i>C}7%c({YRxCO4l&%EG7FCoO?;V)c&Vj3R??73D>W=U`Q& zJL%L;D&N>l)q>%B6jM2=Vj1xsv*!ov5VFTP4<&G{Fru=UyolcDkEF=I;1r7WS(AXs zH<4n+*3jDF0vAF6_{~{GG`d+-(lxq82rSUlsEKjEPJV7cG&Pzhq0gDCOa?_=t}r(s zvqx?gxrD^WiYAKI%^knXbMdmmaI0p<=*KOJmUfEz9)C!J39U{tA5%_uZ;6>9U6D2G zeaxZlpWi8q^X+}+R-ee0#L_{%9}PF^leXBHE>K^^wFK)YQFc&$o+G%1>vz&2Y?Oxk zTwAjz5yM?fF>T=8A$T2j8u0ojEEwH>QI0O`ymKO&b~wwiFWbFc&7w)Pi5gUo{gF>t zlTd>$=u;4yml2X~$|1i*zGGSwk}292r^VRQO`IlWKF=N?%o!Lmkvhq}|G?1;p%^L7 zvx$j!Ey(I7Msjvru#mNCFx%y@2vJAy>@-AC4}i9f(9)E_z+a)ki7wC|>jE-B5M=pa zDgxVhN(=fd%cthHZGo3XMd%5sO(3<*p2CzaNTmltO4vpRTD91*K1jU_06L98wr9yg zs(T}LDv-u1I^2b0%KR(bkzLb?Cl*7VXirI}2p}amutsi)?L%z2zQTaYwX(x0+{3@% zRTLpR^buZ&S|sFm%A|u{!5i|1y%BHJ8}r7Q1d9o<nEcAS$Gg|t;@#(M^|pEUdk=UY z@V0wD=I!uydJlTLyxra&Z?Ct{d&ryg9`-)y?O)t~J9{zz*-Sa>O?d}iDqQUM9`PQ9 zXY+uZd(3+r=LWrl-iL6m;633ziSHrr$1&L)N?Afh400cCl;SyB)n3u+2>WcB#Xc5) zgtn>wWbqIWkFxkM3vRDcA7t$#ES_O;4n;F}=`nmB$LAnEAHwGee4bQ)$RB)yw;gA3 zp2cAnPqR2E1#dac+7m4H@$f0u-e7Tp#Yq&+d{8e{)eMhM@whKonP*X#r6lz%FMO26 zA-Q_3q}-wdd23R1kfDuGlv!cwJ@V-r7D>Ao9UUDVGiG6#fP~ZN9(;uFRZ&?#N_urS z90#-BUPS86As@kIWFnFyiQK!_goxNTi*(pajgw0^>X(qB+tiNv<>qL3Fw^jtaa64! zjkb@F0mz9xW{%F(v<2E6o>!%6z_|O(!opIeezw%O)Eq4PN0%_)G{?&N$7f0nRk_~W z%){k6@`P6#`gcgyJz`EG1GwLu;6e3TZRwhCezURcAFGthD}jHyvUsUcsV*YDH%<lh zrP6|M(KDrbb6id}O4WwkMF>tTA?&?WR;mlrVdZF8IT=<y&L5vFtpq`(R6V-1qIh9u z89CQkIpZr-0Haix2)sFpgPN*eLa!{|Xco%;$I9ivZ}9wC#OyT?Y%2Tb>i)vYQb|RC z<1y#zHFLv2**{-dlE<B2QS&S4umvAIribds<}brY-7G8;NgoGl#+NEpq@g~kN?rxs z*Boc1v=ki|8cd^#-k;np*p(j&cBSSS?8*UpI>zoo0=vse>^73vtsCq@hSAuSAA?2= zc9BM1V^{x9V^>aw*j+H#HNOEWJ&oNZ3%j0$-DQnkoFaDRF5;yeVz&(JmgEd7^I>H% ztSDl4(O`GpU>8)avAY~%S1MJ5-Q@&!YY}$q#IA+_*bNMJBfx>(0NB+x0J{x?-9|fh zYc_UOjNQc+>_*3eUG~0~3MqkxbJpikZ;mQI8V^B>8s6Mk@-D9gjdK@HBDm}<lB@=| zIFV5)$zXYVJ^r~oo)VweH6^wIln^tiVT;B`2(1;7d$HaI!}Q@y6%L?OWz=DbQ{K-w z<y?7S^m4>1KP+2r5Q804KEkCUU`{UH#Cj9YR1A{5!fE*5|KRr{Um{M=JQwhDFN#~4 zpBYDBq%4DcUw}E~Y81{rt0*@>0y=^(_3Pw7M2RjYS^HZQUkcepK6CSoa~0FoH*HEt zynX5LqF+U}T=kI?;ilv=-}M`O{~gq9k*r<Q<Q-oiNTaCG#y*U-I{G-Q0?MTle1 zMS}O^fGE~Bg(aCBE>{MEV?dUO-7xZfy+M>RzX^7%-p(?}JcX%6Xi!IxOdijm*GeIo z9p(CL{A}5I1%)1lurJEpRPT+J`+7Fe=eTs6Jcpy#MraDV`bikf=+VT4?4#b0q<#N$ zdD57Uv{c<~t_{nzcc3PWM=_ZCU)x~S5dvRUP4FzVYUHq1J~o=OS#NY}=9R3%q64AP z@AvQ)Z`?5E4Q82W8hxpb5v!!uX1|`I^JOqRh(wi}{>_IijpR~e8IChXqr^gt;UH6( zY8&7b>N219DHcmCejbGh5w%I%{BGk+b7Efkr7N|S#&P|m0CE<XTK<ZEBZ&Q@^&>vZ z=hRtTWg(VA4j4s4le&O`r0!>JD~s=-u;(g8DY|vIP)qz8Y4ZRoq)q0G+b;e$<DgTW z&LrPAj`KXG9g!tJDTymP46Spmakgn<ifEU*b%U5gkf+<2R_<f&V>u$#zR-88k4w&t zewdpi$ulVL1g>M-2~#HMbH=;sx7+T`sc-RK$x1$;<A!1sysXdZ9R|8C;r6hj@cIrM zGoRn+>zP}9c-NQpad5XW_UY`^yUY>#LjEl1*UKJ?AiWhrIxcr_!0-P4>Zz+tM1^<1 zCUnYQT|EWrXC7|s{-#!`S1Cz;F6S$q&~c;s4DXaxXHt&lNEBn$1{R#O#XPJ^tj)0a zE@}BMSrb~35OG3`LP>XV0Sltf@VaobA#&oGs^?$Vu3EpwD=iZ&fAnXh7@nsG=_sh= z-W*cj<e1HS95(q0gbB!r=N1>xBx!~_TtEj}Ic~z7x9OsvBTN@b>K|oIi2e?1B;`&K z&hMG2I^I`fQ;eNf2wRi+FkB}_`wElD;C#P&9&cN~)1$vWQ+vO%qU>}qt?4onmqa^- z-RjmX;7Y1nku4Sh&ev$E)q%|0jIeLxU9Cpg&yn0#YlMB97#L-bN-#+}uV7E5%Z)49 z1+jjIx5^*C`4Rn&!i-Tig@ilURo@{5ltMB&=i)-kdsF;LqE$Fj69zoYl(%RF=c*fB zL_=8!o0teBre+z+Z=o*El(rDjI_Q20H+?^Xvd?Lpc0&ohj~35JTwpUvzS2iKP|=Wv zZU+Lb78x=obqJD7+3WBNNTM@UA~EWqEx&_jgi_H<s9Ua|T};LQ%?5G$C*Q$VK9{j7 zrBPubpTOO&^woBO)^<nlW+o+>|6kPe?se)GAVWLuDaZ#2_##$E(@xm$NfFD?3)X5` zGZ=s=+unmD&zHq_3k}nFq>j~Y8?9$}wuGV+anX|ZE}KYBq{C>YY^+RaXuBmiqOh=~ z&>5KA4X&P=(vY=?BLiW<O-u7KRzYj__HHP<E$xJvx9TfOUd?f7eFPF1*=c~UmrC7) zD1Fqz&NyZD4@ZOu$K#&n06+$vZapz<$3|*zw`TTh8*4NQkFbde{JPeGqt4WRExM7$ zDD2KR@(R10vy+a8AxuFm!@>&0yv`19Q;M47$#;F1^f!S!VG|ya)MR24hE@1yQ<?8` zxIMHAi-i{I4J@=sJm}?NnHBpmzWZq-#`gg2#P}Yhtr*`0+Kcf$M4K_bhiNy)_lUO{ zf?4tAgAOJP5kgUqHxVupTsR75Q3hP;Tv!6(=Zz0*zwu!m0C&ziV<1ulW||Sb${ME` z8Ith=ua!T++teSkSOh7nAE1U<^&%UM@$7%G5WMWb_2yVOJ4r)gf7aPrSz6Y@(woL* zHEi~(x%*}k9v4A1ch^p;+Cdf0scz@Z@MW3`=jJNaN@H#=vKOEkF$;SX2Qrn2AwpbU z`nbueclXo{#ywTH-+#{zs=MOZL^9sH23iXpbzP+8$Y3kE@<~lske{1PcmxV#rW$G} z6jQ!Th@1;MP5*azoiK|8loq}=iIa45L_)rZ!Pcs{k;edyh(6!x0vQQ*zXh2~KxpmB z1bJheCKzzUmgqID`!lj4#8I6g8|i#$5s<ybaW0|lj}Tmno|I{vVp>Ol-O#S1I5Q6z z53aFG!zm&GWF*tXQZH9kppJvHTmE(6>~<REScb7ER+wC`WJ@mdWZc`Zrn&dzB?&hq zj}9WsMME2rQ(O*~g7z7OmZW~!mxs9qj;j|EvrrzIKhN}C9yB>h`sQ@JA!z(J@CKQ; z6Iq1Aam$r#t8T;{nc}e)M8P|3QWya4HlH`mA{y{o-#^cDJ;{K?>C^1ZQTzlB&PX^t z3M<g2zLZUVAqcjh5T08reb^4Bp#)_0#j2=-lE;Yzb+{c&LzwM$7=gzfAo>+{DW^=u z*-3HCD-J5X=Yvh}v>v{pW%O?(h#cOq<4?d#jEmvizn(8(VFAxtz@_Mqvlsu?+dFKJ zL(mcFEYUd$Sts%hy8w8)%Q`6=)TteFuaA~(;=MkDMi<bsjYu>jPKic3{vQECyyHf# z$p&$ncp$e5rIbiQagj}X=d7PC;vyjd=4p#?O=ymHr`RJRW*2ker0`&mH%qH8uR(rz zK7!gEF)|(MZd+W^dEft_k6=WRDNp9OZmK+~rDOr>vPn7s4Ozx}Wq-S@rGuFLmBf+~ z_W7#jIC4Ob?a}fEIG{^F>d>NgCP>0NhmT0?F+*d`<W$bhHa7{(iRUKpP$FVF*nT)d zFIjl#k<7cP+}#C`ofZZ{2J;^JpFHMDqW@jKDT#h^u$eXkx2SG0n~9lAH<fx*`>UQM zcw90Ce;F6fBK$=yrt+4vxOsh*YDm+YoH3LHTq(MkwI2mc=}e~GtZlR-ZMYtEa*ia^ z2$#uZE}_)lX0MQk)Y+Tbh{E_?&|h79Zye29KlX6l8aJubmh96s<&v|8jCH-_ZriIP zTeW0R7d7ZD+^znZUDIJ?(-8D?7KARJQdjqc>SQNdbvh#utC-CQUhV=WuYbw{^TTNZ zkh>#$itV=p@8Gl<YV0zZV*6XdunVPVEBp%JaO5L~Wvx6lztWgmtTm>{j@M|-rEK~O zY#cQ+V_846x(2SDC%2)Z8&7^4Fn-2DMJfktK}E=v*V6*K-HD2bRcj4PTDT??`yDnj zVS;sql5`D^u(9p@I?}!$Mn8t+mejrt;kB(OJm74tVT<pjt#<*+FR!_+p)lJq%e8Pv zu{ytum$jOn34n52oi{tWw?<ee@Ee$(nSn5NNWPTHCEsV$bL!%!fZu~!b_mT$=a``h zx?L@6SG)=?_Gz1qH8d?|;~p96ud?g$vDB_~8MeLc>&I4qlYmh8Ma;X-Oe@j(KVsJU zTNaeAy)`j$JE82j6ui#t^$QlL(;c~w6V#qqEXQm(=h;T_be7tyZIL|mi&hKZ|JN4M zyjy4gXqTwJVnORl*^mZp$XeR?Xk<M|CyZ4q;1!IpuUmlr#45Tq1a!8h31-bkMkm`# zGWlM~gbMgK*`7!N?<{B~Nj+>)2d>^-rR~nedu<H4<{N8nObgrYU^{iOZ4!ny;dS8M zTT*EFR|qtz6#N@m^{oHAx{L=;Zc${{>Ze$|!GeUVw!jLZwz8l|r~ZP)w^+Q%bKhX? zn=BY`Si+)7JZssrslLryUgU+}W9{3ld2GWRi!xuDRkV>#Zd1?lBG(kun=Ia8@qHHm z%VHaUzn#S{7Jtp+Z&<v=;%yfH!h)#+CG~>@GL@iFvVB-KO^Jh=ER>7UShRaZ;YHe? z5QQfB(o-nti5=8Y$>a)K3xnGxCtidz->%|;;$rbg@tNX_nehL);!YfGDozzo7LOL^ zi$7gFUG$3kib3&_;#0*v#l6M7tMO!)w@0Iw(+o!szXJvhp$914rQnkc3Fdb82z@J& zXQz>sC4OxDdI_6}c?b8>YR7XP8&6&Ye7T9IL~F%-E)j7MpWs0h@Gal=$=nOs7jhyW z!A0wJJinZ4^)vrP+zTn@2)>%xE6waRVDu;1r4%fcbR%8O|AEAZ)0uqs=5Fm>KUZpC zTLv^a-%5ZHd646o6xtQN1=JJ@ocKKJe0X!B>ib?WryoSWtq^(gYI*CIaP!~sty+~p zIwq_%DxOs<C{8TMWP}>O+4N`d3AUqvt7_&-L5)_>rRZjKA$;_6x3Hh?Rl1^LPj+5C zhWoVe&u$c-Wi*`Y_qaICQ*y_0cu{vp+$aBm3vWiyA%RdHzQPiPW&u~CKM-H$2tFcr zhvp_P3*U_#An8-raqZ@P$Caw79hK^idPxO7Hty9HR@f;7^l98-?dkt39ts$7A>G9% z{SyIVcMu$THYP>($a%c#Vg52aU=Plom^{!No|`MLU;~LiH>ZeRMM6@1Msq{GQa><v z4VqF-9SADdWuR-MKEmrG@ET{JD})ORG@Ad7za3%$Kr(6s#l?*c<@@t1l_k$t!GZZw z;Hyzy97E9@f(tp=L$wjeeh2N}JHg8vS#Yvbn^_Ps>K+#22EK*0`&evc@nsg<Scq3R z7roU7SUkvLKMM{yb(WLMPSl!%%l>i=e(o|zHBk|x&7tGh7kmjkBHice>1N^Za?QhT uD(+U)n_Ljf5fs3jxZ&s2*zlI&t%XrcHZNvQj)zlBr|;8+!Ay2|@c#j6CB?-6 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/__pycache__/serializer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..55ddcb75302618c134da553b625a577c3059437e GIT binary patch literal 10786 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py new file mode 100644 index 0000000..4c77717 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_ihatexml.py @@ -0,0 +1,288 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +import warnings + +from .constants import DataLossWarning + +baseChar = """ +[#x0041-#x005A] | [#x0061-#x007A] | [#x00C0-#x00D6] | [#x00D8-#x00F6] | +[#x00F8-#x00FF] | [#x0100-#x0131] | [#x0134-#x013E] | [#x0141-#x0148] | +[#x014A-#x017E] | [#x0180-#x01C3] | [#x01CD-#x01F0] | [#x01F4-#x01F5] | +[#x01FA-#x0217] | [#x0250-#x02A8] | [#x02BB-#x02C1] | #x0386 | +[#x0388-#x038A] | #x038C | [#x038E-#x03A1] | [#x03A3-#x03CE] | +[#x03D0-#x03D6] | #x03DA | #x03DC | #x03DE | #x03E0 | [#x03E2-#x03F3] | +[#x0401-#x040C] | [#x040E-#x044F] | [#x0451-#x045C] | [#x045E-#x0481] | +[#x0490-#x04C4] | [#x04C7-#x04C8] | [#x04CB-#x04CC] | [#x04D0-#x04EB] | +[#x04EE-#x04F5] | [#x04F8-#x04F9] | [#x0531-#x0556] | #x0559 | +[#x0561-#x0586] | [#x05D0-#x05EA] | [#x05F0-#x05F2] | [#x0621-#x063A] | +[#x0641-#x064A] | [#x0671-#x06B7] | [#x06BA-#x06BE] | [#x06C0-#x06CE] | +[#x06D0-#x06D3] | #x06D5 | [#x06E5-#x06E6] | [#x0905-#x0939] | #x093D | +[#x0958-#x0961] | [#x0985-#x098C] | [#x098F-#x0990] | [#x0993-#x09A8] | +[#x09AA-#x09B0] | #x09B2 | [#x09B6-#x09B9] | [#x09DC-#x09DD] | +[#x09DF-#x09E1] | [#x09F0-#x09F1] | [#x0A05-#x0A0A] | [#x0A0F-#x0A10] | +[#x0A13-#x0A28] | [#x0A2A-#x0A30] | [#x0A32-#x0A33] | [#x0A35-#x0A36] | +[#x0A38-#x0A39] | [#x0A59-#x0A5C] | #x0A5E | [#x0A72-#x0A74] | +[#x0A85-#x0A8B] | #x0A8D | [#x0A8F-#x0A91] | [#x0A93-#x0AA8] | +[#x0AAA-#x0AB0] | [#x0AB2-#x0AB3] | [#x0AB5-#x0AB9] | #x0ABD | #x0AE0 | +[#x0B05-#x0B0C] | [#x0B0F-#x0B10] | [#x0B13-#x0B28] | [#x0B2A-#x0B30] | +[#x0B32-#x0B33] | [#x0B36-#x0B39] | #x0B3D | [#x0B5C-#x0B5D] | +[#x0B5F-#x0B61] | [#x0B85-#x0B8A] | [#x0B8E-#x0B90] | [#x0B92-#x0B95] | +[#x0B99-#x0B9A] | #x0B9C | [#x0B9E-#x0B9F] | [#x0BA3-#x0BA4] | +[#x0BA8-#x0BAA] | [#x0BAE-#x0BB5] | [#x0BB7-#x0BB9] | [#x0C05-#x0C0C] | +[#x0C0E-#x0C10] | [#x0C12-#x0C28] | [#x0C2A-#x0C33] | [#x0C35-#x0C39] | +[#x0C60-#x0C61] | [#x0C85-#x0C8C] | [#x0C8E-#x0C90] | [#x0C92-#x0CA8] | +[#x0CAA-#x0CB3] | [#x0CB5-#x0CB9] | #x0CDE | [#x0CE0-#x0CE1] | +[#x0D05-#x0D0C] | [#x0D0E-#x0D10] | [#x0D12-#x0D28] | [#x0D2A-#x0D39] | +[#x0D60-#x0D61] | [#x0E01-#x0E2E] | #x0E30 | [#x0E32-#x0E33] | +[#x0E40-#x0E45] | [#x0E81-#x0E82] | #x0E84 | [#x0E87-#x0E88] | #x0E8A | +#x0E8D | [#x0E94-#x0E97] | [#x0E99-#x0E9F] | [#x0EA1-#x0EA3] | #x0EA5 | +#x0EA7 | [#x0EAA-#x0EAB] | [#x0EAD-#x0EAE] | #x0EB0 | [#x0EB2-#x0EB3] | +#x0EBD | [#x0EC0-#x0EC4] | [#x0F40-#x0F47] | [#x0F49-#x0F69] | +[#x10A0-#x10C5] | [#x10D0-#x10F6] | #x1100 | [#x1102-#x1103] | +[#x1105-#x1107] | #x1109 | [#x110B-#x110C] | [#x110E-#x1112] | #x113C | +#x113E | #x1140 | #x114C | #x114E | #x1150 | [#x1154-#x1155] | #x1159 | +[#x115F-#x1161] | #x1163 | #x1165 | #x1167 | #x1169 | [#x116D-#x116E] | +[#x1172-#x1173] | #x1175 | #x119E | #x11A8 | #x11AB | [#x11AE-#x11AF] | +[#x11B7-#x11B8] | #x11BA | [#x11BC-#x11C2] | #x11EB | #x11F0 | #x11F9 | +[#x1E00-#x1E9B] | [#x1EA0-#x1EF9] | [#x1F00-#x1F15] | [#x1F18-#x1F1D] | +[#x1F20-#x1F45] | [#x1F48-#x1F4D] | [#x1F50-#x1F57] | #x1F59 | #x1F5B | +#x1F5D | [#x1F5F-#x1F7D] | [#x1F80-#x1FB4] | [#x1FB6-#x1FBC] | #x1FBE | +[#x1FC2-#x1FC4] | [#x1FC6-#x1FCC] | [#x1FD0-#x1FD3] | [#x1FD6-#x1FDB] | +[#x1FE0-#x1FEC] | [#x1FF2-#x1FF4] | [#x1FF6-#x1FFC] | #x2126 | +[#x212A-#x212B] | #x212E | [#x2180-#x2182] | [#x3041-#x3094] | +[#x30A1-#x30FA] | [#x3105-#x312C] | [#xAC00-#xD7A3]""" + +ideographic = """[#x4E00-#x9FA5] | #x3007 | [#x3021-#x3029]""" + +combiningCharacter = """ +[#x0300-#x0345] | [#x0360-#x0361] | [#x0483-#x0486] | [#x0591-#x05A1] | +[#x05A3-#x05B9] | [#x05BB-#x05BD] | #x05BF | [#x05C1-#x05C2] | #x05C4 | +[#x064B-#x0652] | #x0670 | [#x06D6-#x06DC] | [#x06DD-#x06DF] | +[#x06E0-#x06E4] | [#x06E7-#x06E8] | [#x06EA-#x06ED] | [#x0901-#x0903] | +#x093C | [#x093E-#x094C] | #x094D | [#x0951-#x0954] | [#x0962-#x0963] | +[#x0981-#x0983] | #x09BC | #x09BE | #x09BF | [#x09C0-#x09C4] | +[#x09C7-#x09C8] | [#x09CB-#x09CD] | #x09D7 | [#x09E2-#x09E3] | #x0A02 | +#x0A3C | #x0A3E | #x0A3F | [#x0A40-#x0A42] | [#x0A47-#x0A48] | +[#x0A4B-#x0A4D] | [#x0A70-#x0A71] | [#x0A81-#x0A83] | #x0ABC | +[#x0ABE-#x0AC5] | [#x0AC7-#x0AC9] | [#x0ACB-#x0ACD] | [#x0B01-#x0B03] | +#x0B3C | [#x0B3E-#x0B43] | [#x0B47-#x0B48] | [#x0B4B-#x0B4D] | +[#x0B56-#x0B57] | [#x0B82-#x0B83] | [#x0BBE-#x0BC2] | [#x0BC6-#x0BC8] | +[#x0BCA-#x0BCD] | #x0BD7 | [#x0C01-#x0C03] | [#x0C3E-#x0C44] | +[#x0C46-#x0C48] | [#x0C4A-#x0C4D] | [#x0C55-#x0C56] | [#x0C82-#x0C83] | +[#x0CBE-#x0CC4] | [#x0CC6-#x0CC8] | [#x0CCA-#x0CCD] | [#x0CD5-#x0CD6] | +[#x0D02-#x0D03] | [#x0D3E-#x0D43] | [#x0D46-#x0D48] | [#x0D4A-#x0D4D] | +#x0D57 | #x0E31 | [#x0E34-#x0E3A] | [#x0E47-#x0E4E] | #x0EB1 | +[#x0EB4-#x0EB9] | [#x0EBB-#x0EBC] | [#x0EC8-#x0ECD] | [#x0F18-#x0F19] | +#x0F35 | #x0F37 | #x0F39 | #x0F3E | #x0F3F | [#x0F71-#x0F84] | +[#x0F86-#x0F8B] | [#x0F90-#x0F95] | #x0F97 | [#x0F99-#x0FAD] | +[#x0FB1-#x0FB7] | #x0FB9 | [#x20D0-#x20DC] | #x20E1 | [#x302A-#x302F] | +#x3099 | #x309A""" + +digit = """ +[#x0030-#x0039] | [#x0660-#x0669] | [#x06F0-#x06F9] | [#x0966-#x096F] | +[#x09E6-#x09EF] | [#x0A66-#x0A6F] | [#x0AE6-#x0AEF] | [#x0B66-#x0B6F] | +[#x0BE7-#x0BEF] | [#x0C66-#x0C6F] | [#x0CE6-#x0CEF] | [#x0D66-#x0D6F] | +[#x0E50-#x0E59] | [#x0ED0-#x0ED9] | [#x0F20-#x0F29]""" + +extender = """ +#x00B7 | #x02D0 | #x02D1 | #x0387 | #x0640 | #x0E46 | #x0EC6 | #x3005 | +#[#x3031-#x3035] | [#x309D-#x309E] | [#x30FC-#x30FE]""" + +letter = " | ".join([baseChar, ideographic]) + +# Without the +name = " | ".join([letter, digit, ".", "-", "_", combiningCharacter, + extender]) +nameFirst = " | ".join([letter, "_"]) + +reChar = re.compile(r"#x([\d|A-F]{4,4})") +reCharRange = re.compile(r"\[#x([\d|A-F]{4,4})-#x([\d|A-F]{4,4})\]") + + +def charStringToList(chars): + charRanges = [item.strip() for item in chars.split(" | ")] + rv = [] + for item in charRanges: + foundMatch = False + for regexp in (reChar, reCharRange): + match = regexp.match(item) + if match is not None: + rv.append([hexToInt(item) for item in match.groups()]) + if len(rv[-1]) == 1: + rv[-1] = rv[-1] * 2 + foundMatch = True + break + if not foundMatch: + assert len(item) == 1 + + rv.append([ord(item)] * 2) + rv = normaliseCharList(rv) + return rv + + +def normaliseCharList(charList): + charList = sorted(charList) + for item in charList: + assert item[1] >= item[0] + rv = [] + i = 0 + while i < len(charList): + j = 1 + rv.append(charList[i]) + while i + j < len(charList) and charList[i + j][0] <= rv[-1][1] + 1: + rv[-1][1] = charList[i + j][1] + j += 1 + i += j + return rv + +# We don't really support characters above the BMP :( +max_unicode = int("FFFF", 16) + + +def missingRanges(charList): + rv = [] + if charList[0] != 0: + rv.append([0, charList[0][0] - 1]) + for i, item in enumerate(charList[:-1]): + rv.append([item[1] + 1, charList[i + 1][0] - 1]) + if charList[-1][1] != max_unicode: + rv.append([charList[-1][1] + 1, max_unicode]) + return rv + + +def listToRegexpStr(charList): + rv = [] + for item in charList: + if item[0] == item[1]: + rv.append(escapeRegexp(chr(item[0]))) + else: + rv.append(escapeRegexp(chr(item[0])) + "-" + + escapeRegexp(chr(item[1]))) + return "[%s]" % "".join(rv) + + +def hexToInt(hex_str): + return int(hex_str, 16) + + +def escapeRegexp(string): + specialCharacters = (".", "^", "$", "*", "+", "?", "{", "}", + "[", "]", "|", "(", ")", "-") + for char in specialCharacters: + string = string.replace(char, "\\" + char) + + return string + +# output from the above +nonXmlNameBMPRegexp = re.compile('[\x00-,/:-@\\[-\\^`\\{-\xb6\xb8-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u02cf\u02d2-\u02ff\u0346-\u035f\u0362-\u0385\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482\u0487-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u0590\u05a2\u05ba\u05be\u05c0\u05c3\u05c5-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u063f\u0653-\u065f\u066a-\u066f\u06b8-\u06b9\u06bf\u06cf\u06d4\u06e9\u06ee-\u06ef\u06fa-\u0900\u0904\u093a-\u093b\u094e-\u0950\u0955-\u0957\u0964-\u0965\u0970-\u0980\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09bb\u09bd\u09c5-\u09c6\u09c9-\u09ca\u09ce-\u09d6\u09d8-\u09db\u09de\u09e4-\u09e5\u09f2-\u0a01\u0a03-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a3b\u0a3d\u0a43-\u0a46\u0a49-\u0a4a\u0a4e-\u0a58\u0a5d\u0a5f-\u0a65\u0a75-\u0a80\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abb\u0ac6\u0aca\u0ace-\u0adf\u0ae1-\u0ae5\u0af0-\u0b00\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3b\u0b44-\u0b46\u0b49-\u0b4a\u0b4e-\u0b55\u0b58-\u0b5b\u0b5e\u0b62-\u0b65\u0b70-\u0b81\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0bbd\u0bc3-\u0bc5\u0bc9\u0bce-\u0bd6\u0bd8-\u0be6\u0bf0-\u0c00\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c3d\u0c45\u0c49\u0c4e-\u0c54\u0c57-\u0c5f\u0c62-\u0c65\u0c70-\u0c81\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cbd\u0cc5\u0cc9\u0cce-\u0cd4\u0cd7-\u0cdd\u0cdf\u0ce2-\u0ce5\u0cf0-\u0d01\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d3d\u0d44-\u0d45\u0d49\u0d4e-\u0d56\u0d58-\u0d5f\u0d62-\u0d65\u0d70-\u0e00\u0e2f\u0e3b-\u0e3f\u0e4f\u0e5a-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eba\u0ebe-\u0ebf\u0ec5\u0ec7\u0ece-\u0ecf\u0eda-\u0f17\u0f1a-\u0f1f\u0f2a-\u0f34\u0f36\u0f38\u0f3a-\u0f3d\u0f48\u0f6a-\u0f70\u0f85\u0f8c-\u0f8f\u0f96\u0f98\u0fae-\u0fb0\u0fb8\u0fba-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u20cf\u20dd-\u20e0\u20e2-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3004\u3006\u3008-\u3020\u3030\u3036-\u3040\u3095-\u3098\u309b-\u309c\u309f-\u30a0\u30fb\u30ff-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +nonXmlNameFirstBMPRegexp = re.compile('[\x00-@\\[-\\^`\\{-\xbf\xd7\xf7\u0132-\u0133\u013f-\u0140\u0149\u017f\u01c4-\u01cc\u01f1-\u01f3\u01f6-\u01f9\u0218-\u024f\u02a9-\u02ba\u02c2-\u0385\u0387\u038b\u038d\u03a2\u03cf\u03d7-\u03d9\u03db\u03dd\u03df\u03e1\u03f4-\u0400\u040d\u0450\u045d\u0482-\u048f\u04c5-\u04c6\u04c9-\u04ca\u04cd-\u04cf\u04ec-\u04ed\u04f6-\u04f7\u04fa-\u0530\u0557-\u0558\u055a-\u0560\u0587-\u05cf\u05eb-\u05ef\u05f3-\u0620\u063b-\u0640\u064b-\u0670\u06b8-\u06b9\u06bf\u06cf\u06d4\u06d6-\u06e4\u06e7-\u0904\u093a-\u093c\u093e-\u0957\u0962-\u0984\u098d-\u098e\u0991-\u0992\u09a9\u09b1\u09b3-\u09b5\u09ba-\u09db\u09de\u09e2-\u09ef\u09f2-\u0a04\u0a0b-\u0a0e\u0a11-\u0a12\u0a29\u0a31\u0a34\u0a37\u0a3a-\u0a58\u0a5d\u0a5f-\u0a71\u0a75-\u0a84\u0a8c\u0a8e\u0a92\u0aa9\u0ab1\u0ab4\u0aba-\u0abc\u0abe-\u0adf\u0ae1-\u0b04\u0b0d-\u0b0e\u0b11-\u0b12\u0b29\u0b31\u0b34-\u0b35\u0b3a-\u0b3c\u0b3e-\u0b5b\u0b5e\u0b62-\u0b84\u0b8b-\u0b8d\u0b91\u0b96-\u0b98\u0b9b\u0b9d\u0ba0-\u0ba2\u0ba5-\u0ba7\u0bab-\u0bad\u0bb6\u0bba-\u0c04\u0c0d\u0c11\u0c29\u0c34\u0c3a-\u0c5f\u0c62-\u0c84\u0c8d\u0c91\u0ca9\u0cb4\u0cba-\u0cdd\u0cdf\u0ce2-\u0d04\u0d0d\u0d11\u0d29\u0d3a-\u0d5f\u0d62-\u0e00\u0e2f\u0e31\u0e34-\u0e3f\u0e46-\u0e80\u0e83\u0e85-\u0e86\u0e89\u0e8b-\u0e8c\u0e8e-\u0e93\u0e98\u0ea0\u0ea4\u0ea6\u0ea8-\u0ea9\u0eac\u0eaf\u0eb1\u0eb4-\u0ebc\u0ebe-\u0ebf\u0ec5-\u0f3f\u0f48\u0f6a-\u109f\u10c6-\u10cf\u10f7-\u10ff\u1101\u1104\u1108\u110a\u110d\u1113-\u113b\u113d\u113f\u1141-\u114b\u114d\u114f\u1151-\u1153\u1156-\u1158\u115a-\u115e\u1162\u1164\u1166\u1168\u116a-\u116c\u116f-\u1171\u1174\u1176-\u119d\u119f-\u11a7\u11a9-\u11aa\u11ac-\u11ad\u11b0-\u11b6\u11b9\u11bb\u11c3-\u11ea\u11ec-\u11ef\u11f1-\u11f8\u11fa-\u1dff\u1e9c-\u1e9f\u1efa-\u1eff\u1f16-\u1f17\u1f1e-\u1f1f\u1f46-\u1f47\u1f4e-\u1f4f\u1f58\u1f5a\u1f5c\u1f5e\u1f7e-\u1f7f\u1fb5\u1fbd\u1fbf-\u1fc1\u1fc5\u1fcd-\u1fcf\u1fd4-\u1fd5\u1fdc-\u1fdf\u1fed-\u1ff1\u1ff5\u1ffd-\u2125\u2127-\u2129\u212c-\u212d\u212f-\u217f\u2183-\u3006\u3008-\u3020\u302a-\u3040\u3095-\u30a0\u30fb-\u3104\u312d-\u4dff\u9fa6-\uabff\ud7a4-\uffff]') # noqa + +# Simpler things +nonPubidCharRegexp = re.compile("[^\x20\x0D\x0Aa-zA-Z0-9\\-'()+,./:=?;!*#@$_%]") + + +class InfosetFilter(object): + replacementRegexp = re.compile(r"U[\dA-F]{5,5}") + + def __init__(self, + dropXmlnsLocalName=False, + dropXmlnsAttrNs=False, + preventDoubleDashComments=False, + preventDashAtCommentEnd=False, + replaceFormFeedCharacters=True, + preventSingleQuotePubid=False): + + self.dropXmlnsLocalName = dropXmlnsLocalName + self.dropXmlnsAttrNs = dropXmlnsAttrNs + + self.preventDoubleDashComments = preventDoubleDashComments + self.preventDashAtCommentEnd = preventDashAtCommentEnd + + self.replaceFormFeedCharacters = replaceFormFeedCharacters + + self.preventSingleQuotePubid = preventSingleQuotePubid + + self.replaceCache = {} + + def coerceAttribute(self, name, namespace=None): + if self.dropXmlnsLocalName and name.startswith("xmlns:"): + warnings.warn("Attributes cannot begin with xmlns", DataLossWarning) + return None + elif (self.dropXmlnsAttrNs and + namespace == "http://www.w3.org/2000/xmlns/"): + warnings.warn("Attributes cannot be in the xml namespace", DataLossWarning) + return None + else: + return self.toXmlName(name) + + def coerceElement(self, name): + return self.toXmlName(name) + + def coerceComment(self, data): + if self.preventDoubleDashComments: + while "--" in data: + warnings.warn("Comments cannot contain adjacent dashes", DataLossWarning) + data = data.replace("--", "- -") + if data.endswith("-"): + warnings.warn("Comments cannot end in a dash", DataLossWarning) + data += " " + return data + + def coerceCharacters(self, data): + if self.replaceFormFeedCharacters: + for _ in range(data.count("\x0C")): + warnings.warn("Text cannot contain U+000C", DataLossWarning) + data = data.replace("\x0C", " ") + # Other non-xml characters + return data + + def coercePubid(self, data): + dataOutput = data + for char in nonPubidCharRegexp.findall(data): + warnings.warn("Coercing non-XML pubid", DataLossWarning) + replacement = self.getReplacementCharacter(char) + dataOutput = dataOutput.replace(char, replacement) + if self.preventSingleQuotePubid and dataOutput.find("'") >= 0: + warnings.warn("Pubid cannot contain single quote", DataLossWarning) + dataOutput = dataOutput.replace("'", self.getReplacementCharacter("'")) + return dataOutput + + def toXmlName(self, name): + nameFirst = name[0] + nameRest = name[1:] + m = nonXmlNameFirstBMPRegexp.match(nameFirst) + if m: + warnings.warn("Coercing non-XML name", DataLossWarning) + nameFirstOutput = self.getReplacementCharacter(nameFirst) + else: + nameFirstOutput = nameFirst + + nameRestOutput = nameRest + replaceChars = set(nonXmlNameBMPRegexp.findall(nameRest)) + for char in replaceChars: + warnings.warn("Coercing non-XML name", DataLossWarning) + replacement = self.getReplacementCharacter(char) + nameRestOutput = nameRestOutput.replace(char, replacement) + return nameFirstOutput + nameRestOutput + + def getReplacementCharacter(self, char): + if char in self.replaceCache: + replacement = self.replaceCache[char] + else: + replacement = self.escapeChar(char) + return replacement + + def fromXmlName(self, name): + for item in set(self.replacementRegexp.findall(name)): + name = name.replace(item, self.unescapeChar(item)) + return name + + def escapeChar(self, char): + replacement = "U%05X" % ord(char) + self.replaceCache[char] = replacement + return replacement + + def unescapeChar(self, charcode): + return chr(int(charcode[1:], 16)) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py new file mode 100644 index 0000000..a65e55f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_inputstream.py @@ -0,0 +1,923 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type, binary_type +from pip._vendor.six.moves import http_client, urllib + +import codecs +import re + +from pip._vendor import webencodings + +from .constants import EOF, spaceCharacters, asciiLetters, asciiUppercase +from .constants import _ReparseException +from . import _utils + +from io import StringIO + +try: + from io import BytesIO +except ImportError: + BytesIO = StringIO + +# Non-unicode versions of constants for use in the pre-parser +spaceCharactersBytes = frozenset([item.encode("ascii") for item in spaceCharacters]) +asciiLettersBytes = frozenset([item.encode("ascii") for item in asciiLetters]) +asciiUppercaseBytes = frozenset([item.encode("ascii") for item in asciiUppercase]) +spacesAngleBrackets = spaceCharactersBytes | frozenset([b">", b"<"]) + + +invalid_unicode_no_surrogate = "[\u0001-\u0008\u000B\u000E-\u001F\u007F-\u009F\uFDD0-\uFDEF\uFFFE\uFFFF\U0001FFFE\U0001FFFF\U0002FFFE\U0002FFFF\U0003FFFE\U0003FFFF\U0004FFFE\U0004FFFF\U0005FFFE\U0005FFFF\U0006FFFE\U0006FFFF\U0007FFFE\U0007FFFF\U0008FFFE\U0008FFFF\U0009FFFE\U0009FFFF\U000AFFFE\U000AFFFF\U000BFFFE\U000BFFFF\U000CFFFE\U000CFFFF\U000DFFFE\U000DFFFF\U000EFFFE\U000EFFFF\U000FFFFE\U000FFFFF\U0010FFFE\U0010FFFF]" # noqa + +if _utils.supports_lone_surrogates: + # Use one extra step of indirection and create surrogates with + # eval. Not using this indirection would introduce an illegal + # unicode literal on platforms not supporting such lone + # surrogates. + assert invalid_unicode_no_surrogate[-1] == "]" and invalid_unicode_no_surrogate.count("]") == 1 + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate[:-1] + + eval('"\\uD800-\\uDFFF"') + # pylint:disable=eval-used + "]") +else: + invalid_unicode_re = re.compile(invalid_unicode_no_surrogate) + +non_bmp_invalid_codepoints = set([0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, + 0x6FFFE, 0x6FFFF, 0x7FFFE, 0x7FFFF, 0x8FFFE, + 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF, + 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, + 0x10FFFE, 0x10FFFF]) + +ascii_punctuation_re = re.compile("[\u0009-\u000D\u0020-\u002F\u003A-\u0040\u005C\u005B-\u0060\u007B-\u007E]") + +# Cache for charsUntil() +charsUntilRegEx = {} + + +class BufferedStream(object): + """Buffering for streams that do not have buffering of their own + + The buffer is implemented as a list of chunks on the assumption that + joining many strings will be slow since it is O(n**2) + """ + + def __init__(self, stream): + self.stream = stream + self.buffer = [] + self.position = [-1, 0] # chunk number, offset + + def tell(self): + pos = 0 + for chunk in self.buffer[:self.position[0]]: + pos += len(chunk) + pos += self.position[1] + return pos + + def seek(self, pos): + assert pos <= self._bufferedBytes() + offset = pos + i = 0 + while len(self.buffer[i]) < offset: + offset -= len(self.buffer[i]) + i += 1 + self.position = [i, offset] + + def read(self, bytes): + if not self.buffer: + return self._readStream(bytes) + elif (self.position[0] == len(self.buffer) and + self.position[1] == len(self.buffer[-1])): + return self._readStream(bytes) + else: + return self._readFromBuffer(bytes) + + def _bufferedBytes(self): + return sum([len(item) for item in self.buffer]) + + def _readStream(self, bytes): + data = self.stream.read(bytes) + self.buffer.append(data) + self.position[0] += 1 + self.position[1] = len(data) + return data + + def _readFromBuffer(self, bytes): + remainingBytes = bytes + rv = [] + bufferIndex = self.position[0] + bufferOffset = self.position[1] + while bufferIndex < len(self.buffer) and remainingBytes != 0: + assert remainingBytes > 0 + bufferedData = self.buffer[bufferIndex] + + if remainingBytes <= len(bufferedData) - bufferOffset: + bytesToRead = remainingBytes + self.position = [bufferIndex, bufferOffset + bytesToRead] + else: + bytesToRead = len(bufferedData) - bufferOffset + self.position = [bufferIndex, len(bufferedData)] + bufferIndex += 1 + rv.append(bufferedData[bufferOffset:bufferOffset + bytesToRead]) + remainingBytes -= bytesToRead + + bufferOffset = 0 + + if remainingBytes: + rv.append(self._readStream(remainingBytes)) + + return b"".join(rv) + + +def HTMLInputStream(source, **kwargs): + # Work around Python bug #20007: read(0) closes the connection. + # http://bugs.python.org/issue20007 + if (isinstance(source, http_client.HTTPResponse) or + # Also check for addinfourl wrapping HTTPResponse + (isinstance(source, urllib.response.addbase) and + isinstance(source.fp, http_client.HTTPResponse))): + isUnicode = False + elif hasattr(source, "read"): + isUnicode = isinstance(source.read(0), text_type) + else: + isUnicode = isinstance(source, text_type) + + if isUnicode: + encodings = [x for x in kwargs if x.endswith("_encoding")] + if encodings: + raise TypeError("Cannot set an encoding with a unicode input, set %r" % encodings) + + return HTMLUnicodeInputStream(source, **kwargs) + else: + return HTMLBinaryInputStream(source, **kwargs) + + +class HTMLUnicodeInputStream(object): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + _defaultChunkSize = 10240 + + def __init__(self, source): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + + if not _utils.supports_lone_surrogates: + # Such platforms will have already checked for such + # surrogate errors, so no need to do this checking. + self.reportCharacterErrors = None + elif len("\U0010FFFF") == 1: + self.reportCharacterErrors = self.characterErrorsUCS4 + else: + self.reportCharacterErrors = self.characterErrorsUCS2 + + # List of where new lines occur + self.newLines = [0] + + self.charEncoding = (lookupEncoding("utf-8"), "certain") + self.dataStream = self.openStream(source) + + self.reset() + + def reset(self): + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + self.errors = [] + + # number of (complete) lines in previous chunks + self.prevNumLines = 0 + # number of columns in the last line of the previous chunk + self.prevNumCols = 0 + + # Deal with CR LF and surrogates split over chunk boundaries + self._bufferedCharacter = None + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = StringIO(source) + + return stream + + def _position(self, offset): + chunk = self.chunk + nLines = chunk.count('\n', 0, offset) + positionLine = self.prevNumLines + nLines + lastLinePos = chunk.rfind('\n', 0, offset) + if lastLinePos == -1: + positionColumn = self.prevNumCols + offset + else: + positionColumn = offset - (lastLinePos + 1) + return (positionLine, positionColumn) + + def position(self): + """Returns (line, col) of the current position in the stream.""" + line, col = self._position(self.chunkOffset) + return (line + 1, col) + + def char(self): + """ Read one character from the stream or queue if available. Return + EOF when EOF is reached. + """ + # Read a new chunk from the input stream if necessary + if self.chunkOffset >= self.chunkSize: + if not self.readChunk(): + return EOF + + chunkOffset = self.chunkOffset + char = self.chunk[chunkOffset] + self.chunkOffset = chunkOffset + 1 + + return char + + def readChunk(self, chunkSize=None): + if chunkSize is None: + chunkSize = self._defaultChunkSize + + self.prevNumLines, self.prevNumCols = self._position(self.chunkSize) + + self.chunk = "" + self.chunkSize = 0 + self.chunkOffset = 0 + + data = self.dataStream.read(chunkSize) + + # Deal with CR LF and surrogates broken across chunks + if self._bufferedCharacter: + data = self._bufferedCharacter + data + self._bufferedCharacter = None + elif not data: + # We have no more data, bye-bye stream + return False + + if len(data) > 1: + lastv = ord(data[-1]) + if lastv == 0x0D or 0xD800 <= lastv <= 0xDBFF: + self._bufferedCharacter = data[-1] + data = data[:-1] + + if self.reportCharacterErrors: + self.reportCharacterErrors(data) + + # Replace invalid characters + data = data.replace("\r\n", "\n") + data = data.replace("\r", "\n") + + self.chunk = data + self.chunkSize = len(data) + + return True + + def characterErrorsUCS4(self, data): + for _ in range(len(invalid_unicode_re.findall(data))): + self.errors.append("invalid-codepoint") + + def characterErrorsUCS2(self, data): + # Someone picked the wrong compile option + # You lose + skip = False + for match in invalid_unicode_re.finditer(data): + if skip: + continue + codepoint = ord(match.group()) + pos = match.start() + # Pretty sure there should be endianness issues here + if _utils.isSurrogatePair(data[pos:pos + 2]): + # We have a surrogate pair! + char_val = _utils.surrogatePairToCodepoint(data[pos:pos + 2]) + if char_val in non_bmp_invalid_codepoints: + self.errors.append("invalid-codepoint") + skip = True + elif (codepoint >= 0xD800 and codepoint <= 0xDFFF and + pos == len(data) - 1): + self.errors.append("invalid-codepoint") + else: + skip = False + self.errors.append("invalid-codepoint") + + def charsUntil(self, characters, opposite=False): + """ Returns a string of characters from the stream up to but not + including any character in 'characters' or EOF. 'characters' must be + a container that supports the 'in' method and iteration over its + characters. + """ + + # Use a cache of regexps to find the required characters + try: + chars = charsUntilRegEx[(characters, opposite)] + except KeyError: + if __debug__: + for c in characters: + assert(ord(c) < 128) + regex = "".join(["\\x%02x" % ord(c) for c in characters]) + if not opposite: + regex = "^%s" % regex + chars = charsUntilRegEx[(characters, opposite)] = re.compile("[%s]+" % regex) + + rv = [] + + while True: + # Find the longest matching prefix + m = chars.match(self.chunk, self.chunkOffset) + if m is None: + # If nothing matched, and it wasn't because we ran out of chunk, + # then stop + if self.chunkOffset != self.chunkSize: + break + else: + end = m.end() + # If not the whole chunk matched, return everything + # up to the part that didn't match + if end != self.chunkSize: + rv.append(self.chunk[self.chunkOffset:end]) + self.chunkOffset = end + break + # If the whole remainder of the chunk matched, + # use it all and read the next chunk + rv.append(self.chunk[self.chunkOffset:]) + if not self.readChunk(): + # Reached EOF + break + + r = "".join(rv) + return r + + def unget(self, char): + # Only one character is allowed to be ungotten at once - it must + # be consumed again before any further call to unget + if char is not None: + if self.chunkOffset == 0: + # unget is called quite rarely, so it's a good idea to do + # more work here if it saves a bit of work in the frequently + # called char and charsUntil. + # So, just prepend the ungotten character onto the current + # chunk: + self.chunk = char + self.chunk + self.chunkSize += 1 + else: + self.chunkOffset -= 1 + assert self.chunk[self.chunkOffset] == char + + +class HTMLBinaryInputStream(HTMLUnicodeInputStream): + """Provides a unicode stream of characters to the HTMLTokenizer. + + This class takes care of character encoding and removing or replacing + incorrect byte-sequences and also provides column and line tracking. + + """ + + def __init__(self, source, override_encoding=None, transport_encoding=None, + same_origin_parent_encoding=None, likely_encoding=None, + default_encoding="windows-1252", useChardet=True): + """Initialises the HTMLInputStream. + + HTMLInputStream(source, [encoding]) -> Normalized stream from source + for use by html5lib. + + source can be either a file-object, local filename or a string. + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + """ + # Raw Stream - for unicode objects this will encode to utf-8 and set + # self.charEncoding as appropriate + self.rawStream = self.openStream(source) + + HTMLUnicodeInputStream.__init__(self, self.rawStream) + + # Encoding Information + # Number of bytes to use when looking for a meta element with + # encoding information + self.numBytesMeta = 1024 + # Number of bytes to use when using detecting encoding using chardet + self.numBytesChardet = 100 + # Things from args + self.override_encoding = override_encoding + self.transport_encoding = transport_encoding + self.same_origin_parent_encoding = same_origin_parent_encoding + self.likely_encoding = likely_encoding + self.default_encoding = default_encoding + + # Determine encoding + self.charEncoding = self.determineEncoding(useChardet) + assert self.charEncoding[0] is not None + + # Call superclass + self.reset() + + def reset(self): + self.dataStream = self.charEncoding[0].codec_info.streamreader(self.rawStream, 'replace') + HTMLUnicodeInputStream.reset(self) + + def openStream(self, source): + """Produces a file object from source. + + source can be either a file object, local filename or a string. + + """ + # Already a file object + if hasattr(source, 'read'): + stream = source + else: + stream = BytesIO(source) + + try: + stream.seek(stream.tell()) + except: # pylint:disable=bare-except + stream = BufferedStream(stream) + + return stream + + def determineEncoding(self, chardet=True): + # BOMs take precedence over everything + # This will also read past the BOM if present + charEncoding = self.detectBOM(), "certain" + if charEncoding[0] is not None: + return charEncoding + + # If we've been overriden, we've been overriden + charEncoding = lookupEncoding(self.override_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Now check the transport layer + charEncoding = lookupEncoding(self.transport_encoding), "certain" + if charEncoding[0] is not None: + return charEncoding + + # Look for meta elements with encoding information + charEncoding = self.detectEncodingMeta(), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Parent document encoding + charEncoding = lookupEncoding(self.same_origin_parent_encoding), "tentative" + if charEncoding[0] is not None and not charEncoding[0].name.startswith("utf-16"): + return charEncoding + + # "likely" encoding + charEncoding = lookupEncoding(self.likely_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Guess with chardet, if available + if chardet: + try: + from pip._vendor.chardet.universaldetector import UniversalDetector + except ImportError: + pass + else: + buffers = [] + detector = UniversalDetector() + while not detector.done: + buffer = self.rawStream.read(self.numBytesChardet) + assert isinstance(buffer, bytes) + if not buffer: + break + buffers.append(buffer) + detector.feed(buffer) + detector.close() + encoding = lookupEncoding(detector.result['encoding']) + self.rawStream.seek(0) + if encoding is not None: + return encoding, "tentative" + + # Try the default encoding + charEncoding = lookupEncoding(self.default_encoding), "tentative" + if charEncoding[0] is not None: + return charEncoding + + # Fallback to html5lib's default if even that hasn't worked + return lookupEncoding("windows-1252"), "tentative" + + def changeEncoding(self, newEncoding): + assert self.charEncoding[1] != "certain" + newEncoding = lookupEncoding(newEncoding) + if newEncoding is None: + return + if newEncoding.name in ("utf-16be", "utf-16le"): + newEncoding = lookupEncoding("utf-8") + assert newEncoding is not None + elif newEncoding == self.charEncoding[0]: + self.charEncoding = (self.charEncoding[0], "certain") + else: + self.rawStream.seek(0) + self.charEncoding = (newEncoding, "certain") + self.reset() + raise _ReparseException("Encoding changed from %s to %s" % (self.charEncoding[0], newEncoding)) + + def detectBOM(self): + """Attempts to detect at BOM at the start of the stream. If + an encoding can be determined from the BOM return the name of the + encoding otherwise return None""" + bomDict = { + codecs.BOM_UTF8: 'utf-8', + codecs.BOM_UTF16_LE: 'utf-16le', codecs.BOM_UTF16_BE: 'utf-16be', + codecs.BOM_UTF32_LE: 'utf-32le', codecs.BOM_UTF32_BE: 'utf-32be' + } + + # Go to beginning of file and read in 4 bytes + string = self.rawStream.read(4) + assert isinstance(string, bytes) + + # Try detecting the BOM using bytes from the string + encoding = bomDict.get(string[:3]) # UTF-8 + seek = 3 + if not encoding: + # Need to detect UTF-32 before UTF-16 + encoding = bomDict.get(string) # UTF-32 + seek = 4 + if not encoding: + encoding = bomDict.get(string[:2]) # UTF-16 + seek = 2 + + # Set the read position past the BOM if one was found, otherwise + # set it to the start of the stream + if encoding: + self.rawStream.seek(seek) + return lookupEncoding(encoding) + else: + self.rawStream.seek(0) + return None + + def detectEncodingMeta(self): + """Report the encoding declared by the meta element + """ + buffer = self.rawStream.read(self.numBytesMeta) + assert isinstance(buffer, bytes) + parser = EncodingParser(buffer) + self.rawStream.seek(0) + encoding = parser.getEncoding() + + if encoding is not None and encoding.name in ("utf-16be", "utf-16le"): + encoding = lookupEncoding("utf-8") + + return encoding + + +class EncodingBytes(bytes): + """String-like object with an associated position and various extra methods + If the position is ever greater than the string length then an exception is + raised""" + def __new__(self, value): + assert isinstance(value, bytes) + return bytes.__new__(self, value.lower()) + + def __init__(self, value): + # pylint:disable=unused-argument + self._position = -1 + + def __iter__(self): + return self + + def __next__(self): + p = self._position = self._position + 1 + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + return self[p:p + 1] + + def next(self): + # Py2 compat + return self.__next__() + + def previous(self): + p = self._position + if p >= len(self): + raise StopIteration + elif p < 0: + raise TypeError + self._position = p = p - 1 + return self[p:p + 1] + + def setPosition(self, position): + if self._position >= len(self): + raise StopIteration + self._position = position + + def getPosition(self): + if self._position >= len(self): + raise StopIteration + if self._position >= 0: + return self._position + else: + return None + + position = property(getPosition, setPosition) + + def getCurrentByte(self): + return self[self.position:self.position + 1] + + currentByte = property(getCurrentByte) + + def skip(self, chars=spaceCharactersBytes): + """Skip past a list of characters""" + p = self.position # use property for the error-checking + while p < len(self): + c = self[p:p + 1] + if c not in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def skipUntil(self, chars): + p = self.position + while p < len(self): + c = self[p:p + 1] + if c in chars: + self._position = p + return c + p += 1 + self._position = p + return None + + def matchBytes(self, bytes): + """Look for a sequence of bytes at the start of a string. If the bytes + are found return True and advance the position to the byte after the + match. Otherwise return False and leave the position alone""" + p = self.position + data = self[p:p + len(bytes)] + rv = data.startswith(bytes) + if rv: + self.position += len(bytes) + return rv + + def jumpTo(self, bytes): + """Look for the next sequence of bytes matching a given sequence. If + a match is found advance the position to the last byte of the match""" + newPosition = self[self.position:].find(bytes) + if newPosition > -1: + # XXX: This is ugly, but I can't see a nicer way to fix this. + if self._position == -1: + self._position = 0 + self._position += (newPosition + len(bytes) - 1) + return True + else: + raise StopIteration + + +class EncodingParser(object): + """Mini parser for detecting character encoding from meta elements""" + + def __init__(self, data): + """string - the data to work on for encoding detection""" + self.data = EncodingBytes(data) + self.encoding = None + + def getEncoding(self): + methodDispatch = ( + (b"<!--", self.handleComment), + (b"<meta", self.handleMeta), + (b"</", self.handlePossibleEndTag), + (b"<!", self.handleOther), + (b"<?", self.handleOther), + (b"<", self.handlePossibleStartTag)) + for _ in self.data: + keepParsing = True + for key, method in methodDispatch: + if self.data.matchBytes(key): + try: + keepParsing = method() + break + except StopIteration: + keepParsing = False + break + if not keepParsing: + break + + return self.encoding + + def handleComment(self): + """Skip over comments""" + return self.data.jumpTo(b"-->") + + def handleMeta(self): + if self.data.currentByte not in spaceCharactersBytes: + # if we have <meta not followed by a space so just keep going + return True + # We have a valid meta element we want to search for attributes + hasPragma = False + pendingEncoding = None + while True: + # Try to find the next attribute after the current position + attr = self.getAttribute() + if attr is None: + return True + else: + if attr[0] == b"http-equiv": + hasPragma = attr[1] == b"content-type" + if hasPragma and pendingEncoding is not None: + self.encoding = pendingEncoding + return False + elif attr[0] == b"charset": + tentativeEncoding = attr[1] + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + self.encoding = codec + return False + elif attr[0] == b"content": + contentParser = ContentAttrParser(EncodingBytes(attr[1])) + tentativeEncoding = contentParser.parse() + if tentativeEncoding is not None: + codec = lookupEncoding(tentativeEncoding) + if codec is not None: + if hasPragma: + self.encoding = codec + return False + else: + pendingEncoding = codec + + def handlePossibleStartTag(self): + return self.handlePossibleTag(False) + + def handlePossibleEndTag(self): + next(self.data) + return self.handlePossibleTag(True) + + def handlePossibleTag(self, endTag): + data = self.data + if data.currentByte not in asciiLettersBytes: + # If the next byte is not an ascii letter either ignore this + # fragment (possible start tag case) or treat it according to + # handleOther + if endTag: + data.previous() + self.handleOther() + return True + + c = data.skipUntil(spacesAngleBrackets) + if c == b"<": + # return to the first step in the overall "two step" algorithm + # reprocessing the < byte + data.previous() + else: + # Read all attributes + attr = self.getAttribute() + while attr is not None: + attr = self.getAttribute() + return True + + def handleOther(self): + return self.data.jumpTo(b">") + + def getAttribute(self): + """Return a name,value pair for the next attribute in the stream, + if one is found, or None""" + data = self.data + # Step 1 (skip chars) + c = data.skip(spaceCharactersBytes | frozenset([b"/"])) + assert c is None or len(c) == 1 + # Step 2 + if c in (b">", None): + return None + # Step 3 + attrName = [] + attrValue = [] + # Step 4 attribute name + while True: + if c == b"=" and attrName: + break + elif c in spaceCharactersBytes: + # Step 6! + c = data.skip() + break + elif c in (b"/", b">"): + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrName.append(c.lower()) + elif c is None: + return None + else: + attrName.append(c) + # Step 5 + c = next(data) + # Step 7 + if c != b"=": + data.previous() + return b"".join(attrName), b"" + # Step 8 + next(data) + # Step 9 + c = data.skip() + # Step 10 + if c in (b"'", b'"'): + # 10.1 + quoteChar = c + while True: + # 10.2 + c = next(data) + # 10.3 + if c == quoteChar: + next(data) + return b"".join(attrName), b"".join(attrValue) + # 10.4 + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + # 10.5 + else: + attrValue.append(c) + elif c == b">": + return b"".join(attrName), b"" + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + # Step 11 + while True: + c = next(data) + if c in spacesAngleBrackets: + return b"".join(attrName), b"".join(attrValue) + elif c in asciiUppercaseBytes: + attrValue.append(c.lower()) + elif c is None: + return None + else: + attrValue.append(c) + + +class ContentAttrParser(object): + def __init__(self, data): + assert isinstance(data, bytes) + self.data = data + + def parse(self): + try: + # Check if the attr name is charset + # otherwise return + self.data.jumpTo(b"charset") + self.data.position += 1 + self.data.skip() + if not self.data.currentByte == b"=": + # If there is no = sign keep looking for attrs + return None + self.data.position += 1 + self.data.skip() + # Look for an encoding between matching quote marks + if self.data.currentByte in (b'"', b"'"): + quoteMark = self.data.currentByte + self.data.position += 1 + oldPosition = self.data.position + if self.data.jumpTo(quoteMark): + return self.data[oldPosition:self.data.position] + else: + return None + else: + # Unquoted value + oldPosition = self.data.position + try: + self.data.skipUntil(spaceCharactersBytes) + return self.data[oldPosition:self.data.position] + except StopIteration: + # Return the whole remaining value + return self.data[oldPosition:] + except StopIteration: + return None + + +def lookupEncoding(encoding): + """Return the python codec name corresponding to an encoding or None if the + string doesn't correspond to a valid encoding.""" + if isinstance(encoding, binary_type): + try: + encoding = encoding.decode("ascii") + except UnicodeDecodeError: + return None + + if encoding is not None: + try: + return webencodings.lookup(encoding) + except AttributeError: + return None + else: + return None diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py new file mode 100644 index 0000000..178f6e7 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_tokenizer.py @@ -0,0 +1,1721 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import unichr as chr + +from collections import deque + +from .constants import spaceCharacters +from .constants import entities +from .constants import asciiLetters, asciiUpper2Lower +from .constants import digits, hexDigits, EOF +from .constants import tokenTypes, tagTokenTypes +from .constants import replacementCharacters + +from ._inputstream import HTMLInputStream + +from ._trie import Trie + +entitiesTrie = Trie(entities) + + +class HTMLTokenizer(object): + """ This class takes care of tokenizing HTML. + + * self.currentToken + Holds the token that is currently being processed. + + * self.state + Holds a reference to the method to be invoked... XXX + + * self.stream + Points to HTMLInputStream object. + """ + + def __init__(self, stream, parser=None, **kwargs): + + self.stream = HTMLInputStream(stream, **kwargs) + self.parser = parser + + # Setup the initial tokenizer state + self.escapeFlag = False + self.lastFourChars = [] + self.state = self.dataState + self.escape = False + + # The current token being created + self.currentToken = None + super(HTMLTokenizer, self).__init__() + + def __iter__(self): + """ This is where the magic happens. + + We do our usually processing through the states and when we have a token + to return we yield the token which pauses processing until the next token + is requested. + """ + self.tokenQueue = deque([]) + # Start processing. When EOF is reached self.state will return False + # instead of True and the loop will terminate. + while self.state(): + while self.stream.errors: + yield {"type": tokenTypes["ParseError"], "data": self.stream.errors.pop(0)} + while self.tokenQueue: + yield self.tokenQueue.popleft() + + def consumeNumberEntity(self, isHex): + """This function returns either U+FFFD or the character based on the + decimal or hexadecimal representation. It also discards ";" if present. + If not present self.tokenQueue.append({"type": tokenTypes["ParseError"]}) is invoked. + """ + + allowed = digits + radix = 10 + if isHex: + allowed = hexDigits + radix = 16 + + charStack = [] + + # Consume all the characters that are in range while making sure we + # don't hit an EOF. + c = self.stream.char() + while c in allowed and c is not EOF: + charStack.append(c) + c = self.stream.char() + + # Convert the set of characters consumed to an int. + charAsInt = int("".join(charStack), radix) + + # Certain characters get replaced with others + if charAsInt in replacementCharacters: + char = replacementCharacters[charAsInt] + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + elif ((0xD800 <= charAsInt <= 0xDFFF) or + (charAsInt > 0x10FFFF)): + char = "\uFFFD" + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + else: + # Should speed up this check somehow (e.g. move the set to a constant) + if ((0x0001 <= charAsInt <= 0x0008) or + (0x000E <= charAsInt <= 0x001F) or + (0x007F <= charAsInt <= 0x009F) or + (0xFDD0 <= charAsInt <= 0xFDEF) or + charAsInt in frozenset([0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, + 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, + 0x3FFFF, 0x4FFFE, 0x4FFFF, 0x5FFFE, + 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, + 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, + 0x9FFFF, 0xAFFFE, 0xAFFFF, 0xBFFFE, + 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, + 0xFFFFF, 0x10FFFE, 0x10FFFF])): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "illegal-codepoint-for-numeric-entity", + "datavars": {"charAsInt": charAsInt}}) + try: + # Try/except needed as UCS-2 Python builds' unichar only works + # within the BMP. + char = chr(charAsInt) + except ValueError: + v = charAsInt - 0x10000 + char = chr(0xD800 | (v >> 10)) + chr(0xDC00 | (v & 0x3FF)) + + # Discard the ; if present. Otherwise, put it back on the queue and + # invoke parseError on parser. + if c != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "numeric-entity-without-semicolon"}) + self.stream.unget(c) + + return char + + def consumeEntity(self, allowedChar=None, fromAttribute=False): + # Initialise to the default output for when no entity is matched + output = "&" + + charStack = [self.stream.char()] + if (charStack[0] in spaceCharacters or charStack[0] in (EOF, "<", "&") or + (allowedChar is not None and allowedChar == charStack[0])): + self.stream.unget(charStack[0]) + + elif charStack[0] == "#": + # Read the next character to see if it's hex or decimal + hex = False + charStack.append(self.stream.char()) + if charStack[-1] in ("x", "X"): + hex = True + charStack.append(self.stream.char()) + + # charStack[-1] should be the first digit + if (hex and charStack[-1] in hexDigits) \ + or (not hex and charStack[-1] in digits): + # At least one digit found, so consume the whole number + self.stream.unget(charStack[-1]) + output = self.consumeNumberEntity(hex) + else: + # No digits found + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "expected-numeric-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + else: + # At this point in the process might have named entity. Entities + # are stored in the global variable "entities". + # + # Consume characters and compare to these to a substring of the + # entity names in the list until the substring no longer matches. + while (charStack[-1] is not EOF): + if not entitiesTrie.has_keys_with_prefix("".join(charStack)): + break + charStack.append(self.stream.char()) + + # At this point we have a string that starts with some characters + # that may match an entity + # Try to find the longest entity the string will match to take care + # of ¬i for instance. + try: + entityName = entitiesTrie.longest_prefix("".join(charStack[:-1])) + entityLength = len(entityName) + except KeyError: + entityName = None + + if entityName is not None: + if entityName[-1] != ";": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "named-entity-without-semicolon"}) + if (entityName[-1] != ";" and fromAttribute and + (charStack[entityLength] in asciiLetters or + charStack[entityLength] in digits or + charStack[entityLength] == "=")): + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + else: + output = entities[entityName] + self.stream.unget(charStack.pop()) + output += "".join(charStack[entityLength:]) + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-named-entity"}) + self.stream.unget(charStack.pop()) + output = "&" + "".join(charStack) + + if fromAttribute: + self.currentToken["data"][-1][1] += output + else: + if output in spaceCharacters: + tokenType = "SpaceCharacters" + else: + tokenType = "Characters" + self.tokenQueue.append({"type": tokenTypes[tokenType], "data": output}) + + def processEntityInAttribute(self, allowedChar): + """This method replaces the need for "entityInAttributeValueState". + """ + self.consumeEntity(allowedChar=allowedChar, fromAttribute=True) + + def emitCurrentToken(self): + """This method is a generic handler for emitting the tags. It also sets + the state to "data" because that's what's needed after a token has been + emitted. + """ + token = self.currentToken + # Add token to the queue to be yielded + if (token["type"] in tagTokenTypes): + token["name"] = token["name"].translate(asciiUpper2Lower) + if token["type"] == tokenTypes["EndTag"]: + if token["data"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "attributes-in-end-tag"}) + if token["selfClosing"]: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "self-closing-flag-on-end-tag"}) + self.tokenQueue.append(token) + self.state = self.dataState + + # Below are the various tokenizer states worked out. + def dataState(self): + data = self.stream.char() + if data == "&": + self.state = self.entityDataState + elif data == "<": + self.state = self.tagOpenState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\u0000"}) + elif data is EOF: + # Tokenization ends. + return False + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def entityDataState(self): + self.consumeEntity() + self.state = self.dataState + return True + + def rcdataState(self): + data = self.stream.char() + if data == "&": + self.state = self.characterReferenceInRcdata + elif data == "<": + self.state = self.rcdataLessThanSignState + elif data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data in spaceCharacters: + # Directly after emitting a token you switch back to the "data + # state". At that point spaceCharacters are important so they are + # emitted separately. + self.tokenQueue.append({"type": tokenTypes["SpaceCharacters"], "data": + data + self.stream.charsUntil(spaceCharacters, True)}) + # No need to update lastFourChars here, since the first space will + # have already been appended to lastFourChars and will have broken + # any <!-- or --> sequences + else: + chars = self.stream.charsUntil(("&", "<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def characterReferenceInRcdata(self): + self.consumeEntity() + self.state = self.rcdataState + return True + + def rawtextState(self): + data = self.stream.char() + if data == "<": + self.state = self.rawtextLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataState(self): + data = self.stream.char() + if data == "<": + self.state = self.scriptDataLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + # Tokenization ends. + return False + else: + chars = self.stream.charsUntil(("<", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def plaintextState(self): + data = self.stream.char() + if data == EOF: + # Tokenization ends. + return False + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + self.stream.charsUntil("\u0000")}) + return True + + def tagOpenState(self): + data = self.stream.char() + if data == "!": + self.state = self.markupDeclarationOpenState + elif data == "/": + self.state = self.closeTagOpenState + elif data in asciiLetters: + self.currentToken = {"type": tokenTypes["StartTag"], + "name": data, "data": [], + "selfClosing": False, + "selfClosingAcknowledged": False} + self.state = self.tagNameState + elif data == ">": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-right-bracket"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<>"}) + self.state = self.dataState + elif data == "?": + # XXX In theory it could be something besides a tag name. But + # do we really care? + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name-but-got-question-mark"}) + self.stream.unget(data) + self.state = self.bogusCommentState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-tag-name"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.dataState + return True + + def closeTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.currentToken = {"type": tokenTypes["EndTag"], "name": data, + "data": [], "selfClosing": False} + self.state = self.tagNameState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-right-bracket"}) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-eof"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.state = self.dataState + else: + # XXX data can be _'_... + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-closing-tag-but-got-char", + "datavars": {"data": data}}) + self.stream.unget(data) + self.state = self.bogusCommentState + return True + + def tagNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-tag-name"}) + self.state = self.dataState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + else: + self.currentToken["name"] += data + # (Don't use charsUntil here, because tag names are + # very short and it's faster to not do anything fancy) + return True + + def rcdataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rcdataEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rcdataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rcdataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rcdataState + return True + + def rawtextLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.rawtextEndTagOpenState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.rawtextEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def rawtextEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.rawtextState + return True + + def scriptDataLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEndTagOpenState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<!"}) + self.state = self.scriptDataEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer += data + self.state = self.scriptDataEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapeStartDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapeStartDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + else: + self.stream.unget(data) + self.state = self.scriptDataState + return True + + def scriptDataEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.state = self.dataState + else: + chars = self.stream.charsUntil(("<", "-", "\u0000")) + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": + data + chars}) + return True + + def scriptDataEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataEscapedDashDashState + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.state = self.scriptDataEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataEscapedState + elif data == EOF: + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.temporaryBuffer = "" + self.state = self.scriptDataEscapedEndTagOpenState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<" + data}) + self.temporaryBuffer = data + self.state = self.scriptDataDoubleEscapeStartState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagOpenState(self): + data = self.stream.char() + if data in asciiLetters: + self.temporaryBuffer = data + self.state = self.scriptDataEscapedEndTagNameState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "</"}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataEscapedEndTagNameState(self): + appropriate = self.currentToken and self.currentToken["name"].lower() == self.temporaryBuffer.lower() + data = self.stream.char() + if data in spaceCharacters and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.beforeAttributeNameState + elif data == "/" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.state = self.selfClosingStartTagState + elif data == ">" and appropriate: + self.currentToken = {"type": tokenTypes["EndTag"], + "name": self.temporaryBuffer, + "data": [], "selfClosing": False} + self.emitCurrentToken() + self.state = self.dataState + elif data in asciiLetters: + self.temporaryBuffer += data + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "</" + self.temporaryBuffer}) + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapeStartState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataDoubleEscapedState + else: + self.state = self.scriptDataEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataEscapedState + return True + + def scriptDataDoubleEscapedState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + return True + + def scriptDataDoubleEscapedDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + self.state = self.scriptDataDoubleEscapedDashDashState + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedDashDashState(self): + data = self.stream.char() + if data == "-": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "-"}) + elif data == "<": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "<"}) + self.state = self.scriptDataDoubleEscapedLessThanSignState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": ">"}) + self.state = self.scriptDataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": "\uFFFD"}) + self.state = self.scriptDataDoubleEscapedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-script-in-script"}) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapedLessThanSignState(self): + data = self.stream.char() + if data == "/": + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": "/"}) + self.temporaryBuffer = "" + self.state = self.scriptDataDoubleEscapeEndState + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def scriptDataDoubleEscapeEndState(self): + data = self.stream.char() + if data in (spaceCharacters | frozenset(("/", ">"))): + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + if self.temporaryBuffer.lower() == "script": + self.state = self.scriptDataEscapedState + else: + self.state = self.scriptDataDoubleEscapedState + elif data in asciiLetters: + self.tokenQueue.append({"type": tokenTypes["Characters"], "data": data}) + self.temporaryBuffer += data + else: + self.stream.unget(data) + self.state = self.scriptDataDoubleEscapedState + return True + + def beforeAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data in ("'", '"', "=", "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-name-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def attributeNameState(self): + data = self.stream.char() + leavingThisState = True + emitToken = False + if data == "=": + self.state = self.beforeAttributeValueState + elif data in asciiLetters: + self.currentToken["data"][-1][0] += data +\ + self.stream.charsUntil(asciiLetters, True) + leavingThisState = False + elif data == ">": + # XXX If we emit here the attributes are converted to a dict + # without being checked and when the code below runs we error + # because data is a dict not a list + emitToken = True + elif data in spaceCharacters: + self.state = self.afterAttributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][0] += "\uFFFD" + leavingThisState = False + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "invalid-character-in-attribute-name"}) + self.currentToken["data"][-1][0] += data + leavingThisState = False + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-attribute-name"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][0] += data + leavingThisState = False + + if leavingThisState: + # Attributes are not dropped at this stage. That happens when the + # start tag token is emitted so values can still be safely appended + # to attributes, but we do want to report the parse error in time. + self.currentToken["data"][-1][0] = ( + self.currentToken["data"][-1][0].translate(asciiUpper2Lower)) + for name, _ in self.currentToken["data"][:-1]: + if self.currentToken["data"][-1][0] == name: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "duplicate-attribute"}) + break + # XXX Fix for above XXX + if emitToken: + self.emitCurrentToken() + return True + + def afterAttributeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "=": + self.state = self.beforeAttributeValueState + elif data == ">": + self.emitCurrentToken() + elif data in asciiLetters: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data == "/": + self.state = self.selfClosingStartTagState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"].append(["\uFFFD", ""]) + self.state = self.attributeNameState + elif data in ("'", '"', "<"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "invalid-character-after-attribute-name"}) + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-end-of-tag-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"].append([data, ""]) + self.state = self.attributeNameState + return True + + def beforeAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.stream.charsUntil(spaceCharacters, True) + elif data == "\"": + self.state = self.attributeValueDoubleQuotedState + elif data == "&": + self.state = self.attributeValueUnQuotedState + self.stream.unget(data) + elif data == "'": + self.state = self.attributeValueSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-right-bracket"}) + self.emitCurrentToken() + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + self.state = self.attributeValueUnQuotedState + elif data in ("=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "equals-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-attribute-value-but-got-eof"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.state = self.attributeValueUnQuotedState + return True + + def attributeValueDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute('"') + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-double-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("\"", "&", "\u0000")) + return True + + def attributeValueSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterAttributeValueState + elif data == "&": + self.processEntityInAttribute("'") + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-single-quote"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data +\ + self.stream.charsUntil(("'", "&", "\u0000")) + return True + + def attributeValueUnQuotedState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == "&": + self.processEntityInAttribute(">") + elif data == ">": + self.emitCurrentToken() + elif data in ('"', "'", "=", "<", "`"): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-in-unquoted-attribute-value"}) + self.currentToken["data"][-1][1] += data + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"][-1][1] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-attribute-value-no-quotes"}) + self.state = self.dataState + else: + self.currentToken["data"][-1][1] += data + self.stream.charsUntil( + frozenset(("&", ">", '"', "'", "=", "<", "`", "\u0000")) | spaceCharacters) + return True + + def afterAttributeValueState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeAttributeNameState + elif data == ">": + self.emitCurrentToken() + elif data == "/": + self.state = self.selfClosingStartTagState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-EOF-after-attribute-value"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-attribute-value"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def selfClosingStartTagState(self): + data = self.stream.char() + if data == ">": + self.currentToken["selfClosing"] = True + self.emitCurrentToken() + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": + "unexpected-EOF-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-character-after-solidus-in-tag"}) + self.stream.unget(data) + self.state = self.beforeAttributeNameState + return True + + def bogusCommentState(self): + # Make a new comment token and give it as value all the characters + # until the first > or EOF (charsUntil checks for EOF automatically) + # and emit it. + data = self.stream.charsUntil(">") + data = data.replace("\u0000", "\uFFFD") + self.tokenQueue.append( + {"type": tokenTypes["Comment"], "data": data}) + + # Eat the character directly after the bogus comment which is either a + # ">" or an EOF. + self.stream.char() + self.state = self.dataState + return True + + def markupDeclarationOpenState(self): + charStack = [self.stream.char()] + if charStack[-1] == "-": + charStack.append(self.stream.char()) + if charStack[-1] == "-": + self.currentToken = {"type": tokenTypes["Comment"], "data": ""} + self.state = self.commentStartState + return True + elif charStack[-1] in ('d', 'D'): + matched = True + for expected in (('o', 'O'), ('c', 'C'), ('t', 'T'), + ('y', 'Y'), ('p', 'P'), ('e', 'E')): + charStack.append(self.stream.char()) + if charStack[-1] not in expected: + matched = False + break + if matched: + self.currentToken = {"type": tokenTypes["Doctype"], + "name": "", + "publicId": None, "systemId": None, + "correct": True} + self.state = self.doctypeState + return True + elif (charStack[-1] == "[" and + self.parser is not None and + self.parser.tree.openElements and + self.parser.tree.openElements[-1].namespace != self.parser.tree.defaultNamespace): + matched = True + for expected in ["C", "D", "A", "T", "A", "["]: + charStack.append(self.stream.char()) + if charStack[-1] != expected: + matched = False + break + if matched: + self.state = self.cdataSectionState + return True + + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-dashes-or-doctype"}) + + while charStack: + self.stream.unget(charStack.pop()) + self.state = self.bogusCommentState + return True + + def commentStartState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentStartDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + self.state = self.commentState + return True + + def commentStartDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "incorrect-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "\uFFFD" + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "eof-in-comment"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += data + \ + self.stream.charsUntil(("-", "\u0000")) + return True + + def commentEndDashState(self): + data = self.stream.char() + if data == "-": + self.state = self.commentEndState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "-\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "-" + data + self.state = self.commentState + return True + + def commentEndState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--\uFFFD" + self.state = self.commentState + elif data == "!": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-bang-after-double-dash-in-comment"}) + self.state = self.commentEndBangState + elif data == "-": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-dash-after-double-dash-in-comment"}) + self.currentToken["data"] += data + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-double-dash"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + # XXX + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-comment"}) + self.currentToken["data"] += "--" + data + self.state = self.commentState + return True + + def commentEndBangState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "-": + self.currentToken["data"] += "--!" + self.state = self.commentEndDashState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["data"] += "--!\uFFFD" + self.state = self.commentState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-comment-end-bang-state"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["data"] += "--!" + data + self.state = self.commentState + return True + + def doctypeState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "need-space-after-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeNameState + return True + + def beforeDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-right-bracket"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] = "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-doctype-name-but-got-eof"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] = data + self.state = self.doctypeNameState + return True + + def doctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.state = self.afterDoctypeNameState + elif data == ">": + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["name"] += "\uFFFD" + self.state = self.doctypeNameState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype-name"}) + self.currentToken["correct"] = False + self.currentToken["name"] = self.currentToken["name"].translate(asciiUpper2Lower) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["name"] += data + return True + + def afterDoctypeNameState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.currentToken["correct"] = False + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + if data in ("p", "P"): + matched = True + for expected in (("u", "U"), ("b", "B"), ("l", "L"), + ("i", "I"), ("c", "C")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypePublicKeywordState + return True + elif data in ("s", "S"): + matched = True + for expected in (("y", "Y"), ("s", "S"), ("t", "T"), + ("e", "E"), ("m", "M")): + data = self.stream.char() + if data not in expected: + matched = False + break + if matched: + self.state = self.afterDoctypeSystemKeywordState + return True + + # All the characters read before the current 'data' will be + # [a-zA-Z], so they're garbage in the bogus doctype and can be + # discarded; only the latest character might be '>' or EOF + # and needs to be ungetted + self.stream.unget(data) + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "expected-space-or-right-bracket-in-doctype", "datavars": + {"data": data}}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + + return True + + def afterDoctypePublicKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypePublicIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypePublicIdentifierState + return True + + def beforeDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["publicId"] = "" + self.state = self.doctypePublicIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypePublicIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def doctypePublicIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypePublicIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["publicId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["publicId"] += data + return True + + def afterDoctypePublicIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.betweenDoctypePublicAndSystemIdentifiersState + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def betweenDoctypePublicAndSystemIdentifiersState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data == '"': + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def afterDoctypeSystemKeywordState(self): + data = self.stream.char() + if data in spaceCharacters: + self.state = self.beforeDoctypeSystemIdentifierState + elif data in ("'", '"'): + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.stream.unget(data) + self.state = self.beforeDoctypeSystemIdentifierState + return True + + def beforeDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == "\"": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierDoubleQuotedState + elif data == "'": + self.currentToken["systemId"] = "" + self.state = self.doctypeSystemIdentifierSingleQuotedState + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.currentToken["correct"] = False + self.state = self.bogusDoctypeState + return True + + def doctypeSystemIdentifierDoubleQuotedState(self): + data = self.stream.char() + if data == "\"": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def doctypeSystemIdentifierSingleQuotedState(self): + data = self.stream.char() + if data == "'": + self.state = self.afterDoctypeSystemIdentifierState + elif data == "\u0000": + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + self.currentToken["systemId"] += "\uFFFD" + elif data == ">": + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-end-of-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.currentToken["systemId"] += data + return True + + def afterDoctypeSystemIdentifierState(self): + data = self.stream.char() + if data in spaceCharacters: + pass + elif data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "eof-in-doctype"}) + self.currentToken["correct"] = False + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + self.tokenQueue.append({"type": tokenTypes["ParseError"], "data": + "unexpected-char-in-doctype"}) + self.state = self.bogusDoctypeState + return True + + def bogusDoctypeState(self): + data = self.stream.char() + if data == ">": + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + elif data is EOF: + # XXX EMIT + self.stream.unget(data) + self.tokenQueue.append(self.currentToken) + self.state = self.dataState + else: + pass + return True + + def cdataSectionState(self): + data = [] + while True: + data.append(self.stream.charsUntil("]")) + data.append(self.stream.charsUntil(">")) + char = self.stream.char() + if char == EOF: + break + else: + assert char == ">" + if data[-1][-2:] == "]]": + data[-1] = data[-1][:-2] + break + else: + data.append(char) + + data = "".join(data) # pylint:disable=redefined-variable-type + # Deal with null here rather than in the parser + nullCount = data.count("\u0000") + if nullCount > 0: + for _ in range(nullCount): + self.tokenQueue.append({"type": tokenTypes["ParseError"], + "data": "invalid-codepoint"}) + data = data.replace("\u0000", "\uFFFD") + if data: + self.tokenQueue.append({"type": tokenTypes["Characters"], + "data": data}) + self.state = self.dataState + return True diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py new file mode 100644 index 0000000..a5ba4bf --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__init__.py @@ -0,0 +1,14 @@ +from __future__ import absolute_import, division, unicode_literals + +from .py import Trie as PyTrie + +Trie = PyTrie + +# pylint:disable=wrong-import-position +try: + from .datrie import Trie as DATrie +except ImportError: + pass +else: + Trie = DATrie +# pylint:enable=wrong-import-position diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d91d86eda3e40859398a502e988fbd6686f6ef3 GIT binary patch literal 382 zcmXwzy-ve05XaBX2O*`U124dWl%ZsS4Iw~9f(0Q!0xTpetqmA#Cpb<~o`#uM^2*d# zV8V{XS@*lUzkTOB8;^7FM!xo*b`ii&DE=+;$%*&&#)APv5)>jxVS-geA_NSxNX9B5 zDFU97q@NDThF3BK_n>!T;G6Hcxj+!kBk1%2ct#Qy-$IeB{ah#_w_PpTT6UIGp_<xQ zmoc#tt*Et|c3LcJ#;FvRn@YB8za<pN#dk*Vt0H$frO%!145!p!e`lhA*u&wbH)%-H z>pnauDXZ)d=cl1|qs!sHb7N}r4Q3QN1AgbFRZZE5W+rrND=BBo&lmk>KMsO8I9+kg uYE!;iB@d-olr)SkDHU2+O81-IWk;%Jo#e-1=XT<;gST)TVKhY(l;S@{;$lev literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/_base.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18788af40aebb927bb86db979e9e8c04e1bf0ec8 GIT binary patch literal 1465 zcmZuxL2uhO6n>;6TXvkZOM<N#y28MU0y@<0p}iDA&~Dv!80Jd?6c9ELiYO;qC`%#f zHZj!8oS{AM4=mYje@WM!`WJfIdvub;LkRGRA|Ls_?|YB@W_7g-*y2AQ{rr~)@DKf5 zH6I5ru$!l7BuJ*9U@<Fr%nL8}7|n6z7eO2__yMFR{WFk$7R<f4C4*gvS|4#IL|$_z z**B${+Dzm{RchOWGJlhsyqq+5r;|J_WhPW^Go2_Cv8Me~QdRlnAf@eBjo?r-&(UNM zGYK)5EcWEedl)kpz7zX0kgYR_1KE}#ep|95yZCLt2Or`PLG>DcPv_a}tC#!6>Lj)O z{lsMbR3*mr$EEIDTs5PVyJ!F?%XK$T@W+B>HO%=rzkqlA1Ilm|>Ic@V`JC;7!@?v# z3v2!gXeRPTDZ4z34h^txU^ic)IfNR1S%1fBb`Brlf@!~IfAC{}7ybrRqHAoTt$CZ< z!-zM0@T6fUINhprHqK9U8&CN3a%hWcSmo8@e1h&uJx<>qOn$Y;PifM1@g|$dQV$Pp zp`NLHe<+CLP!RJ$b^58ZZ8DpdMYVI6fDy_T%<hv;gQM)!47OF7Vs3T@*N&0j1ZG-g zTDQ=<@yV_6@EA<DZ!$I3D>$$3ph3VLA)LTML~OCpyISqwz=UXkuknzDeAc;+yOabf zfN#n9A)1p1HJrl*ydw2@&CgLmRIe*h@Z;`ltV}2T-uDrA7&JwQJpCDd9Dv3{#7@A4 zAw13IVPXU^5u~_SsJxCV3xI5mbqU~>19+S7?SS|2gc@t+sHJ-~0z7$c@j77@u{o3M z3#=ui@epZXP1k${e&<_Q7U<o-IfKOdufd|%oc)HLNRW>{Qe~m!flej|S>vf}(u6-| zr{8H^>LtD`|3BL`RpK6FFL`bePm%#x$b5c}t+RDL+i+Z$J(pP0{cvgd90!yXN(7~( zMlM@0rbMt2rk%=t2~k_!DB~Mh*jSDx@L?#v#?8h(0hof>y<0#zH;UA0LLnwekqOas zg(ylnRW$AiaXd}b<w{!!S*AiPs$&z6cL4Q$95t(#<(g(np$lCzXOIO|gLcJBbx+;U z6H1D$b;5Sob@yQuwJG*^YNr}wYr0XIl+whZSxHN!vee=OXf(YCZqt8pZio?XF9_^V LqMZVpyyyK3H<(Uq literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/datrie.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..65aeb72bbc8dc82440415477cb6b193b14f8b500 GIT binary patch literal 1984 zcmb7FTTdf56t>4RlSv4W4eSbfO>e74?ZQj@Qmv|m-Kwfo@zPb1MpV`i8yI#jiS4j} zhL?q3(U-zw|B_$(w11&bJ;#&KfY7!$^0DXGKHukaaW?1YTLfDC$K##feM0`ik7<K% z@(jBE8H6B$W+bOE&Ar&mS<EQvyv)yoICOKCHS#EqVD5vy3HlZ#KN1m$@Pdd?w$51` zh{i9ZAH4;Oq|fYPva8E%Y$Q+fVX2IbM0%9!v@C3AT%?0iNS>ueswC5WYW<fgl`uAq zJT}~%4CPx2h6ZSD+89ipLD#>6kR+yp#GatSyC5+WO!zSRH78^vBKQtPQ?y`gh-J|h z^A|LZ#DZ7^O;dEl0~lMPE0$oK6LY}-p$fqGzypCTgpP{m(De}rL(a*Wcl=#NFX<I| zL4I31W5%nPVdtKHY<xk_=^J|dsA90TaOPLuWl;H7l#<cc+ho+)CMFc#Wux-0U}r^m zbo>$6YC2op9q){t1yxXy!>D3U$!KRALIJec*6GSdmi1oA6Wz<l+Vpm1PaBmM``VIz z%Q7vE^>Nv@z{`a;NimQL`P=48aOV$7mCCY22phiGKyO?BuuKaZaFLkA1`vx}_e1Mz zneAD>Rt^plr7Z)y*2lRGj*@IF|0HS!EdRZ^Zt~&!FdaT|h*|bz@Or;EG^1}&={i4> zg(%hffyuLPvvhZz18cbs=3!VHp4f=<v`7u-n6A1Dg3ypI&=!rLcfAhn($je)yf)o= z9Ucr5b{8HzUx7;x$*T}tMz{J@bwJnm6k1geQ6TMFtisH;IUkgTNq|1*k3gec<mu^y z3E;o01I$NkINks?1VAC0HK=D<CW{)G*2uR&8=S)q&XK_suRXzY3pbz;?)rY1es3V} zC-<{UTc!CaA7(O_g^|Jq8LsW_dkYo)4CTi82Q#qOeswGF@GE$=qN`Kf|Mcq|=ljxN zN^$=23|?n)&FjUj8<<$(?yhZ^U?eYTMX#ogb*Ku%JPD}{hf40H$G4*DwtPB++H|N` z9QQ@D%Lj?(c#^+P%>l3RrWy4KVBE$=+%IOZR~`0UR_@JZAuEf0sm=dj@fk4qa)!l{ zV{!BRz44cBp2u{`-{p$WfxuTYBv$SqQ5%6;ZR0~wB)R0=wm8pAG0t!f6*?LxS-qm( z19R$q6d$6%)KWbZm=y|rukh*$p=ToFN&(Bwz3xqzxQ8a9Q9EMwujNL!zSW;Y3VUNS zRzN{vu`5hXh5wuIm*U<ow^c2G#xBBRw>Ej`)->d!dv*i9n`mhp8=KGZ;&;)p(bM{( R-(!{Q2*k42rfsjy{sDXUtdRf! literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/__pycache__/py.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..24a1608fe112a3ec197262fba9bdcef12fe0cdd3 GIT binary patch literal 2187 zcma)7&2Aev5GJ`lTFJ64r>PU8ZK|SZ3KfmqLz`X#BR_2l6oD@_T0lra$l}^wd$p2D zDzS~#rOJCWKK2FrFueAZQ|~$T8?L3qMi6utI~)#YIWymIh7XsQ8w^kH&)ZM`jT!rg zCi5o*b04310-~7WIUDjGABvtB2EBljOyuD(>P4Op@_1P5)xd`;%9CNe*Wm0Yreall z!Bj16%z|EBCBLvv{S|g(oxrX3cg-lD*i>f2@km>jsO(v0vQgn$lOh|8R4Vh#rn;Y- z4tI5%o>*y5$0;UDyO~J`R_5uReZ^@%?!q0Nr32c0{sds|<1>#zQr6>&^@QR|ykNaR z1uDb{cU6orQZ<!ej8$DVFxFH{HP!M9-b>VqT7{&pmf-%HPO#ZPfY3uDVf6@~`5D9l zD>6{>m;9Xlz-D~L%`GcbFynvll9x;dHmp`>G>cRS8mq|GO6cwh%o4?5D&8JYX!Oj@ z81UvMNXdS0O}T{`%V*+O#@Vs(Kk@C3a1Fp%7~3xfsg9rxk?4No_{m>PH!**`wP}ar z&2cuq<Ms0V&fxieacGafC87W1v$Rkny?J1V`FDA?yD2U3-5j5G$EUCB_x95wJsIn* zCGx0p@2pK3=t`LtnU%78FCPt%yRGg*`RwL{JZ~SRr=~re7~9@W+XlN9`^GWt(^z*w zKhIrAI<CHhZ2zeBNV`a?zU{l%;Gm=m(@H@O`h$ZMd$=G^3)igX<55;vgP=o`=6f!r zUwzyaS%%9lnY&3fU<ee(*LfmhzQSXEwtOj+OX;RyeY)vSO6VawijgiL&-Dk8b%fr) z-~#w~)ofGB!Kko(z%C^zd+ZoLTe~p$W_6K#0_KuYq@5k&tW-vYz5#{GGWV9R8m&nb zN+IR?TlSh4_WZ*CHswMp$oJVIT%jT*K`;+)fu>)151PQT<QsJOucE0xrXVR#ZzXX_ z%Kg;B-cU+fpWAC)1h-h+Uf8TbjY`62@NY0By24Rn)-m!Ufe}8Kw)J@>h*7F2$;05B z>n9k)r(!CmfsIHH*%xIn3qv*yr%}<GOJ|~zpf=ewE<+oW_6+-LTjH#oeC_{^HW>Ei z*!g7{zpTw==bW=LQsR3yjgFuFMpn=?%CL-la|mgNPOz<4;k~AKI*I-eg9}V*T?2Km zt$Ci=15F9n)GjpoJM-rR^`%s&R-Mpztkb>h#EE?5#6jjF|F7ejUL*a>XnWbGkegc| zR4onB<PE+qTE1#RagDcl6MRFQ)qMu2NEgTx>I>u*CiB|SE2_eoFc(1MF2>*jXEevd zXpZwVEShMZUNRHY@B-P$BfFynvPEkla7C*<rveGKcOD~LDmDE%kt>)Ga2}XWRMpNG zB)CoFOClX2mw|BC5BkP8AW1083dFlmG}k~FFbO>}*F;mSfIr*tXuRt$I_C{)Mn!*^ zO6eL>4o7N|6OUeTJn84vivEZk`Gg3;uiHdEBjQu_6>)Fe^c?j$e_PeTm=%zOC-o$# z-o_2Tw%u7Gqk9uO(J-p1(dd8(U2AR?*FpE<D(IT*#9t>auC8Bys?dvf`zH09x!Qw= ak0{o6x#E(0RcKq(&<tIp*Ku6%2LAz77TDPU literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py new file mode 100644 index 0000000..a1158bb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/_base.py @@ -0,0 +1,37 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import Mapping + + +class Trie(Mapping): + """Abstract base class for tries""" + + def keys(self, prefix=None): + # pylint:disable=arguments-differ + keys = super(Trie, self).keys() + + if prefix is None: + return set(keys) + + return {x for x in keys if x.startswith(prefix)} + + def has_keys_with_prefix(self, prefix): + for key in self.keys(): + if key.startswith(prefix): + return True + + return False + + def longest_prefix(self, prefix): + if prefix in self: + return prefix + + for i in range(1, len(prefix) + 1): + if prefix[:-i] in self: + return prefix[:-i] + + raise KeyError(prefix) + + def longest_prefix_item(self, prefix): + lprefix = self.longest_prefix(prefix) + return (lprefix, self[lprefix]) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py new file mode 100644 index 0000000..e2e5f86 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/datrie.py @@ -0,0 +1,44 @@ +from __future__ import absolute_import, division, unicode_literals + +from datrie import Trie as DATrie +from pip._vendor.six import text_type + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + chars = set() + for key in data.keys(): + if not isinstance(key, text_type): + raise TypeError("All keys must be strings") + for char in key: + chars.add(char) + + self._data = DATrie("".join(chars)) + for key, value in data.items(): + self._data[key] = value + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + raise NotImplementedError() + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + return self._data.keys(prefix) + + def has_keys_with_prefix(self, prefix): + return self._data.has_keys_with_prefix(prefix) + + def longest_prefix(self, prefix): + return self._data.longest_prefix(prefix) + + def longest_prefix_item(self, prefix): + return self._data.longest_prefix_item(prefix) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/py.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/py.py new file mode 100644 index 0000000..c178b21 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_trie/py.py @@ -0,0 +1,67 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from bisect import bisect_left + +from ._base import Trie as ABCTrie + + +class Trie(ABCTrie): + def __init__(self, data): + if not all(isinstance(x, text_type) for x in data.keys()): + raise TypeError("All keys must be strings") + + self._data = data + self._keys = sorted(data.keys()) + self._cachestr = "" + self._cachepoints = (0, len(data)) + + def __contains__(self, key): + return key in self._data + + def __len__(self): + return len(self._data) + + def __iter__(self): + return iter(self._data) + + def __getitem__(self, key): + return self._data[key] + + def keys(self, prefix=None): + if prefix is None or prefix == "" or not self._keys: + return set(self._keys) + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + start = i = bisect_left(self._keys, prefix, lo, hi) + else: + start = i = bisect_left(self._keys, prefix) + + keys = set() + if start == len(self._keys): + return keys + + while self._keys[i].startswith(prefix): + keys.add(self._keys[i]) + i += 1 + + self._cachestr = prefix + self._cachepoints = (start, i) + + return keys + + def has_keys_with_prefix(self, prefix): + if prefix in self._data: + return True + + if prefix.startswith(self._cachestr): + lo, hi = self._cachepoints + i = bisect_left(self._keys, prefix, lo, hi) + else: + i = bisect_left(self._keys, prefix) + + if i == len(self._keys): + return False + + return self._keys[i].startswith(prefix) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py new file mode 100644 index 0000000..0703afb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/_utils.py @@ -0,0 +1,124 @@ +from __future__ import absolute_import, division, unicode_literals + +from types import ModuleType + +from pip._vendor.six import text_type + +try: + import xml.etree.cElementTree as default_etree +except ImportError: + import xml.etree.ElementTree as default_etree + + +__all__ = ["default_etree", "MethodDispatcher", "isSurrogatePair", + "surrogatePairToCodepoint", "moduleFactoryFactory", + "supports_lone_surrogates"] + + +# Platforms not supporting lone surrogates (\uD800-\uDFFF) should be +# caught by the below test. In general this would be any platform +# using UTF-16 as its encoding of unicode strings, such as +# Jython. This is because UTF-16 itself is based on the use of such +# surrogates, and there is no mechanism to further escape such +# escapes. +try: + _x = eval('"\\uD800"') # pylint:disable=eval-used + if not isinstance(_x, text_type): + # We need this with u"" because of http://bugs.jython.org/issue2039 + _x = eval('u"\\uD800"') # pylint:disable=eval-used + assert isinstance(_x, text_type) +except: # pylint:disable=bare-except + supports_lone_surrogates = False +else: + supports_lone_surrogates = True + + +class MethodDispatcher(dict): + """Dict with 2 special properties: + + On initiation, keys that are lists, sets or tuples are converted to + multiple keys so accessing any one of the items in the original + list-like object returns the matching value + + md = MethodDispatcher({("foo", "bar"):"baz"}) + md["foo"] == "baz" + + A default value which can be set through the default attribute. + """ + + def __init__(self, items=()): + # Using _dictEntries instead of directly assigning to self is about + # twice as fast. Please do careful performance testing before changing + # anything here. + _dictEntries = [] + for name, value in items: + if isinstance(name, (list, tuple, frozenset, set)): + for item in name: + _dictEntries.append((item, value)) + else: + _dictEntries.append((name, value)) + dict.__init__(self, _dictEntries) + assert len(self) == len(_dictEntries) + self.default = None + + def __getitem__(self, key): + return dict.get(self, key, self.default) + + +# Some utility functions to deal with weirdness around UCS2 vs UCS4 +# python builds + +def isSurrogatePair(data): + return (len(data) == 2 and + ord(data[0]) >= 0xD800 and ord(data[0]) <= 0xDBFF and + ord(data[1]) >= 0xDC00 and ord(data[1]) <= 0xDFFF) + + +def surrogatePairToCodepoint(data): + char_val = (0x10000 + (ord(data[0]) - 0xD800) * 0x400 + + (ord(data[1]) - 0xDC00)) + return char_val + +# Module Factory Factory (no, this isn't Java, I know) +# Here to stop this being duplicated all over the place. + + +def moduleFactoryFactory(factory): + moduleCache = {} + + def moduleFactory(baseModule, *args, **kwargs): + if isinstance(ModuleType.__name__, type("")): + name = "_%s_factory" % baseModule.__name__ + else: + name = b"_%s_factory" % baseModule.__name__ + + kwargs_tuple = tuple(kwargs.items()) + + try: + return moduleCache[name][args][kwargs_tuple] + except KeyError: + mod = ModuleType(name) + objs = factory(baseModule, *args, **kwargs) + mod.__dict__.update(objs) + if "name" not in moduleCache: + moduleCache[name] = {} + if "args" not in moduleCache[name]: + moduleCache[name][args] = {} + if "kwargs" not in moduleCache[name][args]: + moduleCache[name][args][kwargs_tuple] = {} + moduleCache[name][args][kwargs_tuple] = mod + return mod + + return moduleFactory + + +def memoize(func): + cache = {} + + def wrapped(*args, **kwargs): + key = (tuple(args), tuple(kwargs.items())) + if key not in cache: + cache[key] = func(*args, **kwargs) + return cache[key] + + return wrapped diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py new file mode 100644 index 0000000..1ff8041 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/constants.py @@ -0,0 +1,2947 @@ +from __future__ import absolute_import, division, unicode_literals + +import string + +EOF = None + +E = { + "null-character": + "Null character in input stream, replaced with U+FFFD.", + "invalid-codepoint": + "Invalid codepoint in stream.", + "incorrectly-placed-solidus": + "Solidus (/) incorrectly placed in tag.", + "incorrect-cr-newline-entity": + "Incorrect CR newline entity, replaced with LF.", + "illegal-windows-1252-entity": + "Entity used with illegal number (windows-1252 reference).", + "cant-convert-numeric-entity": + "Numeric entity couldn't be converted to character " + "(codepoint U+%(charAsInt)08x).", + "illegal-codepoint-for-numeric-entity": + "Numeric entity represents an illegal codepoint: " + "U+%(charAsInt)08x.", + "numeric-entity-without-semicolon": + "Numeric entity didn't end with ';'.", + "expected-numeric-entity-but-got-eof": + "Numeric entity expected. Got end of file instead.", + "expected-numeric-entity": + "Numeric entity expected but none found.", + "named-entity-without-semicolon": + "Named entity didn't end with ';'.", + "expected-named-entity": + "Named entity expected. Got none.", + "attributes-in-end-tag": + "End tag contains unexpected attributes.", + 'self-closing-flag-on-end-tag': + "End tag contains unexpected self-closing flag.", + "expected-tag-name-but-got-right-bracket": + "Expected tag name. Got '>' instead.", + "expected-tag-name-but-got-question-mark": + "Expected tag name. Got '?' instead. (HTML doesn't " + "support processing instructions.)", + "expected-tag-name": + "Expected tag name. Got something else instead", + "expected-closing-tag-but-got-right-bracket": + "Expected closing tag. Got '>' instead. Ignoring '</>'.", + "expected-closing-tag-but-got-eof": + "Expected closing tag. Unexpected end of file.", + "expected-closing-tag-but-got-char": + "Expected closing tag. Unexpected character '%(data)s' found.", + "eof-in-tag-name": + "Unexpected end of file in the tag name.", + "expected-attribute-name-but-got-eof": + "Unexpected end of file. Expected attribute name instead.", + "eof-in-attribute-name": + "Unexpected end of file in attribute name.", + "invalid-character-in-attribute-name": + "Invalid character in attribute name", + "duplicate-attribute": + "Dropped duplicate attribute on tag.", + "expected-end-of-tag-name-but-got-eof": + "Unexpected end of file. Expected = or end of tag.", + "expected-attribute-value-but-got-eof": + "Unexpected end of file. Expected attribute value.", + "expected-attribute-value-but-got-right-bracket": + "Expected attribute value. Got '>' instead.", + 'equals-in-unquoted-attribute-value': + "Unexpected = in unquoted attribute", + 'unexpected-character-in-unquoted-attribute-value': + "Unexpected character in unquoted attribute", + "invalid-character-after-attribute-name": + "Unexpected character after attribute name.", + "unexpected-character-after-attribute-value": + "Unexpected character after attribute value.", + "eof-in-attribute-value-double-quote": + "Unexpected end of file in attribute value (\").", + "eof-in-attribute-value-single-quote": + "Unexpected end of file in attribute value (').", + "eof-in-attribute-value-no-quotes": + "Unexpected end of file in attribute value.", + "unexpected-EOF-after-solidus-in-tag": + "Unexpected end of file in tag. Expected >", + "unexpected-character-after-solidus-in-tag": + "Unexpected character after / in tag. Expected >", + "expected-dashes-or-doctype": + "Expected '--' or 'DOCTYPE'. Not found.", + "unexpected-bang-after-double-dash-in-comment": + "Unexpected ! after -- in comment", + "unexpected-space-after-double-dash-in-comment": + "Unexpected space after -- in comment", + "incorrect-comment": + "Incorrect comment.", + "eof-in-comment": + "Unexpected end of file in comment.", + "eof-in-comment-end-dash": + "Unexpected end of file in comment (-)", + "unexpected-dash-after-double-dash-in-comment": + "Unexpected '-' after '--' found in comment.", + "eof-in-comment-double-dash": + "Unexpected end of file in comment (--).", + "eof-in-comment-end-space-state": + "Unexpected end of file in comment.", + "eof-in-comment-end-bang-state": + "Unexpected end of file in comment.", + "unexpected-char-in-comment": + "Unexpected character in comment found.", + "need-space-after-doctype": + "No space after literal string 'DOCTYPE'.", + "expected-doctype-name-but-got-right-bracket": + "Unexpected > character. Expected DOCTYPE name.", + "expected-doctype-name-but-got-eof": + "Unexpected end of file. Expected DOCTYPE name.", + "eof-in-doctype-name": + "Unexpected end of file in DOCTYPE name.", + "eof-in-doctype": + "Unexpected end of file in DOCTYPE.", + "expected-space-or-right-bracket-in-doctype": + "Expected space or '>'. Got '%(data)s'", + "unexpected-end-of-doctype": + "Unexpected end of DOCTYPE.", + "unexpected-char-in-doctype": + "Unexpected character in DOCTYPE.", + "eof-in-innerhtml": + "XXX innerHTML EOF", + "unexpected-doctype": + "Unexpected DOCTYPE. Ignored.", + "non-html-root": + "html needs to be the first start tag.", + "expected-doctype-but-got-eof": + "Unexpected End of file. Expected DOCTYPE.", + "unknown-doctype": + "Erroneous DOCTYPE.", + "expected-doctype-but-got-chars": + "Unexpected non-space characters. Expected DOCTYPE.", + "expected-doctype-but-got-start-tag": + "Unexpected start tag (%(name)s). Expected DOCTYPE.", + "expected-doctype-but-got-end-tag": + "Unexpected end tag (%(name)s). Expected DOCTYPE.", + "end-tag-after-implied-root": + "Unexpected end tag (%(name)s) after the (implied) root element.", + "expected-named-closing-tag-but-got-eof": + "Unexpected end of file. Expected end tag (%(name)s).", + "two-heads-are-not-better-than-one": + "Unexpected start tag head in existing head. Ignored.", + "unexpected-end-tag": + "Unexpected end tag (%(name)s). Ignored.", + "unexpected-start-tag-out-of-my-head": + "Unexpected start tag (%(name)s) that can be in head. Moved.", + "unexpected-start-tag": + "Unexpected start tag (%(name)s).", + "missing-end-tag": + "Missing end tag (%(name)s).", + "missing-end-tags": + "Missing end tags (%(name)s).", + "unexpected-start-tag-implies-end-tag": + "Unexpected start tag (%(startName)s) " + "implies end tag (%(endName)s).", + "unexpected-start-tag-treated-as": + "Unexpected start tag (%(originalName)s). Treated as %(newName)s.", + "deprecated-tag": + "Unexpected start tag %(name)s. Don't use it!", + "unexpected-start-tag-ignored": + "Unexpected start tag %(name)s. Ignored.", + "expected-one-end-tag-but-got-another": + "Unexpected end tag (%(gotName)s). " + "Missing end tag (%(expectedName)s).", + "end-tag-too-early": + "End tag (%(name)s) seen too early. Expected other end tag.", + "end-tag-too-early-named": + "Unexpected end tag (%(gotName)s). Expected end tag (%(expectedName)s).", + "end-tag-too-early-ignored": + "End tag (%(name)s) seen too early. Ignored.", + "adoption-agency-1.1": + "End tag (%(name)s) violates step 1, " + "paragraph 1 of the adoption agency algorithm.", + "adoption-agency-1.2": + "End tag (%(name)s) violates step 1, " + "paragraph 2 of the adoption agency algorithm.", + "adoption-agency-1.3": + "End tag (%(name)s) violates step 1, " + "paragraph 3 of the adoption agency algorithm.", + "adoption-agency-4.4": + "End tag (%(name)s) violates step 4, " + "paragraph 4 of the adoption agency algorithm.", + "unexpected-end-tag-treated-as": + "Unexpected end tag (%(originalName)s). Treated as %(newName)s.", + "no-end-tag": + "This element (%(name)s) has no end tag.", + "unexpected-implied-end-tag-in-table": + "Unexpected implied end tag (%(name)s) in the table phase.", + "unexpected-implied-end-tag-in-table-body": + "Unexpected implied end tag (%(name)s) in the table body phase.", + "unexpected-char-implies-table-voodoo": + "Unexpected non-space characters in " + "table context caused voodoo mode.", + "unexpected-hidden-input-in-table": + "Unexpected input with type hidden in table context.", + "unexpected-form-in-table": + "Unexpected form in table context.", + "unexpected-start-tag-implies-table-voodoo": + "Unexpected start tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-end-tag-implies-table-voodoo": + "Unexpected end tag (%(name)s) in " + "table context caused voodoo mode.", + "unexpected-cell-in-table-body": + "Unexpected table cell start tag (%(name)s) " + "in the table body phase.", + "unexpected-cell-end-tag": + "Got table cell end tag (%(name)s) " + "while required end tags are missing.", + "unexpected-end-tag-in-table-body": + "Unexpected end tag (%(name)s) in the table body phase. Ignored.", + "unexpected-implied-end-tag-in-table-row": + "Unexpected implied end tag (%(name)s) in the table row phase.", + "unexpected-end-tag-in-table-row": + "Unexpected end tag (%(name)s) in the table row phase. Ignored.", + "unexpected-select-in-select": + "Unexpected select start tag in the select phase " + "treated as select end tag.", + "unexpected-input-in-select": + "Unexpected input start tag in the select phase.", + "unexpected-start-tag-in-select": + "Unexpected start tag token (%(name)s in the select phase. " + "Ignored.", + "unexpected-end-tag-in-select": + "Unexpected end tag (%(name)s) in the select phase. Ignored.", + "unexpected-table-element-start-tag-in-select-in-table": + "Unexpected table element start tag (%(name)s) in the select in table phase.", + "unexpected-table-element-end-tag-in-select-in-table": + "Unexpected table element end tag (%(name)s) in the select in table phase.", + "unexpected-char-after-body": + "Unexpected non-space characters in the after body phase.", + "unexpected-start-tag-after-body": + "Unexpected start tag token (%(name)s)" + " in the after body phase.", + "unexpected-end-tag-after-body": + "Unexpected end tag token (%(name)s)" + " in the after body phase.", + "unexpected-char-in-frameset": + "Unexpected characters in the frameset phase. Characters ignored.", + "unexpected-start-tag-in-frameset": + "Unexpected start tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-frameset-in-frameset-innerhtml": + "Unexpected end tag token (frameset) " + "in the frameset phase (innerHTML).", + "unexpected-end-tag-in-frameset": + "Unexpected end tag token (%(name)s)" + " in the frameset phase. Ignored.", + "unexpected-char-after-frameset": + "Unexpected non-space characters in the " + "after frameset phase. Ignored.", + "unexpected-start-tag-after-frameset": + "Unexpected start tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-frameset": + "Unexpected end tag (%(name)s)" + " in the after frameset phase. Ignored.", + "unexpected-end-tag-after-body-innerhtml": + "Unexpected end tag after body(innerHtml)", + "expected-eof-but-got-char": + "Unexpected non-space characters. Expected end of file.", + "expected-eof-but-got-start-tag": + "Unexpected start tag (%(name)s)" + ". Expected end of file.", + "expected-eof-but-got-end-tag": + "Unexpected end tag (%(name)s)" + ". Expected end of file.", + "eof-in-table": + "Unexpected end of file. Expected table content.", + "eof-in-select": + "Unexpected end of file. Expected select content.", + "eof-in-frameset": + "Unexpected end of file. Expected frameset content.", + "eof-in-script-in-script": + "Unexpected end of file. Expected script content.", + "eof-in-foreign-lands": + "Unexpected end of file. Expected foreign content", + "non-void-element-with-trailing-solidus": + "Trailing solidus not allowed on element %(name)s", + "unexpected-html-element-in-foreign-content": + "Element %(name)s not allowed in a non-html context", + "unexpected-end-tag-before-html": + "Unexpected end tag (%(name)s) before html.", + "unexpected-inhead-noscript-tag": + "Element %(name)s not allowed in a inhead-noscript context", + "eof-in-head-noscript": + "Unexpected end of file. Expected inhead-noscript content", + "char-in-head-noscript": + "Unexpected non-space character. Expected inhead-noscript content", + "XXX-undefined-error": + "Undefined error (this sucks and should be fixed)", +} + +namespaces = { + "html": "http://www.w3.org/1999/xhtml", + "mathml": "http://www.w3.org/1998/Math/MathML", + "svg": "http://www.w3.org/2000/svg", + "xlink": "http://www.w3.org/1999/xlink", + "xml": "http://www.w3.org/XML/1998/namespace", + "xmlns": "http://www.w3.org/2000/xmlns/" +} + +scopingElements = frozenset([ + (namespaces["html"], "applet"), + (namespaces["html"], "caption"), + (namespaces["html"], "html"), + (namespaces["html"], "marquee"), + (namespaces["html"], "object"), + (namespaces["html"], "table"), + (namespaces["html"], "td"), + (namespaces["html"], "th"), + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext"), + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title"), +]) + +formattingElements = frozenset([ + (namespaces["html"], "a"), + (namespaces["html"], "b"), + (namespaces["html"], "big"), + (namespaces["html"], "code"), + (namespaces["html"], "em"), + (namespaces["html"], "font"), + (namespaces["html"], "i"), + (namespaces["html"], "nobr"), + (namespaces["html"], "s"), + (namespaces["html"], "small"), + (namespaces["html"], "strike"), + (namespaces["html"], "strong"), + (namespaces["html"], "tt"), + (namespaces["html"], "u") +]) + +specialElements = frozenset([ + (namespaces["html"], "address"), + (namespaces["html"], "applet"), + (namespaces["html"], "area"), + (namespaces["html"], "article"), + (namespaces["html"], "aside"), + (namespaces["html"], "base"), + (namespaces["html"], "basefont"), + (namespaces["html"], "bgsound"), + (namespaces["html"], "blockquote"), + (namespaces["html"], "body"), + (namespaces["html"], "br"), + (namespaces["html"], "button"), + (namespaces["html"], "caption"), + (namespaces["html"], "center"), + (namespaces["html"], "col"), + (namespaces["html"], "colgroup"), + (namespaces["html"], "command"), + (namespaces["html"], "dd"), + (namespaces["html"], "details"), + (namespaces["html"], "dir"), + (namespaces["html"], "div"), + (namespaces["html"], "dl"), + (namespaces["html"], "dt"), + (namespaces["html"], "embed"), + (namespaces["html"], "fieldset"), + (namespaces["html"], "figure"), + (namespaces["html"], "footer"), + (namespaces["html"], "form"), + (namespaces["html"], "frame"), + (namespaces["html"], "frameset"), + (namespaces["html"], "h1"), + (namespaces["html"], "h2"), + (namespaces["html"], "h3"), + (namespaces["html"], "h4"), + (namespaces["html"], "h5"), + (namespaces["html"], "h6"), + (namespaces["html"], "head"), + (namespaces["html"], "header"), + (namespaces["html"], "hr"), + (namespaces["html"], "html"), + (namespaces["html"], "iframe"), + # Note that image is commented out in the spec as "this isn't an + # element that can end up on the stack, so it doesn't matter," + (namespaces["html"], "image"), + (namespaces["html"], "img"), + (namespaces["html"], "input"), + (namespaces["html"], "isindex"), + (namespaces["html"], "li"), + (namespaces["html"], "link"), + (namespaces["html"], "listing"), + (namespaces["html"], "marquee"), + (namespaces["html"], "menu"), + (namespaces["html"], "meta"), + (namespaces["html"], "nav"), + (namespaces["html"], "noembed"), + (namespaces["html"], "noframes"), + (namespaces["html"], "noscript"), + (namespaces["html"], "object"), + (namespaces["html"], "ol"), + (namespaces["html"], "p"), + (namespaces["html"], "param"), + (namespaces["html"], "plaintext"), + (namespaces["html"], "pre"), + (namespaces["html"], "script"), + (namespaces["html"], "section"), + (namespaces["html"], "select"), + (namespaces["html"], "style"), + (namespaces["html"], "table"), + (namespaces["html"], "tbody"), + (namespaces["html"], "td"), + (namespaces["html"], "textarea"), + (namespaces["html"], "tfoot"), + (namespaces["html"], "th"), + (namespaces["html"], "thead"), + (namespaces["html"], "title"), + (namespaces["html"], "tr"), + (namespaces["html"], "ul"), + (namespaces["html"], "wbr"), + (namespaces["html"], "xmp"), + (namespaces["svg"], "foreignObject") +]) + +htmlIntegrationPointElements = frozenset([ + (namespaces["mathml"], "annotation-xml"), + (namespaces["svg"], "foreignObject"), + (namespaces["svg"], "desc"), + (namespaces["svg"], "title") +]) + +mathmlTextIntegrationPointElements = frozenset([ + (namespaces["mathml"], "mi"), + (namespaces["mathml"], "mo"), + (namespaces["mathml"], "mn"), + (namespaces["mathml"], "ms"), + (namespaces["mathml"], "mtext") +]) + +adjustSVGAttributes = { + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "contentscripttype": "contentScriptType", + "contentstyletype": "contentStyleType", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "externalresourcesrequired": "externalResourcesRequired", + "filterres": "filterRes", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan" +} + +adjustMathMLAttributes = {"definitionurl": "definitionURL"} + +adjustForeignAttributes = { + "xlink:actuate": ("xlink", "actuate", namespaces["xlink"]), + "xlink:arcrole": ("xlink", "arcrole", namespaces["xlink"]), + "xlink:href": ("xlink", "href", namespaces["xlink"]), + "xlink:role": ("xlink", "role", namespaces["xlink"]), + "xlink:show": ("xlink", "show", namespaces["xlink"]), + "xlink:title": ("xlink", "title", namespaces["xlink"]), + "xlink:type": ("xlink", "type", namespaces["xlink"]), + "xml:base": ("xml", "base", namespaces["xml"]), + "xml:lang": ("xml", "lang", namespaces["xml"]), + "xml:space": ("xml", "space", namespaces["xml"]), + "xmlns": (None, "xmlns", namespaces["xmlns"]), + "xmlns:xlink": ("xmlns", "xlink", namespaces["xmlns"]) +} + +unadjustForeignAttributes = dict([((ns, local), qname) for qname, (prefix, local, ns) in + adjustForeignAttributes.items()]) + +spaceCharacters = frozenset([ + "\t", + "\n", + "\u000C", + " ", + "\r" +]) + +tableInsertModeElements = frozenset([ + "table", + "tbody", + "tfoot", + "thead", + "tr" +]) + +asciiLowercase = frozenset(string.ascii_lowercase) +asciiUppercase = frozenset(string.ascii_uppercase) +asciiLetters = frozenset(string.ascii_letters) +digits = frozenset(string.digits) +hexDigits = frozenset(string.hexdigits) + +asciiUpper2Lower = dict([(ord(c), ord(c.lower())) + for c in string.ascii_uppercase]) + +# Heading elements need to be ordered +headingElements = ( + "h1", + "h2", + "h3", + "h4", + "h5", + "h6" +) + +voidElements = frozenset([ + "base", + "command", + "event-source", + "link", + "meta", + "hr", + "br", + "img", + "embed", + "param", + "area", + "col", + "input", + "source", + "track" +]) + +cdataElements = frozenset(['title', 'textarea']) + +rcdataElements = frozenset([ + 'style', + 'script', + 'xmp', + 'iframe', + 'noembed', + 'noframes', + 'noscript' +]) + +booleanAttributes = { + "": frozenset(["irrelevant", "itemscope"]), + "style": frozenset(["scoped"]), + "img": frozenset(["ismap"]), + "audio": frozenset(["autoplay", "controls"]), + "video": frozenset(["autoplay", "controls"]), + "script": frozenset(["defer", "async"]), + "details": frozenset(["open"]), + "datagrid": frozenset(["multiple", "disabled"]), + "command": frozenset(["hidden", "disabled", "checked", "default"]), + "hr": frozenset(["noshade"]), + "menu": frozenset(["autosubmit"]), + "fieldset": frozenset(["disabled", "readonly"]), + "option": frozenset(["disabled", "readonly", "selected"]), + "optgroup": frozenset(["disabled", "readonly"]), + "button": frozenset(["disabled", "autofocus"]), + "input": frozenset(["disabled", "readonly", "required", "autofocus", "checked", "ismap"]), + "select": frozenset(["disabled", "readonly", "autofocus", "multiple"]), + "output": frozenset(["disabled", "readonly"]), + "iframe": frozenset(["seamless"]), +} + +# entitiesWindows1252 has to be _ordered_ and needs to have an index. It +# therefore can't be a frozenset. +entitiesWindows1252 = ( + 8364, # 0x80 0x20AC EURO SIGN + 65533, # 0x81 UNDEFINED + 8218, # 0x82 0x201A SINGLE LOW-9 QUOTATION MARK + 402, # 0x83 0x0192 LATIN SMALL LETTER F WITH HOOK + 8222, # 0x84 0x201E DOUBLE LOW-9 QUOTATION MARK + 8230, # 0x85 0x2026 HORIZONTAL ELLIPSIS + 8224, # 0x86 0x2020 DAGGER + 8225, # 0x87 0x2021 DOUBLE DAGGER + 710, # 0x88 0x02C6 MODIFIER LETTER CIRCUMFLEX ACCENT + 8240, # 0x89 0x2030 PER MILLE SIGN + 352, # 0x8A 0x0160 LATIN CAPITAL LETTER S WITH CARON + 8249, # 0x8B 0x2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK + 338, # 0x8C 0x0152 LATIN CAPITAL LIGATURE OE + 65533, # 0x8D UNDEFINED + 381, # 0x8E 0x017D LATIN CAPITAL LETTER Z WITH CARON + 65533, # 0x8F UNDEFINED + 65533, # 0x90 UNDEFINED + 8216, # 0x91 0x2018 LEFT SINGLE QUOTATION MARK + 8217, # 0x92 0x2019 RIGHT SINGLE QUOTATION MARK + 8220, # 0x93 0x201C LEFT DOUBLE QUOTATION MARK + 8221, # 0x94 0x201D RIGHT DOUBLE QUOTATION MARK + 8226, # 0x95 0x2022 BULLET + 8211, # 0x96 0x2013 EN DASH + 8212, # 0x97 0x2014 EM DASH + 732, # 0x98 0x02DC SMALL TILDE + 8482, # 0x99 0x2122 TRADE MARK SIGN + 353, # 0x9A 0x0161 LATIN SMALL LETTER S WITH CARON + 8250, # 0x9B 0x203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + 339, # 0x9C 0x0153 LATIN SMALL LIGATURE OE + 65533, # 0x9D UNDEFINED + 382, # 0x9E 0x017E LATIN SMALL LETTER Z WITH CARON + 376 # 0x9F 0x0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +) + +xmlEntities = frozenset(['lt;', 'gt;', 'amp;', 'apos;', 'quot;']) + +entities = { + "AElig": "\xc6", + "AElig;": "\xc6", + "AMP": "&", + "AMP;": "&", + "Aacute": "\xc1", + "Aacute;": "\xc1", + "Abreve;": "\u0102", + "Acirc": "\xc2", + "Acirc;": "\xc2", + "Acy;": "\u0410", + "Afr;": "\U0001d504", + "Agrave": "\xc0", + "Agrave;": "\xc0", + "Alpha;": "\u0391", + "Amacr;": "\u0100", + "And;": "\u2a53", + "Aogon;": "\u0104", + "Aopf;": "\U0001d538", + "ApplyFunction;": "\u2061", + "Aring": "\xc5", + "Aring;": "\xc5", + "Ascr;": "\U0001d49c", + "Assign;": "\u2254", + "Atilde": "\xc3", + "Atilde;": "\xc3", + "Auml": "\xc4", + "Auml;": "\xc4", + "Backslash;": "\u2216", + "Barv;": "\u2ae7", + "Barwed;": "\u2306", + "Bcy;": "\u0411", + "Because;": "\u2235", + "Bernoullis;": "\u212c", + "Beta;": "\u0392", + "Bfr;": "\U0001d505", + "Bopf;": "\U0001d539", + "Breve;": "\u02d8", + "Bscr;": "\u212c", + "Bumpeq;": "\u224e", + "CHcy;": "\u0427", + "COPY": "\xa9", + "COPY;": "\xa9", + "Cacute;": "\u0106", + "Cap;": "\u22d2", + "CapitalDifferentialD;": "\u2145", + "Cayleys;": "\u212d", + "Ccaron;": "\u010c", + "Ccedil": "\xc7", + "Ccedil;": "\xc7", + "Ccirc;": "\u0108", + "Cconint;": "\u2230", + "Cdot;": "\u010a", + "Cedilla;": "\xb8", + "CenterDot;": "\xb7", + "Cfr;": "\u212d", + "Chi;": "\u03a7", + "CircleDot;": "\u2299", + "CircleMinus;": "\u2296", + "CirclePlus;": "\u2295", + "CircleTimes;": "\u2297", + "ClockwiseContourIntegral;": "\u2232", + "CloseCurlyDoubleQuote;": "\u201d", + "CloseCurlyQuote;": "\u2019", + "Colon;": "\u2237", + "Colone;": "\u2a74", + "Congruent;": "\u2261", + "Conint;": "\u222f", + "ContourIntegral;": "\u222e", + "Copf;": "\u2102", + "Coproduct;": "\u2210", + "CounterClockwiseContourIntegral;": "\u2233", + "Cross;": "\u2a2f", + "Cscr;": "\U0001d49e", + "Cup;": "\u22d3", + "CupCap;": "\u224d", + "DD;": "\u2145", + "DDotrahd;": "\u2911", + "DJcy;": "\u0402", + "DScy;": "\u0405", + "DZcy;": "\u040f", + "Dagger;": "\u2021", + "Darr;": "\u21a1", + "Dashv;": "\u2ae4", + "Dcaron;": "\u010e", + "Dcy;": "\u0414", + "Del;": "\u2207", + "Delta;": "\u0394", + "Dfr;": "\U0001d507", + "DiacriticalAcute;": "\xb4", + "DiacriticalDot;": "\u02d9", + "DiacriticalDoubleAcute;": "\u02dd", + "DiacriticalGrave;": "`", + "DiacriticalTilde;": "\u02dc", + "Diamond;": "\u22c4", + "DifferentialD;": "\u2146", + "Dopf;": "\U0001d53b", + "Dot;": "\xa8", + "DotDot;": "\u20dc", + "DotEqual;": "\u2250", + "DoubleContourIntegral;": "\u222f", + "DoubleDot;": "\xa8", + "DoubleDownArrow;": "\u21d3", + "DoubleLeftArrow;": "\u21d0", + "DoubleLeftRightArrow;": "\u21d4", + "DoubleLeftTee;": "\u2ae4", + "DoubleLongLeftArrow;": "\u27f8", + "DoubleLongLeftRightArrow;": "\u27fa", + "DoubleLongRightArrow;": "\u27f9", + "DoubleRightArrow;": "\u21d2", + "DoubleRightTee;": "\u22a8", + "DoubleUpArrow;": "\u21d1", + "DoubleUpDownArrow;": "\u21d5", + "DoubleVerticalBar;": "\u2225", + "DownArrow;": "\u2193", + "DownArrowBar;": "\u2913", + "DownArrowUpArrow;": "\u21f5", + "DownBreve;": "\u0311", + "DownLeftRightVector;": "\u2950", + "DownLeftTeeVector;": "\u295e", + "DownLeftVector;": "\u21bd", + "DownLeftVectorBar;": "\u2956", + "DownRightTeeVector;": "\u295f", + "DownRightVector;": "\u21c1", + "DownRightVectorBar;": "\u2957", + "DownTee;": "\u22a4", + "DownTeeArrow;": "\u21a7", + "Downarrow;": "\u21d3", + "Dscr;": "\U0001d49f", + "Dstrok;": "\u0110", + "ENG;": "\u014a", + "ETH": "\xd0", + "ETH;": "\xd0", + "Eacute": "\xc9", + "Eacute;": "\xc9", + "Ecaron;": "\u011a", + "Ecirc": "\xca", + "Ecirc;": "\xca", + "Ecy;": "\u042d", + "Edot;": "\u0116", + "Efr;": "\U0001d508", + "Egrave": "\xc8", + "Egrave;": "\xc8", + "Element;": "\u2208", + "Emacr;": "\u0112", + "EmptySmallSquare;": "\u25fb", + "EmptyVerySmallSquare;": "\u25ab", + "Eogon;": "\u0118", + "Eopf;": "\U0001d53c", + "Epsilon;": "\u0395", + "Equal;": "\u2a75", + "EqualTilde;": "\u2242", + "Equilibrium;": "\u21cc", + "Escr;": "\u2130", + "Esim;": "\u2a73", + "Eta;": "\u0397", + "Euml": "\xcb", + "Euml;": "\xcb", + "Exists;": "\u2203", + "ExponentialE;": "\u2147", + "Fcy;": "\u0424", + "Ffr;": "\U0001d509", + "FilledSmallSquare;": "\u25fc", + "FilledVerySmallSquare;": "\u25aa", + "Fopf;": "\U0001d53d", + "ForAll;": "\u2200", + "Fouriertrf;": "\u2131", + "Fscr;": "\u2131", + "GJcy;": "\u0403", + "GT": ">", + "GT;": ">", + "Gamma;": "\u0393", + "Gammad;": "\u03dc", + "Gbreve;": "\u011e", + "Gcedil;": "\u0122", + "Gcirc;": "\u011c", + "Gcy;": "\u0413", + "Gdot;": "\u0120", + "Gfr;": "\U0001d50a", + "Gg;": "\u22d9", + "Gopf;": "\U0001d53e", + "GreaterEqual;": "\u2265", + "GreaterEqualLess;": "\u22db", + "GreaterFullEqual;": "\u2267", + "GreaterGreater;": "\u2aa2", + "GreaterLess;": "\u2277", + "GreaterSlantEqual;": "\u2a7e", + "GreaterTilde;": "\u2273", + "Gscr;": "\U0001d4a2", + "Gt;": "\u226b", + "HARDcy;": "\u042a", + "Hacek;": "\u02c7", + "Hat;": "^", + "Hcirc;": "\u0124", + "Hfr;": "\u210c", + "HilbertSpace;": "\u210b", + "Hopf;": "\u210d", + "HorizontalLine;": "\u2500", + "Hscr;": "\u210b", + "Hstrok;": "\u0126", + "HumpDownHump;": "\u224e", + "HumpEqual;": "\u224f", + "IEcy;": "\u0415", + "IJlig;": "\u0132", + "IOcy;": "\u0401", + "Iacute": "\xcd", + "Iacute;": "\xcd", + "Icirc": "\xce", + "Icirc;": "\xce", + "Icy;": "\u0418", + "Idot;": "\u0130", + "Ifr;": "\u2111", + "Igrave": "\xcc", + "Igrave;": "\xcc", + "Im;": "\u2111", + "Imacr;": "\u012a", + "ImaginaryI;": "\u2148", + "Implies;": "\u21d2", + "Int;": "\u222c", + "Integral;": "\u222b", + "Intersection;": "\u22c2", + "InvisibleComma;": "\u2063", + "InvisibleTimes;": "\u2062", + "Iogon;": "\u012e", + "Iopf;": "\U0001d540", + "Iota;": "\u0399", + "Iscr;": "\u2110", + "Itilde;": "\u0128", + "Iukcy;": "\u0406", + "Iuml": "\xcf", + "Iuml;": "\xcf", + "Jcirc;": "\u0134", + "Jcy;": "\u0419", + "Jfr;": "\U0001d50d", + "Jopf;": "\U0001d541", + "Jscr;": "\U0001d4a5", + "Jsercy;": "\u0408", + "Jukcy;": "\u0404", + "KHcy;": "\u0425", + "KJcy;": "\u040c", + "Kappa;": "\u039a", + "Kcedil;": "\u0136", + "Kcy;": "\u041a", + "Kfr;": "\U0001d50e", + "Kopf;": "\U0001d542", + "Kscr;": "\U0001d4a6", + "LJcy;": "\u0409", + "LT": "<", + "LT;": "<", + "Lacute;": "\u0139", + "Lambda;": "\u039b", + "Lang;": "\u27ea", + "Laplacetrf;": "\u2112", + "Larr;": "\u219e", + "Lcaron;": "\u013d", + "Lcedil;": "\u013b", + "Lcy;": "\u041b", + "LeftAngleBracket;": "\u27e8", + "LeftArrow;": "\u2190", + "LeftArrowBar;": "\u21e4", + "LeftArrowRightArrow;": "\u21c6", + "LeftCeiling;": "\u2308", + "LeftDoubleBracket;": "\u27e6", + "LeftDownTeeVector;": "\u2961", + "LeftDownVector;": "\u21c3", + "LeftDownVectorBar;": "\u2959", + "LeftFloor;": "\u230a", + "LeftRightArrow;": "\u2194", + "LeftRightVector;": "\u294e", + "LeftTee;": "\u22a3", + "LeftTeeArrow;": "\u21a4", + "LeftTeeVector;": "\u295a", + "LeftTriangle;": "\u22b2", + "LeftTriangleBar;": "\u29cf", + "LeftTriangleEqual;": "\u22b4", + "LeftUpDownVector;": "\u2951", + "LeftUpTeeVector;": "\u2960", + "LeftUpVector;": "\u21bf", + "LeftUpVectorBar;": "\u2958", + "LeftVector;": "\u21bc", + "LeftVectorBar;": "\u2952", + "Leftarrow;": "\u21d0", + "Leftrightarrow;": "\u21d4", + "LessEqualGreater;": "\u22da", + "LessFullEqual;": "\u2266", + "LessGreater;": "\u2276", + "LessLess;": "\u2aa1", + "LessSlantEqual;": "\u2a7d", + "LessTilde;": "\u2272", + "Lfr;": "\U0001d50f", + "Ll;": "\u22d8", + "Lleftarrow;": "\u21da", + "Lmidot;": "\u013f", + "LongLeftArrow;": "\u27f5", + "LongLeftRightArrow;": "\u27f7", + "LongRightArrow;": "\u27f6", + "Longleftarrow;": "\u27f8", + "Longleftrightarrow;": "\u27fa", + "Longrightarrow;": "\u27f9", + "Lopf;": "\U0001d543", + "LowerLeftArrow;": "\u2199", + "LowerRightArrow;": "\u2198", + "Lscr;": "\u2112", + "Lsh;": "\u21b0", + "Lstrok;": "\u0141", + "Lt;": "\u226a", + "Map;": "\u2905", + "Mcy;": "\u041c", + "MediumSpace;": "\u205f", + "Mellintrf;": "\u2133", + "Mfr;": "\U0001d510", + "MinusPlus;": "\u2213", + "Mopf;": "\U0001d544", + "Mscr;": "\u2133", + "Mu;": "\u039c", + "NJcy;": "\u040a", + "Nacute;": "\u0143", + "Ncaron;": "\u0147", + "Ncedil;": "\u0145", + "Ncy;": "\u041d", + "NegativeMediumSpace;": "\u200b", + "NegativeThickSpace;": "\u200b", + "NegativeThinSpace;": "\u200b", + "NegativeVeryThinSpace;": "\u200b", + "NestedGreaterGreater;": "\u226b", + "NestedLessLess;": "\u226a", + "NewLine;": "\n", + "Nfr;": "\U0001d511", + "NoBreak;": "\u2060", + "NonBreakingSpace;": "\xa0", + "Nopf;": "\u2115", + "Not;": "\u2aec", + "NotCongruent;": "\u2262", + "NotCupCap;": "\u226d", + "NotDoubleVerticalBar;": "\u2226", + "NotElement;": "\u2209", + "NotEqual;": "\u2260", + "NotEqualTilde;": "\u2242\u0338", + "NotExists;": "\u2204", + "NotGreater;": "\u226f", + "NotGreaterEqual;": "\u2271", + "NotGreaterFullEqual;": "\u2267\u0338", + "NotGreaterGreater;": "\u226b\u0338", + "NotGreaterLess;": "\u2279", + "NotGreaterSlantEqual;": "\u2a7e\u0338", + "NotGreaterTilde;": "\u2275", + "NotHumpDownHump;": "\u224e\u0338", + "NotHumpEqual;": "\u224f\u0338", + "NotLeftTriangle;": "\u22ea", + "NotLeftTriangleBar;": "\u29cf\u0338", + "NotLeftTriangleEqual;": "\u22ec", + "NotLess;": "\u226e", + "NotLessEqual;": "\u2270", + "NotLessGreater;": "\u2278", + "NotLessLess;": "\u226a\u0338", + "NotLessSlantEqual;": "\u2a7d\u0338", + "NotLessTilde;": "\u2274", + "NotNestedGreaterGreater;": "\u2aa2\u0338", + "NotNestedLessLess;": "\u2aa1\u0338", + "NotPrecedes;": "\u2280", + "NotPrecedesEqual;": "\u2aaf\u0338", + "NotPrecedesSlantEqual;": "\u22e0", + "NotReverseElement;": "\u220c", + "NotRightTriangle;": "\u22eb", + "NotRightTriangleBar;": "\u29d0\u0338", + "NotRightTriangleEqual;": "\u22ed", + "NotSquareSubset;": "\u228f\u0338", + "NotSquareSubsetEqual;": "\u22e2", + "NotSquareSuperset;": "\u2290\u0338", + "NotSquareSupersetEqual;": "\u22e3", + "NotSubset;": "\u2282\u20d2", + "NotSubsetEqual;": "\u2288", + "NotSucceeds;": "\u2281", + "NotSucceedsEqual;": "\u2ab0\u0338", + "NotSucceedsSlantEqual;": "\u22e1", + "NotSucceedsTilde;": "\u227f\u0338", + "NotSuperset;": "\u2283\u20d2", + "NotSupersetEqual;": "\u2289", + "NotTilde;": "\u2241", + "NotTildeEqual;": "\u2244", + "NotTildeFullEqual;": "\u2247", + "NotTildeTilde;": "\u2249", + "NotVerticalBar;": "\u2224", + "Nscr;": "\U0001d4a9", + "Ntilde": "\xd1", + "Ntilde;": "\xd1", + "Nu;": "\u039d", + "OElig;": "\u0152", + "Oacute": "\xd3", + "Oacute;": "\xd3", + "Ocirc": "\xd4", + "Ocirc;": "\xd4", + "Ocy;": "\u041e", + "Odblac;": "\u0150", + "Ofr;": "\U0001d512", + "Ograve": "\xd2", + "Ograve;": "\xd2", + "Omacr;": "\u014c", + "Omega;": "\u03a9", + "Omicron;": "\u039f", + "Oopf;": "\U0001d546", + "OpenCurlyDoubleQuote;": "\u201c", + "OpenCurlyQuote;": "\u2018", + "Or;": "\u2a54", + "Oscr;": "\U0001d4aa", + "Oslash": "\xd8", + "Oslash;": "\xd8", + "Otilde": "\xd5", + "Otilde;": "\xd5", + "Otimes;": "\u2a37", + "Ouml": "\xd6", + "Ouml;": "\xd6", + "OverBar;": "\u203e", + "OverBrace;": "\u23de", + "OverBracket;": "\u23b4", + "OverParenthesis;": "\u23dc", + "PartialD;": "\u2202", + "Pcy;": "\u041f", + "Pfr;": "\U0001d513", + "Phi;": "\u03a6", + "Pi;": "\u03a0", + "PlusMinus;": "\xb1", + "Poincareplane;": "\u210c", + "Popf;": "\u2119", + "Pr;": "\u2abb", + "Precedes;": "\u227a", + "PrecedesEqual;": "\u2aaf", + "PrecedesSlantEqual;": "\u227c", + "PrecedesTilde;": "\u227e", + "Prime;": "\u2033", + "Product;": "\u220f", + "Proportion;": "\u2237", + "Proportional;": "\u221d", + "Pscr;": "\U0001d4ab", + "Psi;": "\u03a8", + "QUOT": "\"", + "QUOT;": "\"", + "Qfr;": "\U0001d514", + "Qopf;": "\u211a", + "Qscr;": "\U0001d4ac", + "RBarr;": "\u2910", + "REG": "\xae", + "REG;": "\xae", + "Racute;": "\u0154", + "Rang;": "\u27eb", + "Rarr;": "\u21a0", + "Rarrtl;": "\u2916", + "Rcaron;": "\u0158", + "Rcedil;": "\u0156", + "Rcy;": "\u0420", + "Re;": "\u211c", + "ReverseElement;": "\u220b", + "ReverseEquilibrium;": "\u21cb", + "ReverseUpEquilibrium;": "\u296f", + "Rfr;": "\u211c", + "Rho;": "\u03a1", + "RightAngleBracket;": "\u27e9", + "RightArrow;": "\u2192", + "RightArrowBar;": "\u21e5", + "RightArrowLeftArrow;": "\u21c4", + "RightCeiling;": "\u2309", + "RightDoubleBracket;": "\u27e7", + "RightDownTeeVector;": "\u295d", + "RightDownVector;": "\u21c2", + "RightDownVectorBar;": "\u2955", + "RightFloor;": "\u230b", + "RightTee;": "\u22a2", + "RightTeeArrow;": "\u21a6", + "RightTeeVector;": "\u295b", + "RightTriangle;": "\u22b3", + "RightTriangleBar;": "\u29d0", + "RightTriangleEqual;": "\u22b5", + "RightUpDownVector;": "\u294f", + "RightUpTeeVector;": "\u295c", + "RightUpVector;": "\u21be", + "RightUpVectorBar;": "\u2954", + "RightVector;": "\u21c0", + "RightVectorBar;": "\u2953", + "Rightarrow;": "\u21d2", + "Ropf;": "\u211d", + "RoundImplies;": "\u2970", + "Rrightarrow;": "\u21db", + "Rscr;": "\u211b", + "Rsh;": "\u21b1", + "RuleDelayed;": "\u29f4", + "SHCHcy;": "\u0429", + "SHcy;": "\u0428", + "SOFTcy;": "\u042c", + "Sacute;": "\u015a", + "Sc;": "\u2abc", + "Scaron;": "\u0160", + "Scedil;": "\u015e", + "Scirc;": "\u015c", + "Scy;": "\u0421", + "Sfr;": "\U0001d516", + "ShortDownArrow;": "\u2193", + "ShortLeftArrow;": "\u2190", + "ShortRightArrow;": "\u2192", + "ShortUpArrow;": "\u2191", + "Sigma;": "\u03a3", + "SmallCircle;": "\u2218", + "Sopf;": "\U0001d54a", + "Sqrt;": "\u221a", + "Square;": "\u25a1", + "SquareIntersection;": "\u2293", + "SquareSubset;": "\u228f", + "SquareSubsetEqual;": "\u2291", + "SquareSuperset;": "\u2290", + "SquareSupersetEqual;": "\u2292", + "SquareUnion;": "\u2294", + "Sscr;": "\U0001d4ae", + "Star;": "\u22c6", + "Sub;": "\u22d0", + "Subset;": "\u22d0", + "SubsetEqual;": "\u2286", + "Succeeds;": "\u227b", + "SucceedsEqual;": "\u2ab0", + "SucceedsSlantEqual;": "\u227d", + "SucceedsTilde;": "\u227f", + "SuchThat;": "\u220b", + "Sum;": "\u2211", + "Sup;": "\u22d1", + "Superset;": "\u2283", + "SupersetEqual;": "\u2287", + "Supset;": "\u22d1", + "THORN": "\xde", + "THORN;": "\xde", + "TRADE;": "\u2122", + "TSHcy;": "\u040b", + "TScy;": "\u0426", + "Tab;": "\t", + "Tau;": "\u03a4", + "Tcaron;": "\u0164", + "Tcedil;": "\u0162", + "Tcy;": "\u0422", + "Tfr;": "\U0001d517", + "Therefore;": "\u2234", + "Theta;": "\u0398", + "ThickSpace;": "\u205f\u200a", + "ThinSpace;": "\u2009", + "Tilde;": "\u223c", + "TildeEqual;": "\u2243", + "TildeFullEqual;": "\u2245", + "TildeTilde;": "\u2248", + "Topf;": "\U0001d54b", + "TripleDot;": "\u20db", + "Tscr;": "\U0001d4af", + "Tstrok;": "\u0166", + "Uacute": "\xda", + "Uacute;": "\xda", + "Uarr;": "\u219f", + "Uarrocir;": "\u2949", + "Ubrcy;": "\u040e", + "Ubreve;": "\u016c", + "Ucirc": "\xdb", + "Ucirc;": "\xdb", + "Ucy;": "\u0423", + "Udblac;": "\u0170", + "Ufr;": "\U0001d518", + "Ugrave": "\xd9", + "Ugrave;": "\xd9", + "Umacr;": "\u016a", + "UnderBar;": "_", + "UnderBrace;": "\u23df", + "UnderBracket;": "\u23b5", + "UnderParenthesis;": "\u23dd", + "Union;": "\u22c3", + "UnionPlus;": "\u228e", + "Uogon;": "\u0172", + "Uopf;": "\U0001d54c", + "UpArrow;": "\u2191", + "UpArrowBar;": "\u2912", + "UpArrowDownArrow;": "\u21c5", + "UpDownArrow;": "\u2195", + "UpEquilibrium;": "\u296e", + "UpTee;": "\u22a5", + "UpTeeArrow;": "\u21a5", + "Uparrow;": "\u21d1", + "Updownarrow;": "\u21d5", + "UpperLeftArrow;": "\u2196", + "UpperRightArrow;": "\u2197", + "Upsi;": "\u03d2", + "Upsilon;": "\u03a5", + "Uring;": "\u016e", + "Uscr;": "\U0001d4b0", + "Utilde;": "\u0168", + "Uuml": "\xdc", + "Uuml;": "\xdc", + "VDash;": "\u22ab", + "Vbar;": "\u2aeb", + "Vcy;": "\u0412", + "Vdash;": "\u22a9", + "Vdashl;": "\u2ae6", + "Vee;": "\u22c1", + "Verbar;": "\u2016", + "Vert;": "\u2016", + "VerticalBar;": "\u2223", + "VerticalLine;": "|", + "VerticalSeparator;": "\u2758", + "VerticalTilde;": "\u2240", + "VeryThinSpace;": "\u200a", + "Vfr;": "\U0001d519", + "Vopf;": "\U0001d54d", + "Vscr;": "\U0001d4b1", + "Vvdash;": "\u22aa", + "Wcirc;": "\u0174", + "Wedge;": "\u22c0", + "Wfr;": "\U0001d51a", + "Wopf;": "\U0001d54e", + "Wscr;": "\U0001d4b2", + "Xfr;": "\U0001d51b", + "Xi;": "\u039e", + "Xopf;": "\U0001d54f", + "Xscr;": "\U0001d4b3", + "YAcy;": "\u042f", + "YIcy;": "\u0407", + "YUcy;": "\u042e", + "Yacute": "\xdd", + "Yacute;": "\xdd", + "Ycirc;": "\u0176", + "Ycy;": "\u042b", + "Yfr;": "\U0001d51c", + "Yopf;": "\U0001d550", + "Yscr;": "\U0001d4b4", + "Yuml;": "\u0178", + "ZHcy;": "\u0416", + "Zacute;": "\u0179", + "Zcaron;": "\u017d", + "Zcy;": "\u0417", + "Zdot;": "\u017b", + "ZeroWidthSpace;": "\u200b", + "Zeta;": "\u0396", + "Zfr;": "\u2128", + "Zopf;": "\u2124", + "Zscr;": "\U0001d4b5", + "aacute": "\xe1", + "aacute;": "\xe1", + "abreve;": "\u0103", + "ac;": "\u223e", + "acE;": "\u223e\u0333", + "acd;": "\u223f", + "acirc": "\xe2", + "acirc;": "\xe2", + "acute": "\xb4", + "acute;": "\xb4", + "acy;": "\u0430", + "aelig": "\xe6", + "aelig;": "\xe6", + "af;": "\u2061", + "afr;": "\U0001d51e", + "agrave": "\xe0", + "agrave;": "\xe0", + "alefsym;": "\u2135", + "aleph;": "\u2135", + "alpha;": "\u03b1", + "amacr;": "\u0101", + "amalg;": "\u2a3f", + "amp": "&", + "amp;": "&", + "and;": "\u2227", + "andand;": "\u2a55", + "andd;": "\u2a5c", + "andslope;": "\u2a58", + "andv;": "\u2a5a", + "ang;": "\u2220", + "ange;": "\u29a4", + "angle;": "\u2220", + "angmsd;": "\u2221", + "angmsdaa;": "\u29a8", + "angmsdab;": "\u29a9", + "angmsdac;": "\u29aa", + "angmsdad;": "\u29ab", + "angmsdae;": "\u29ac", + "angmsdaf;": "\u29ad", + "angmsdag;": "\u29ae", + "angmsdah;": "\u29af", + "angrt;": "\u221f", + "angrtvb;": "\u22be", + "angrtvbd;": "\u299d", + "angsph;": "\u2222", + "angst;": "\xc5", + "angzarr;": "\u237c", + "aogon;": "\u0105", + "aopf;": "\U0001d552", + "ap;": "\u2248", + "apE;": "\u2a70", + "apacir;": "\u2a6f", + "ape;": "\u224a", + "apid;": "\u224b", + "apos;": "'", + "approx;": "\u2248", + "approxeq;": "\u224a", + "aring": "\xe5", + "aring;": "\xe5", + "ascr;": "\U0001d4b6", + "ast;": "*", + "asymp;": "\u2248", + "asympeq;": "\u224d", + "atilde": "\xe3", + "atilde;": "\xe3", + "auml": "\xe4", + "auml;": "\xe4", + "awconint;": "\u2233", + "awint;": "\u2a11", + "bNot;": "\u2aed", + "backcong;": "\u224c", + "backepsilon;": "\u03f6", + "backprime;": "\u2035", + "backsim;": "\u223d", + "backsimeq;": "\u22cd", + "barvee;": "\u22bd", + "barwed;": "\u2305", + "barwedge;": "\u2305", + "bbrk;": "\u23b5", + "bbrktbrk;": "\u23b6", + "bcong;": "\u224c", + "bcy;": "\u0431", + "bdquo;": "\u201e", + "becaus;": "\u2235", + "because;": "\u2235", + "bemptyv;": "\u29b0", + "bepsi;": "\u03f6", + "bernou;": "\u212c", + "beta;": "\u03b2", + "beth;": "\u2136", + "between;": "\u226c", + "bfr;": "\U0001d51f", + "bigcap;": "\u22c2", + "bigcirc;": "\u25ef", + "bigcup;": "\u22c3", + "bigodot;": "\u2a00", + "bigoplus;": "\u2a01", + "bigotimes;": "\u2a02", + "bigsqcup;": "\u2a06", + "bigstar;": "\u2605", + "bigtriangledown;": "\u25bd", + "bigtriangleup;": "\u25b3", + "biguplus;": "\u2a04", + "bigvee;": "\u22c1", + "bigwedge;": "\u22c0", + "bkarow;": "\u290d", + "blacklozenge;": "\u29eb", + "blacksquare;": "\u25aa", + "blacktriangle;": "\u25b4", + "blacktriangledown;": "\u25be", + "blacktriangleleft;": "\u25c2", + "blacktriangleright;": "\u25b8", + "blank;": "\u2423", + "blk12;": "\u2592", + "blk14;": "\u2591", + "blk34;": "\u2593", + "block;": "\u2588", + "bne;": "=\u20e5", + "bnequiv;": "\u2261\u20e5", + "bnot;": "\u2310", + "bopf;": "\U0001d553", + "bot;": "\u22a5", + "bottom;": "\u22a5", + "bowtie;": "\u22c8", + "boxDL;": "\u2557", + "boxDR;": "\u2554", + "boxDl;": "\u2556", + "boxDr;": "\u2553", + "boxH;": "\u2550", + "boxHD;": "\u2566", + "boxHU;": "\u2569", + "boxHd;": "\u2564", + "boxHu;": "\u2567", + "boxUL;": "\u255d", + "boxUR;": "\u255a", + "boxUl;": "\u255c", + "boxUr;": "\u2559", + "boxV;": "\u2551", + "boxVH;": "\u256c", + "boxVL;": "\u2563", + "boxVR;": "\u2560", + "boxVh;": "\u256b", + "boxVl;": "\u2562", + "boxVr;": "\u255f", + "boxbox;": "\u29c9", + "boxdL;": "\u2555", + "boxdR;": "\u2552", + "boxdl;": "\u2510", + "boxdr;": "\u250c", + "boxh;": "\u2500", + "boxhD;": "\u2565", + "boxhU;": "\u2568", + "boxhd;": "\u252c", + "boxhu;": "\u2534", + "boxminus;": "\u229f", + "boxplus;": "\u229e", + "boxtimes;": "\u22a0", + "boxuL;": "\u255b", + "boxuR;": "\u2558", + "boxul;": "\u2518", + "boxur;": "\u2514", + "boxv;": "\u2502", + "boxvH;": "\u256a", + "boxvL;": "\u2561", + "boxvR;": "\u255e", + "boxvh;": "\u253c", + "boxvl;": "\u2524", + "boxvr;": "\u251c", + "bprime;": "\u2035", + "breve;": "\u02d8", + "brvbar": "\xa6", + "brvbar;": "\xa6", + "bscr;": "\U0001d4b7", + "bsemi;": "\u204f", + "bsim;": "\u223d", + "bsime;": "\u22cd", + "bsol;": "\\", + "bsolb;": "\u29c5", + "bsolhsub;": "\u27c8", + "bull;": "\u2022", + "bullet;": "\u2022", + "bump;": "\u224e", + "bumpE;": "\u2aae", + "bumpe;": "\u224f", + "bumpeq;": "\u224f", + "cacute;": "\u0107", + "cap;": "\u2229", + "capand;": "\u2a44", + "capbrcup;": "\u2a49", + "capcap;": "\u2a4b", + "capcup;": "\u2a47", + "capdot;": "\u2a40", + "caps;": "\u2229\ufe00", + "caret;": "\u2041", + "caron;": "\u02c7", + "ccaps;": "\u2a4d", + "ccaron;": "\u010d", + "ccedil": "\xe7", + "ccedil;": "\xe7", + "ccirc;": "\u0109", + "ccups;": "\u2a4c", + "ccupssm;": "\u2a50", + "cdot;": "\u010b", + "cedil": "\xb8", + "cedil;": "\xb8", + "cemptyv;": "\u29b2", + "cent": "\xa2", + "cent;": "\xa2", + "centerdot;": "\xb7", + "cfr;": "\U0001d520", + "chcy;": "\u0447", + "check;": "\u2713", + "checkmark;": "\u2713", + "chi;": "\u03c7", + "cir;": "\u25cb", + "cirE;": "\u29c3", + "circ;": "\u02c6", + "circeq;": "\u2257", + "circlearrowleft;": "\u21ba", + "circlearrowright;": "\u21bb", + "circledR;": "\xae", + "circledS;": "\u24c8", + "circledast;": "\u229b", + "circledcirc;": "\u229a", + "circleddash;": "\u229d", + "cire;": "\u2257", + "cirfnint;": "\u2a10", + "cirmid;": "\u2aef", + "cirscir;": "\u29c2", + "clubs;": "\u2663", + "clubsuit;": "\u2663", + "colon;": ":", + "colone;": "\u2254", + "coloneq;": "\u2254", + "comma;": ",", + "commat;": "@", + "comp;": "\u2201", + "compfn;": "\u2218", + "complement;": "\u2201", + "complexes;": "\u2102", + "cong;": "\u2245", + "congdot;": "\u2a6d", + "conint;": "\u222e", + "copf;": "\U0001d554", + "coprod;": "\u2210", + "copy": "\xa9", + "copy;": "\xa9", + "copysr;": "\u2117", + "crarr;": "\u21b5", + "cross;": "\u2717", + "cscr;": "\U0001d4b8", + "csub;": "\u2acf", + "csube;": "\u2ad1", + "csup;": "\u2ad0", + "csupe;": "\u2ad2", + "ctdot;": "\u22ef", + "cudarrl;": "\u2938", + "cudarrr;": "\u2935", + "cuepr;": "\u22de", + "cuesc;": "\u22df", + "cularr;": "\u21b6", + "cularrp;": "\u293d", + "cup;": "\u222a", + "cupbrcap;": "\u2a48", + "cupcap;": "\u2a46", + "cupcup;": "\u2a4a", + "cupdot;": "\u228d", + "cupor;": "\u2a45", + "cups;": "\u222a\ufe00", + "curarr;": "\u21b7", + "curarrm;": "\u293c", + "curlyeqprec;": "\u22de", + "curlyeqsucc;": "\u22df", + "curlyvee;": "\u22ce", + "curlywedge;": "\u22cf", + "curren": "\xa4", + "curren;": "\xa4", + "curvearrowleft;": "\u21b6", + "curvearrowright;": "\u21b7", + "cuvee;": "\u22ce", + "cuwed;": "\u22cf", + "cwconint;": "\u2232", + "cwint;": "\u2231", + "cylcty;": "\u232d", + "dArr;": "\u21d3", + "dHar;": "\u2965", + "dagger;": "\u2020", + "daleth;": "\u2138", + "darr;": "\u2193", + "dash;": "\u2010", + "dashv;": "\u22a3", + "dbkarow;": "\u290f", + "dblac;": "\u02dd", + "dcaron;": "\u010f", + "dcy;": "\u0434", + "dd;": "\u2146", + "ddagger;": "\u2021", + "ddarr;": "\u21ca", + "ddotseq;": "\u2a77", + "deg": "\xb0", + "deg;": "\xb0", + "delta;": "\u03b4", + "demptyv;": "\u29b1", + "dfisht;": "\u297f", + "dfr;": "\U0001d521", + "dharl;": "\u21c3", + "dharr;": "\u21c2", + "diam;": "\u22c4", + "diamond;": "\u22c4", + "diamondsuit;": "\u2666", + "diams;": "\u2666", + "die;": "\xa8", + "digamma;": "\u03dd", + "disin;": "\u22f2", + "div;": "\xf7", + "divide": "\xf7", + "divide;": "\xf7", + "divideontimes;": "\u22c7", + "divonx;": "\u22c7", + "djcy;": "\u0452", + "dlcorn;": "\u231e", + "dlcrop;": "\u230d", + "dollar;": "$", + "dopf;": "\U0001d555", + "dot;": "\u02d9", + "doteq;": "\u2250", + "doteqdot;": "\u2251", + "dotminus;": "\u2238", + "dotplus;": "\u2214", + "dotsquare;": "\u22a1", + "doublebarwedge;": "\u2306", + "downarrow;": "\u2193", + "downdownarrows;": "\u21ca", + "downharpoonleft;": "\u21c3", + "downharpoonright;": "\u21c2", + "drbkarow;": "\u2910", + "drcorn;": "\u231f", + "drcrop;": "\u230c", + "dscr;": "\U0001d4b9", + "dscy;": "\u0455", + "dsol;": "\u29f6", + "dstrok;": "\u0111", + "dtdot;": "\u22f1", + "dtri;": "\u25bf", + "dtrif;": "\u25be", + "duarr;": "\u21f5", + "duhar;": "\u296f", + "dwangle;": "\u29a6", + "dzcy;": "\u045f", + "dzigrarr;": "\u27ff", + "eDDot;": "\u2a77", + "eDot;": "\u2251", + "eacute": "\xe9", + "eacute;": "\xe9", + "easter;": "\u2a6e", + "ecaron;": "\u011b", + "ecir;": "\u2256", + "ecirc": "\xea", + "ecirc;": "\xea", + "ecolon;": "\u2255", + "ecy;": "\u044d", + "edot;": "\u0117", + "ee;": "\u2147", + "efDot;": "\u2252", + "efr;": "\U0001d522", + "eg;": "\u2a9a", + "egrave": "\xe8", + "egrave;": "\xe8", + "egs;": "\u2a96", + "egsdot;": "\u2a98", + "el;": "\u2a99", + "elinters;": "\u23e7", + "ell;": "\u2113", + "els;": "\u2a95", + "elsdot;": "\u2a97", + "emacr;": "\u0113", + "empty;": "\u2205", + "emptyset;": "\u2205", + "emptyv;": "\u2205", + "emsp13;": "\u2004", + "emsp14;": "\u2005", + "emsp;": "\u2003", + "eng;": "\u014b", + "ensp;": "\u2002", + "eogon;": "\u0119", + "eopf;": "\U0001d556", + "epar;": "\u22d5", + "eparsl;": "\u29e3", + "eplus;": "\u2a71", + "epsi;": "\u03b5", + "epsilon;": "\u03b5", + "epsiv;": "\u03f5", + "eqcirc;": "\u2256", + "eqcolon;": "\u2255", + "eqsim;": "\u2242", + "eqslantgtr;": "\u2a96", + "eqslantless;": "\u2a95", + "equals;": "=", + "equest;": "\u225f", + "equiv;": "\u2261", + "equivDD;": "\u2a78", + "eqvparsl;": "\u29e5", + "erDot;": "\u2253", + "erarr;": "\u2971", + "escr;": "\u212f", + "esdot;": "\u2250", + "esim;": "\u2242", + "eta;": "\u03b7", + "eth": "\xf0", + "eth;": "\xf0", + "euml": "\xeb", + "euml;": "\xeb", + "euro;": "\u20ac", + "excl;": "!", + "exist;": "\u2203", + "expectation;": "\u2130", + "exponentiale;": "\u2147", + "fallingdotseq;": "\u2252", + "fcy;": "\u0444", + "female;": "\u2640", + "ffilig;": "\ufb03", + "fflig;": "\ufb00", + "ffllig;": "\ufb04", + "ffr;": "\U0001d523", + "filig;": "\ufb01", + "fjlig;": "fj", + "flat;": "\u266d", + "fllig;": "\ufb02", + "fltns;": "\u25b1", + "fnof;": "\u0192", + "fopf;": "\U0001d557", + "forall;": "\u2200", + "fork;": "\u22d4", + "forkv;": "\u2ad9", + "fpartint;": "\u2a0d", + "frac12": "\xbd", + "frac12;": "\xbd", + "frac13;": "\u2153", + "frac14": "\xbc", + "frac14;": "\xbc", + "frac15;": "\u2155", + "frac16;": "\u2159", + "frac18;": "\u215b", + "frac23;": "\u2154", + "frac25;": "\u2156", + "frac34": "\xbe", + "frac34;": "\xbe", + "frac35;": "\u2157", + "frac38;": "\u215c", + "frac45;": "\u2158", + "frac56;": "\u215a", + "frac58;": "\u215d", + "frac78;": "\u215e", + "frasl;": "\u2044", + "frown;": "\u2322", + "fscr;": "\U0001d4bb", + "gE;": "\u2267", + "gEl;": "\u2a8c", + "gacute;": "\u01f5", + "gamma;": "\u03b3", + "gammad;": "\u03dd", + "gap;": "\u2a86", + "gbreve;": "\u011f", + "gcirc;": "\u011d", + "gcy;": "\u0433", + "gdot;": "\u0121", + "ge;": "\u2265", + "gel;": "\u22db", + "geq;": "\u2265", + "geqq;": "\u2267", + "geqslant;": "\u2a7e", + "ges;": "\u2a7e", + "gescc;": "\u2aa9", + "gesdot;": "\u2a80", + "gesdoto;": "\u2a82", + "gesdotol;": "\u2a84", + "gesl;": "\u22db\ufe00", + "gesles;": "\u2a94", + "gfr;": "\U0001d524", + "gg;": "\u226b", + "ggg;": "\u22d9", + "gimel;": "\u2137", + "gjcy;": "\u0453", + "gl;": "\u2277", + "glE;": "\u2a92", + "gla;": "\u2aa5", + "glj;": "\u2aa4", + "gnE;": "\u2269", + "gnap;": "\u2a8a", + "gnapprox;": "\u2a8a", + "gne;": "\u2a88", + "gneq;": "\u2a88", + "gneqq;": "\u2269", + "gnsim;": "\u22e7", + "gopf;": "\U0001d558", + "grave;": "`", + "gscr;": "\u210a", + "gsim;": "\u2273", + "gsime;": "\u2a8e", + "gsiml;": "\u2a90", + "gt": ">", + "gt;": ">", + "gtcc;": "\u2aa7", + "gtcir;": "\u2a7a", + "gtdot;": "\u22d7", + "gtlPar;": "\u2995", + "gtquest;": "\u2a7c", + "gtrapprox;": "\u2a86", + "gtrarr;": "\u2978", + "gtrdot;": "\u22d7", + "gtreqless;": "\u22db", + "gtreqqless;": "\u2a8c", + "gtrless;": "\u2277", + "gtrsim;": "\u2273", + "gvertneqq;": "\u2269\ufe00", + "gvnE;": "\u2269\ufe00", + "hArr;": "\u21d4", + "hairsp;": "\u200a", + "half;": "\xbd", + "hamilt;": "\u210b", + "hardcy;": "\u044a", + "harr;": "\u2194", + "harrcir;": "\u2948", + "harrw;": "\u21ad", + "hbar;": "\u210f", + "hcirc;": "\u0125", + "hearts;": "\u2665", + "heartsuit;": "\u2665", + "hellip;": "\u2026", + "hercon;": "\u22b9", + "hfr;": "\U0001d525", + "hksearow;": "\u2925", + "hkswarow;": "\u2926", + "hoarr;": "\u21ff", + "homtht;": "\u223b", + "hookleftarrow;": "\u21a9", + "hookrightarrow;": "\u21aa", + "hopf;": "\U0001d559", + "horbar;": "\u2015", + "hscr;": "\U0001d4bd", + "hslash;": "\u210f", + "hstrok;": "\u0127", + "hybull;": "\u2043", + "hyphen;": "\u2010", + "iacute": "\xed", + "iacute;": "\xed", + "ic;": "\u2063", + "icirc": "\xee", + "icirc;": "\xee", + "icy;": "\u0438", + "iecy;": "\u0435", + "iexcl": "\xa1", + "iexcl;": "\xa1", + "iff;": "\u21d4", + "ifr;": "\U0001d526", + "igrave": "\xec", + "igrave;": "\xec", + "ii;": "\u2148", + "iiiint;": "\u2a0c", + "iiint;": "\u222d", + "iinfin;": "\u29dc", + "iiota;": "\u2129", + "ijlig;": "\u0133", + "imacr;": "\u012b", + "image;": "\u2111", + "imagline;": "\u2110", + "imagpart;": "\u2111", + "imath;": "\u0131", + "imof;": "\u22b7", + "imped;": "\u01b5", + "in;": "\u2208", + "incare;": "\u2105", + "infin;": "\u221e", + "infintie;": "\u29dd", + "inodot;": "\u0131", + "int;": "\u222b", + "intcal;": "\u22ba", + "integers;": "\u2124", + "intercal;": "\u22ba", + "intlarhk;": "\u2a17", + "intprod;": "\u2a3c", + "iocy;": "\u0451", + "iogon;": "\u012f", + "iopf;": "\U0001d55a", + "iota;": "\u03b9", + "iprod;": "\u2a3c", + "iquest": "\xbf", + "iquest;": "\xbf", + "iscr;": "\U0001d4be", + "isin;": "\u2208", + "isinE;": "\u22f9", + "isindot;": "\u22f5", + "isins;": "\u22f4", + "isinsv;": "\u22f3", + "isinv;": "\u2208", + "it;": "\u2062", + "itilde;": "\u0129", + "iukcy;": "\u0456", + "iuml": "\xef", + "iuml;": "\xef", + "jcirc;": "\u0135", + "jcy;": "\u0439", + "jfr;": "\U0001d527", + "jmath;": "\u0237", + "jopf;": "\U0001d55b", + "jscr;": "\U0001d4bf", + "jsercy;": "\u0458", + "jukcy;": "\u0454", + "kappa;": "\u03ba", + "kappav;": "\u03f0", + "kcedil;": "\u0137", + "kcy;": "\u043a", + "kfr;": "\U0001d528", + "kgreen;": "\u0138", + "khcy;": "\u0445", + "kjcy;": "\u045c", + "kopf;": "\U0001d55c", + "kscr;": "\U0001d4c0", + "lAarr;": "\u21da", + "lArr;": "\u21d0", + "lAtail;": "\u291b", + "lBarr;": "\u290e", + "lE;": "\u2266", + "lEg;": "\u2a8b", + "lHar;": "\u2962", + "lacute;": "\u013a", + "laemptyv;": "\u29b4", + "lagran;": "\u2112", + "lambda;": "\u03bb", + "lang;": "\u27e8", + "langd;": "\u2991", + "langle;": "\u27e8", + "lap;": "\u2a85", + "laquo": "\xab", + "laquo;": "\xab", + "larr;": "\u2190", + "larrb;": "\u21e4", + "larrbfs;": "\u291f", + "larrfs;": "\u291d", + "larrhk;": "\u21a9", + "larrlp;": "\u21ab", + "larrpl;": "\u2939", + "larrsim;": "\u2973", + "larrtl;": "\u21a2", + "lat;": "\u2aab", + "latail;": "\u2919", + "late;": "\u2aad", + "lates;": "\u2aad\ufe00", + "lbarr;": "\u290c", + "lbbrk;": "\u2772", + "lbrace;": "{", + "lbrack;": "[", + "lbrke;": "\u298b", + "lbrksld;": "\u298f", + "lbrkslu;": "\u298d", + "lcaron;": "\u013e", + "lcedil;": "\u013c", + "lceil;": "\u2308", + "lcub;": "{", + "lcy;": "\u043b", + "ldca;": "\u2936", + "ldquo;": "\u201c", + "ldquor;": "\u201e", + "ldrdhar;": "\u2967", + "ldrushar;": "\u294b", + "ldsh;": "\u21b2", + "le;": "\u2264", + "leftarrow;": "\u2190", + "leftarrowtail;": "\u21a2", + "leftharpoondown;": "\u21bd", + "leftharpoonup;": "\u21bc", + "leftleftarrows;": "\u21c7", + "leftrightarrow;": "\u2194", + "leftrightarrows;": "\u21c6", + "leftrightharpoons;": "\u21cb", + "leftrightsquigarrow;": "\u21ad", + "leftthreetimes;": "\u22cb", + "leg;": "\u22da", + "leq;": "\u2264", + "leqq;": "\u2266", + "leqslant;": "\u2a7d", + "les;": "\u2a7d", + "lescc;": "\u2aa8", + "lesdot;": "\u2a7f", + "lesdoto;": "\u2a81", + "lesdotor;": "\u2a83", + "lesg;": "\u22da\ufe00", + "lesges;": "\u2a93", + "lessapprox;": "\u2a85", + "lessdot;": "\u22d6", + "lesseqgtr;": "\u22da", + "lesseqqgtr;": "\u2a8b", + "lessgtr;": "\u2276", + "lesssim;": "\u2272", + "lfisht;": "\u297c", + "lfloor;": "\u230a", + "lfr;": "\U0001d529", + "lg;": "\u2276", + "lgE;": "\u2a91", + "lhard;": "\u21bd", + "lharu;": "\u21bc", + "lharul;": "\u296a", + "lhblk;": "\u2584", + "ljcy;": "\u0459", + "ll;": "\u226a", + "llarr;": "\u21c7", + "llcorner;": "\u231e", + "llhard;": "\u296b", + "lltri;": "\u25fa", + "lmidot;": "\u0140", + "lmoust;": "\u23b0", + "lmoustache;": "\u23b0", + "lnE;": "\u2268", + "lnap;": "\u2a89", + "lnapprox;": "\u2a89", + "lne;": "\u2a87", + "lneq;": "\u2a87", + "lneqq;": "\u2268", + "lnsim;": "\u22e6", + "loang;": "\u27ec", + "loarr;": "\u21fd", + "lobrk;": "\u27e6", + "longleftarrow;": "\u27f5", + "longleftrightarrow;": "\u27f7", + "longmapsto;": "\u27fc", + "longrightarrow;": "\u27f6", + "looparrowleft;": "\u21ab", + "looparrowright;": "\u21ac", + "lopar;": "\u2985", + "lopf;": "\U0001d55d", + "loplus;": "\u2a2d", + "lotimes;": "\u2a34", + "lowast;": "\u2217", + "lowbar;": "_", + "loz;": "\u25ca", + "lozenge;": "\u25ca", + "lozf;": "\u29eb", + "lpar;": "(", + "lparlt;": "\u2993", + "lrarr;": "\u21c6", + "lrcorner;": "\u231f", + "lrhar;": "\u21cb", + "lrhard;": "\u296d", + "lrm;": "\u200e", + "lrtri;": "\u22bf", + "lsaquo;": "\u2039", + "lscr;": "\U0001d4c1", + "lsh;": "\u21b0", + "lsim;": "\u2272", + "lsime;": "\u2a8d", + "lsimg;": "\u2a8f", + "lsqb;": "[", + "lsquo;": "\u2018", + "lsquor;": "\u201a", + "lstrok;": "\u0142", + "lt": "<", + "lt;": "<", + "ltcc;": "\u2aa6", + "ltcir;": "\u2a79", + "ltdot;": "\u22d6", + "lthree;": "\u22cb", + "ltimes;": "\u22c9", + "ltlarr;": "\u2976", + "ltquest;": "\u2a7b", + "ltrPar;": "\u2996", + "ltri;": "\u25c3", + "ltrie;": "\u22b4", + "ltrif;": "\u25c2", + "lurdshar;": "\u294a", + "luruhar;": "\u2966", + "lvertneqq;": "\u2268\ufe00", + "lvnE;": "\u2268\ufe00", + "mDDot;": "\u223a", + "macr": "\xaf", + "macr;": "\xaf", + "male;": "\u2642", + "malt;": "\u2720", + "maltese;": "\u2720", + "map;": "\u21a6", + "mapsto;": "\u21a6", + "mapstodown;": "\u21a7", + "mapstoleft;": "\u21a4", + "mapstoup;": "\u21a5", + "marker;": "\u25ae", + "mcomma;": "\u2a29", + "mcy;": "\u043c", + "mdash;": "\u2014", + "measuredangle;": "\u2221", + "mfr;": "\U0001d52a", + "mho;": "\u2127", + "micro": "\xb5", + "micro;": "\xb5", + "mid;": "\u2223", + "midast;": "*", + "midcir;": "\u2af0", + "middot": "\xb7", + "middot;": "\xb7", + "minus;": "\u2212", + "minusb;": "\u229f", + "minusd;": "\u2238", + "minusdu;": "\u2a2a", + "mlcp;": "\u2adb", + "mldr;": "\u2026", + "mnplus;": "\u2213", + "models;": "\u22a7", + "mopf;": "\U0001d55e", + "mp;": "\u2213", + "mscr;": "\U0001d4c2", + "mstpos;": "\u223e", + "mu;": "\u03bc", + "multimap;": "\u22b8", + "mumap;": "\u22b8", + "nGg;": "\u22d9\u0338", + "nGt;": "\u226b\u20d2", + "nGtv;": "\u226b\u0338", + "nLeftarrow;": "\u21cd", + "nLeftrightarrow;": "\u21ce", + "nLl;": "\u22d8\u0338", + "nLt;": "\u226a\u20d2", + "nLtv;": "\u226a\u0338", + "nRightarrow;": "\u21cf", + "nVDash;": "\u22af", + "nVdash;": "\u22ae", + "nabla;": "\u2207", + "nacute;": "\u0144", + "nang;": "\u2220\u20d2", + "nap;": "\u2249", + "napE;": "\u2a70\u0338", + "napid;": "\u224b\u0338", + "napos;": "\u0149", + "napprox;": "\u2249", + "natur;": "\u266e", + "natural;": "\u266e", + "naturals;": "\u2115", + "nbsp": "\xa0", + "nbsp;": "\xa0", + "nbump;": "\u224e\u0338", + "nbumpe;": "\u224f\u0338", + "ncap;": "\u2a43", + "ncaron;": "\u0148", + "ncedil;": "\u0146", + "ncong;": "\u2247", + "ncongdot;": "\u2a6d\u0338", + "ncup;": "\u2a42", + "ncy;": "\u043d", + "ndash;": "\u2013", + "ne;": "\u2260", + "neArr;": "\u21d7", + "nearhk;": "\u2924", + "nearr;": "\u2197", + "nearrow;": "\u2197", + "nedot;": "\u2250\u0338", + "nequiv;": "\u2262", + "nesear;": "\u2928", + "nesim;": "\u2242\u0338", + "nexist;": "\u2204", + "nexists;": "\u2204", + "nfr;": "\U0001d52b", + "ngE;": "\u2267\u0338", + "nge;": "\u2271", + "ngeq;": "\u2271", + "ngeqq;": "\u2267\u0338", + "ngeqslant;": "\u2a7e\u0338", + "nges;": "\u2a7e\u0338", + "ngsim;": "\u2275", + "ngt;": "\u226f", + "ngtr;": "\u226f", + "nhArr;": "\u21ce", + "nharr;": "\u21ae", + "nhpar;": "\u2af2", + "ni;": "\u220b", + "nis;": "\u22fc", + "nisd;": "\u22fa", + "niv;": "\u220b", + "njcy;": "\u045a", + "nlArr;": "\u21cd", + "nlE;": "\u2266\u0338", + "nlarr;": "\u219a", + "nldr;": "\u2025", + "nle;": "\u2270", + "nleftarrow;": "\u219a", + "nleftrightarrow;": "\u21ae", + "nleq;": "\u2270", + "nleqq;": "\u2266\u0338", + "nleqslant;": "\u2a7d\u0338", + "nles;": "\u2a7d\u0338", + "nless;": "\u226e", + "nlsim;": "\u2274", + "nlt;": "\u226e", + "nltri;": "\u22ea", + "nltrie;": "\u22ec", + "nmid;": "\u2224", + "nopf;": "\U0001d55f", + "not": "\xac", + "not;": "\xac", + "notin;": "\u2209", + "notinE;": "\u22f9\u0338", + "notindot;": "\u22f5\u0338", + "notinva;": "\u2209", + "notinvb;": "\u22f7", + "notinvc;": "\u22f6", + "notni;": "\u220c", + "notniva;": "\u220c", + "notnivb;": "\u22fe", + "notnivc;": "\u22fd", + "npar;": "\u2226", + "nparallel;": "\u2226", + "nparsl;": "\u2afd\u20e5", + "npart;": "\u2202\u0338", + "npolint;": "\u2a14", + "npr;": "\u2280", + "nprcue;": "\u22e0", + "npre;": "\u2aaf\u0338", + "nprec;": "\u2280", + "npreceq;": "\u2aaf\u0338", + "nrArr;": "\u21cf", + "nrarr;": "\u219b", + "nrarrc;": "\u2933\u0338", + "nrarrw;": "\u219d\u0338", + "nrightarrow;": "\u219b", + "nrtri;": "\u22eb", + "nrtrie;": "\u22ed", + "nsc;": "\u2281", + "nsccue;": "\u22e1", + "nsce;": "\u2ab0\u0338", + "nscr;": "\U0001d4c3", + "nshortmid;": "\u2224", + "nshortparallel;": "\u2226", + "nsim;": "\u2241", + "nsime;": "\u2244", + "nsimeq;": "\u2244", + "nsmid;": "\u2224", + "nspar;": "\u2226", + "nsqsube;": "\u22e2", + "nsqsupe;": "\u22e3", + "nsub;": "\u2284", + "nsubE;": "\u2ac5\u0338", + "nsube;": "\u2288", + "nsubset;": "\u2282\u20d2", + "nsubseteq;": "\u2288", + "nsubseteqq;": "\u2ac5\u0338", + "nsucc;": "\u2281", + "nsucceq;": "\u2ab0\u0338", + "nsup;": "\u2285", + "nsupE;": "\u2ac6\u0338", + "nsupe;": "\u2289", + "nsupset;": "\u2283\u20d2", + "nsupseteq;": "\u2289", + "nsupseteqq;": "\u2ac6\u0338", + "ntgl;": "\u2279", + "ntilde": "\xf1", + "ntilde;": "\xf1", + "ntlg;": "\u2278", + "ntriangleleft;": "\u22ea", + "ntrianglelefteq;": "\u22ec", + "ntriangleright;": "\u22eb", + "ntrianglerighteq;": "\u22ed", + "nu;": "\u03bd", + "num;": "#", + "numero;": "\u2116", + "numsp;": "\u2007", + "nvDash;": "\u22ad", + "nvHarr;": "\u2904", + "nvap;": "\u224d\u20d2", + "nvdash;": "\u22ac", + "nvge;": "\u2265\u20d2", + "nvgt;": ">\u20d2", + "nvinfin;": "\u29de", + "nvlArr;": "\u2902", + "nvle;": "\u2264\u20d2", + "nvlt;": "<\u20d2", + "nvltrie;": "\u22b4\u20d2", + "nvrArr;": "\u2903", + "nvrtrie;": "\u22b5\u20d2", + "nvsim;": "\u223c\u20d2", + "nwArr;": "\u21d6", + "nwarhk;": "\u2923", + "nwarr;": "\u2196", + "nwarrow;": "\u2196", + "nwnear;": "\u2927", + "oS;": "\u24c8", + "oacute": "\xf3", + "oacute;": "\xf3", + "oast;": "\u229b", + "ocir;": "\u229a", + "ocirc": "\xf4", + "ocirc;": "\xf4", + "ocy;": "\u043e", + "odash;": "\u229d", + "odblac;": "\u0151", + "odiv;": "\u2a38", + "odot;": "\u2299", + "odsold;": "\u29bc", + "oelig;": "\u0153", + "ofcir;": "\u29bf", + "ofr;": "\U0001d52c", + "ogon;": "\u02db", + "ograve": "\xf2", + "ograve;": "\xf2", + "ogt;": "\u29c1", + "ohbar;": "\u29b5", + "ohm;": "\u03a9", + "oint;": "\u222e", + "olarr;": "\u21ba", + "olcir;": "\u29be", + "olcross;": "\u29bb", + "oline;": "\u203e", + "olt;": "\u29c0", + "omacr;": "\u014d", + "omega;": "\u03c9", + "omicron;": "\u03bf", + "omid;": "\u29b6", + "ominus;": "\u2296", + "oopf;": "\U0001d560", + "opar;": "\u29b7", + "operp;": "\u29b9", + "oplus;": "\u2295", + "or;": "\u2228", + "orarr;": "\u21bb", + "ord;": "\u2a5d", + "order;": "\u2134", + "orderof;": "\u2134", + "ordf": "\xaa", + "ordf;": "\xaa", + "ordm": "\xba", + "ordm;": "\xba", + "origof;": "\u22b6", + "oror;": "\u2a56", + "orslope;": "\u2a57", + "orv;": "\u2a5b", + "oscr;": "\u2134", + "oslash": "\xf8", + "oslash;": "\xf8", + "osol;": "\u2298", + "otilde": "\xf5", + "otilde;": "\xf5", + "otimes;": "\u2297", + "otimesas;": "\u2a36", + "ouml": "\xf6", + "ouml;": "\xf6", + "ovbar;": "\u233d", + "par;": "\u2225", + "para": "\xb6", + "para;": "\xb6", + "parallel;": "\u2225", + "parsim;": "\u2af3", + "parsl;": "\u2afd", + "part;": "\u2202", + "pcy;": "\u043f", + "percnt;": "%", + "period;": ".", + "permil;": "\u2030", + "perp;": "\u22a5", + "pertenk;": "\u2031", + "pfr;": "\U0001d52d", + "phi;": "\u03c6", + "phiv;": "\u03d5", + "phmmat;": "\u2133", + "phone;": "\u260e", + "pi;": "\u03c0", + "pitchfork;": "\u22d4", + "piv;": "\u03d6", + "planck;": "\u210f", + "planckh;": "\u210e", + "plankv;": "\u210f", + "plus;": "+", + "plusacir;": "\u2a23", + "plusb;": "\u229e", + "pluscir;": "\u2a22", + "plusdo;": "\u2214", + "plusdu;": "\u2a25", + "pluse;": "\u2a72", + "plusmn": "\xb1", + "plusmn;": "\xb1", + "plussim;": "\u2a26", + "plustwo;": "\u2a27", + "pm;": "\xb1", + "pointint;": "\u2a15", + "popf;": "\U0001d561", + "pound": "\xa3", + "pound;": "\xa3", + "pr;": "\u227a", + "prE;": "\u2ab3", + "prap;": "\u2ab7", + "prcue;": "\u227c", + "pre;": "\u2aaf", + "prec;": "\u227a", + "precapprox;": "\u2ab7", + "preccurlyeq;": "\u227c", + "preceq;": "\u2aaf", + "precnapprox;": "\u2ab9", + "precneqq;": "\u2ab5", + "precnsim;": "\u22e8", + "precsim;": "\u227e", + "prime;": "\u2032", + "primes;": "\u2119", + "prnE;": "\u2ab5", + "prnap;": "\u2ab9", + "prnsim;": "\u22e8", + "prod;": "\u220f", + "profalar;": "\u232e", + "profline;": "\u2312", + "profsurf;": "\u2313", + "prop;": "\u221d", + "propto;": "\u221d", + "prsim;": "\u227e", + "prurel;": "\u22b0", + "pscr;": "\U0001d4c5", + "psi;": "\u03c8", + "puncsp;": "\u2008", + "qfr;": "\U0001d52e", + "qint;": "\u2a0c", + "qopf;": "\U0001d562", + "qprime;": "\u2057", + "qscr;": "\U0001d4c6", + "quaternions;": "\u210d", + "quatint;": "\u2a16", + "quest;": "?", + "questeq;": "\u225f", + "quot": "\"", + "quot;": "\"", + "rAarr;": "\u21db", + "rArr;": "\u21d2", + "rAtail;": "\u291c", + "rBarr;": "\u290f", + "rHar;": "\u2964", + "race;": "\u223d\u0331", + "racute;": "\u0155", + "radic;": "\u221a", + "raemptyv;": "\u29b3", + "rang;": "\u27e9", + "rangd;": "\u2992", + "range;": "\u29a5", + "rangle;": "\u27e9", + "raquo": "\xbb", + "raquo;": "\xbb", + "rarr;": "\u2192", + "rarrap;": "\u2975", + "rarrb;": "\u21e5", + "rarrbfs;": "\u2920", + "rarrc;": "\u2933", + "rarrfs;": "\u291e", + "rarrhk;": "\u21aa", + "rarrlp;": "\u21ac", + "rarrpl;": "\u2945", + "rarrsim;": "\u2974", + "rarrtl;": "\u21a3", + "rarrw;": "\u219d", + "ratail;": "\u291a", + "ratio;": "\u2236", + "rationals;": "\u211a", + "rbarr;": "\u290d", + "rbbrk;": "\u2773", + "rbrace;": "}", + "rbrack;": "]", + "rbrke;": "\u298c", + "rbrksld;": "\u298e", + "rbrkslu;": "\u2990", + "rcaron;": "\u0159", + "rcedil;": "\u0157", + "rceil;": "\u2309", + "rcub;": "}", + "rcy;": "\u0440", + "rdca;": "\u2937", + "rdldhar;": "\u2969", + "rdquo;": "\u201d", + "rdquor;": "\u201d", + "rdsh;": "\u21b3", + "real;": "\u211c", + "realine;": "\u211b", + "realpart;": "\u211c", + "reals;": "\u211d", + "rect;": "\u25ad", + "reg": "\xae", + "reg;": "\xae", + "rfisht;": "\u297d", + "rfloor;": "\u230b", + "rfr;": "\U0001d52f", + "rhard;": "\u21c1", + "rharu;": "\u21c0", + "rharul;": "\u296c", + "rho;": "\u03c1", + "rhov;": "\u03f1", + "rightarrow;": "\u2192", + "rightarrowtail;": "\u21a3", + "rightharpoondown;": "\u21c1", + "rightharpoonup;": "\u21c0", + "rightleftarrows;": "\u21c4", + "rightleftharpoons;": "\u21cc", + "rightrightarrows;": "\u21c9", + "rightsquigarrow;": "\u219d", + "rightthreetimes;": "\u22cc", + "ring;": "\u02da", + "risingdotseq;": "\u2253", + "rlarr;": "\u21c4", + "rlhar;": "\u21cc", + "rlm;": "\u200f", + "rmoust;": "\u23b1", + "rmoustache;": "\u23b1", + "rnmid;": "\u2aee", + "roang;": "\u27ed", + "roarr;": "\u21fe", + "robrk;": "\u27e7", + "ropar;": "\u2986", + "ropf;": "\U0001d563", + "roplus;": "\u2a2e", + "rotimes;": "\u2a35", + "rpar;": ")", + "rpargt;": "\u2994", + "rppolint;": "\u2a12", + "rrarr;": "\u21c9", + "rsaquo;": "\u203a", + "rscr;": "\U0001d4c7", + "rsh;": "\u21b1", + "rsqb;": "]", + "rsquo;": "\u2019", + "rsquor;": "\u2019", + "rthree;": "\u22cc", + "rtimes;": "\u22ca", + "rtri;": "\u25b9", + "rtrie;": "\u22b5", + "rtrif;": "\u25b8", + "rtriltri;": "\u29ce", + "ruluhar;": "\u2968", + "rx;": "\u211e", + "sacute;": "\u015b", + "sbquo;": "\u201a", + "sc;": "\u227b", + "scE;": "\u2ab4", + "scap;": "\u2ab8", + "scaron;": "\u0161", + "sccue;": "\u227d", + "sce;": "\u2ab0", + "scedil;": "\u015f", + "scirc;": "\u015d", + "scnE;": "\u2ab6", + "scnap;": "\u2aba", + "scnsim;": "\u22e9", + "scpolint;": "\u2a13", + "scsim;": "\u227f", + "scy;": "\u0441", + "sdot;": "\u22c5", + "sdotb;": "\u22a1", + "sdote;": "\u2a66", + "seArr;": "\u21d8", + "searhk;": "\u2925", + "searr;": "\u2198", + "searrow;": "\u2198", + "sect": "\xa7", + "sect;": "\xa7", + "semi;": ";", + "seswar;": "\u2929", + "setminus;": "\u2216", + "setmn;": "\u2216", + "sext;": "\u2736", + "sfr;": "\U0001d530", + "sfrown;": "\u2322", + "sharp;": "\u266f", + "shchcy;": "\u0449", + "shcy;": "\u0448", + "shortmid;": "\u2223", + "shortparallel;": "\u2225", + "shy": "\xad", + "shy;": "\xad", + "sigma;": "\u03c3", + "sigmaf;": "\u03c2", + "sigmav;": "\u03c2", + "sim;": "\u223c", + "simdot;": "\u2a6a", + "sime;": "\u2243", + "simeq;": "\u2243", + "simg;": "\u2a9e", + "simgE;": "\u2aa0", + "siml;": "\u2a9d", + "simlE;": "\u2a9f", + "simne;": "\u2246", + "simplus;": "\u2a24", + "simrarr;": "\u2972", + "slarr;": "\u2190", + "smallsetminus;": "\u2216", + "smashp;": "\u2a33", + "smeparsl;": "\u29e4", + "smid;": "\u2223", + "smile;": "\u2323", + "smt;": "\u2aaa", + "smte;": "\u2aac", + "smtes;": "\u2aac\ufe00", + "softcy;": "\u044c", + "sol;": "/", + "solb;": "\u29c4", + "solbar;": "\u233f", + "sopf;": "\U0001d564", + "spades;": "\u2660", + "spadesuit;": "\u2660", + "spar;": "\u2225", + "sqcap;": "\u2293", + "sqcaps;": "\u2293\ufe00", + "sqcup;": "\u2294", + "sqcups;": "\u2294\ufe00", + "sqsub;": "\u228f", + "sqsube;": "\u2291", + "sqsubset;": "\u228f", + "sqsubseteq;": "\u2291", + "sqsup;": "\u2290", + "sqsupe;": "\u2292", + "sqsupset;": "\u2290", + "sqsupseteq;": "\u2292", + "squ;": "\u25a1", + "square;": "\u25a1", + "squarf;": "\u25aa", + "squf;": "\u25aa", + "srarr;": "\u2192", + "sscr;": "\U0001d4c8", + "ssetmn;": "\u2216", + "ssmile;": "\u2323", + "sstarf;": "\u22c6", + "star;": "\u2606", + "starf;": "\u2605", + "straightepsilon;": "\u03f5", + "straightphi;": "\u03d5", + "strns;": "\xaf", + "sub;": "\u2282", + "subE;": "\u2ac5", + "subdot;": "\u2abd", + "sube;": "\u2286", + "subedot;": "\u2ac3", + "submult;": "\u2ac1", + "subnE;": "\u2acb", + "subne;": "\u228a", + "subplus;": "\u2abf", + "subrarr;": "\u2979", + "subset;": "\u2282", + "subseteq;": "\u2286", + "subseteqq;": "\u2ac5", + "subsetneq;": "\u228a", + "subsetneqq;": "\u2acb", + "subsim;": "\u2ac7", + "subsub;": "\u2ad5", + "subsup;": "\u2ad3", + "succ;": "\u227b", + "succapprox;": "\u2ab8", + "succcurlyeq;": "\u227d", + "succeq;": "\u2ab0", + "succnapprox;": "\u2aba", + "succneqq;": "\u2ab6", + "succnsim;": "\u22e9", + "succsim;": "\u227f", + "sum;": "\u2211", + "sung;": "\u266a", + "sup1": "\xb9", + "sup1;": "\xb9", + "sup2": "\xb2", + "sup2;": "\xb2", + "sup3": "\xb3", + "sup3;": "\xb3", + "sup;": "\u2283", + "supE;": "\u2ac6", + "supdot;": "\u2abe", + "supdsub;": "\u2ad8", + "supe;": "\u2287", + "supedot;": "\u2ac4", + "suphsol;": "\u27c9", + "suphsub;": "\u2ad7", + "suplarr;": "\u297b", + "supmult;": "\u2ac2", + "supnE;": "\u2acc", + "supne;": "\u228b", + "supplus;": "\u2ac0", + "supset;": "\u2283", + "supseteq;": "\u2287", + "supseteqq;": "\u2ac6", + "supsetneq;": "\u228b", + "supsetneqq;": "\u2acc", + "supsim;": "\u2ac8", + "supsub;": "\u2ad4", + "supsup;": "\u2ad6", + "swArr;": "\u21d9", + "swarhk;": "\u2926", + "swarr;": "\u2199", + "swarrow;": "\u2199", + "swnwar;": "\u292a", + "szlig": "\xdf", + "szlig;": "\xdf", + "target;": "\u2316", + "tau;": "\u03c4", + "tbrk;": "\u23b4", + "tcaron;": "\u0165", + "tcedil;": "\u0163", + "tcy;": "\u0442", + "tdot;": "\u20db", + "telrec;": "\u2315", + "tfr;": "\U0001d531", + "there4;": "\u2234", + "therefore;": "\u2234", + "theta;": "\u03b8", + "thetasym;": "\u03d1", + "thetav;": "\u03d1", + "thickapprox;": "\u2248", + "thicksim;": "\u223c", + "thinsp;": "\u2009", + "thkap;": "\u2248", + "thksim;": "\u223c", + "thorn": "\xfe", + "thorn;": "\xfe", + "tilde;": "\u02dc", + "times": "\xd7", + "times;": "\xd7", + "timesb;": "\u22a0", + "timesbar;": "\u2a31", + "timesd;": "\u2a30", + "tint;": "\u222d", + "toea;": "\u2928", + "top;": "\u22a4", + "topbot;": "\u2336", + "topcir;": "\u2af1", + "topf;": "\U0001d565", + "topfork;": "\u2ada", + "tosa;": "\u2929", + "tprime;": "\u2034", + "trade;": "\u2122", + "triangle;": "\u25b5", + "triangledown;": "\u25bf", + "triangleleft;": "\u25c3", + "trianglelefteq;": "\u22b4", + "triangleq;": "\u225c", + "triangleright;": "\u25b9", + "trianglerighteq;": "\u22b5", + "tridot;": "\u25ec", + "trie;": "\u225c", + "triminus;": "\u2a3a", + "triplus;": "\u2a39", + "trisb;": "\u29cd", + "tritime;": "\u2a3b", + "trpezium;": "\u23e2", + "tscr;": "\U0001d4c9", + "tscy;": "\u0446", + "tshcy;": "\u045b", + "tstrok;": "\u0167", + "twixt;": "\u226c", + "twoheadleftarrow;": "\u219e", + "twoheadrightarrow;": "\u21a0", + "uArr;": "\u21d1", + "uHar;": "\u2963", + "uacute": "\xfa", + "uacute;": "\xfa", + "uarr;": "\u2191", + "ubrcy;": "\u045e", + "ubreve;": "\u016d", + "ucirc": "\xfb", + "ucirc;": "\xfb", + "ucy;": "\u0443", + "udarr;": "\u21c5", + "udblac;": "\u0171", + "udhar;": "\u296e", + "ufisht;": "\u297e", + "ufr;": "\U0001d532", + "ugrave": "\xf9", + "ugrave;": "\xf9", + "uharl;": "\u21bf", + "uharr;": "\u21be", + "uhblk;": "\u2580", + "ulcorn;": "\u231c", + "ulcorner;": "\u231c", + "ulcrop;": "\u230f", + "ultri;": "\u25f8", + "umacr;": "\u016b", + "uml": "\xa8", + "uml;": "\xa8", + "uogon;": "\u0173", + "uopf;": "\U0001d566", + "uparrow;": "\u2191", + "updownarrow;": "\u2195", + "upharpoonleft;": "\u21bf", + "upharpoonright;": "\u21be", + "uplus;": "\u228e", + "upsi;": "\u03c5", + "upsih;": "\u03d2", + "upsilon;": "\u03c5", + "upuparrows;": "\u21c8", + "urcorn;": "\u231d", + "urcorner;": "\u231d", + "urcrop;": "\u230e", + "uring;": "\u016f", + "urtri;": "\u25f9", + "uscr;": "\U0001d4ca", + "utdot;": "\u22f0", + "utilde;": "\u0169", + "utri;": "\u25b5", + "utrif;": "\u25b4", + "uuarr;": "\u21c8", + "uuml": "\xfc", + "uuml;": "\xfc", + "uwangle;": "\u29a7", + "vArr;": "\u21d5", + "vBar;": "\u2ae8", + "vBarv;": "\u2ae9", + "vDash;": "\u22a8", + "vangrt;": "\u299c", + "varepsilon;": "\u03f5", + "varkappa;": "\u03f0", + "varnothing;": "\u2205", + "varphi;": "\u03d5", + "varpi;": "\u03d6", + "varpropto;": "\u221d", + "varr;": "\u2195", + "varrho;": "\u03f1", + "varsigma;": "\u03c2", + "varsubsetneq;": "\u228a\ufe00", + "varsubsetneqq;": "\u2acb\ufe00", + "varsupsetneq;": "\u228b\ufe00", + "varsupsetneqq;": "\u2acc\ufe00", + "vartheta;": "\u03d1", + "vartriangleleft;": "\u22b2", + "vartriangleright;": "\u22b3", + "vcy;": "\u0432", + "vdash;": "\u22a2", + "vee;": "\u2228", + "veebar;": "\u22bb", + "veeeq;": "\u225a", + "vellip;": "\u22ee", + "verbar;": "|", + "vert;": "|", + "vfr;": "\U0001d533", + "vltri;": "\u22b2", + "vnsub;": "\u2282\u20d2", + "vnsup;": "\u2283\u20d2", + "vopf;": "\U0001d567", + "vprop;": "\u221d", + "vrtri;": "\u22b3", + "vscr;": "\U0001d4cb", + "vsubnE;": "\u2acb\ufe00", + "vsubne;": "\u228a\ufe00", + "vsupnE;": "\u2acc\ufe00", + "vsupne;": "\u228b\ufe00", + "vzigzag;": "\u299a", + "wcirc;": "\u0175", + "wedbar;": "\u2a5f", + "wedge;": "\u2227", + "wedgeq;": "\u2259", + "weierp;": "\u2118", + "wfr;": "\U0001d534", + "wopf;": "\U0001d568", + "wp;": "\u2118", + "wr;": "\u2240", + "wreath;": "\u2240", + "wscr;": "\U0001d4cc", + "xcap;": "\u22c2", + "xcirc;": "\u25ef", + "xcup;": "\u22c3", + "xdtri;": "\u25bd", + "xfr;": "\U0001d535", + "xhArr;": "\u27fa", + "xharr;": "\u27f7", + "xi;": "\u03be", + "xlArr;": "\u27f8", + "xlarr;": "\u27f5", + "xmap;": "\u27fc", + "xnis;": "\u22fb", + "xodot;": "\u2a00", + "xopf;": "\U0001d569", + "xoplus;": "\u2a01", + "xotime;": "\u2a02", + "xrArr;": "\u27f9", + "xrarr;": "\u27f6", + "xscr;": "\U0001d4cd", + "xsqcup;": "\u2a06", + "xuplus;": "\u2a04", + "xutri;": "\u25b3", + "xvee;": "\u22c1", + "xwedge;": "\u22c0", + "yacute": "\xfd", + "yacute;": "\xfd", + "yacy;": "\u044f", + "ycirc;": "\u0177", + "ycy;": "\u044b", + "yen": "\xa5", + "yen;": "\xa5", + "yfr;": "\U0001d536", + "yicy;": "\u0457", + "yopf;": "\U0001d56a", + "yscr;": "\U0001d4ce", + "yucy;": "\u044e", + "yuml": "\xff", + "yuml;": "\xff", + "zacute;": "\u017a", + "zcaron;": "\u017e", + "zcy;": "\u0437", + "zdot;": "\u017c", + "zeetrf;": "\u2128", + "zeta;": "\u03b6", + "zfr;": "\U0001d537", + "zhcy;": "\u0436", + "zigrarr;": "\u21dd", + "zopf;": "\U0001d56b", + "zscr;": "\U0001d4cf", + "zwj;": "\u200d", + "zwnj;": "\u200c", +} + +replacementCharacters = { + 0x0: "\uFFFD", + 0x0d: "\u000D", + 0x80: "\u20AC", + 0x81: "\u0081", + 0x82: "\u201A", + 0x83: "\u0192", + 0x84: "\u201E", + 0x85: "\u2026", + 0x86: "\u2020", + 0x87: "\u2021", + 0x88: "\u02C6", + 0x89: "\u2030", + 0x8A: "\u0160", + 0x8B: "\u2039", + 0x8C: "\u0152", + 0x8D: "\u008D", + 0x8E: "\u017D", + 0x8F: "\u008F", + 0x90: "\u0090", + 0x91: "\u2018", + 0x92: "\u2019", + 0x93: "\u201C", + 0x94: "\u201D", + 0x95: "\u2022", + 0x96: "\u2013", + 0x97: "\u2014", + 0x98: "\u02DC", + 0x99: "\u2122", + 0x9A: "\u0161", + 0x9B: "\u203A", + 0x9C: "\u0153", + 0x9D: "\u009D", + 0x9E: "\u017E", + 0x9F: "\u0178", +} + +tokenTypes = { + "Doctype": 0, + "Characters": 1, + "SpaceCharacters": 2, + "StartTag": 3, + "EndTag": 4, + "EmptyTag": 5, + "Comment": 6, + "ParseError": 7 +} + +tagTokenTypes = frozenset([tokenTypes["StartTag"], tokenTypes["EndTag"], + tokenTypes["EmptyTag"]]) + + +prefixes = dict([(v, k) for k, v in namespaces.items()]) +prefixes["http://www.w3.org/1998/Math/MathML"] = "math" + + +class DataLossWarning(UserWarning): + """Raised when the current tree is unable to represent the input data""" + pass + + +class _ReparseException(Exception): + pass diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dee7907692e5947bba8d2f37dd5ea48884d0586f GIT binary patch literal 157 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd<h9ZzKg81d8Uy@s(Uyxa# zo0(T!l9-dDn_QlrmsL_|0ult{__EZzl>8$7jFQ|O)11sC{j|)SlGLJN{rLFIyv&mL Yc)fzkTO2mI`6;D2sdgaqi-DK{0E_x2xc~qF literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/alphabeticalattributes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d6da0eadbb40a631afb638bd1438f189ba09ed2 GIT binary patch literal 1273 zcmZuxy>A;g6esUPI?1wQG%b(-9XJ$C1vJ*uE`<>!ZPEfARG<lB;E<N4j+8~4_hFKf zBSW5&wR6WNWB(<to$@ENQ{SVlq(g~&kB^V!?|t&V-Q67$808<IzxX{R<S$%oM+U+} zAon9MNhCF-rX{VDGO5!tr9>t&HCdgPImkq2rdRjNKFGQ3y(VSx1Cf1Mye6_x`RU+Q zS`OskDH#vn0UjBr;g*=W)-1i^y6#%*Lm~A_JKZ*6f7$4&m5Lkfl@-Rlqj-mgY$lw7 zdFLl9l~wYwu6%`iIB<q2$ag^QQ(znL`fj9dPbN33^e&kv;74}(_s_~NZNmh7U1!_Q zYT*?-Q)@PFZB%=2^$c8$3I|T==43czFdl8U99xK$VuCfIR<0A3Vtye!s{nSUn9_cs zEIU4)wv9SIW(dq2z&0lb>_|l{IC>8*v~?#e-Uhm8;c_LGF0R-2Kri)t4ly^L`E{q< zm&~>7Lcz6WrL2!Y@2&V2-B)$z*Eh!4TwCW4uAR4-sz7WG)1NV~0>ZHaSVs2Gvx%>} zNvFH}x^Z3@bHBPcX-@t5SE!7{SE`Y%oh*E9zBYO`nQH^ZauZ>?g_tR?D`5~eCeR&p z>oDNB=8)h5EV%?2DeMS%h2nOg{vnXN15A;UN>V10mML}|bXF!as9zp>-$#p=pFP@I zyi|^TFd2)cjH)4L?tPbF%t&a`NnkI3_2iVkf&O?)ACq6ES9C*T-y~-}``o9m$W`+4 z3!i}&dgo34miV5`eoNr&{)^-)y~;M(CfTHi<ouf>0ur1%Bpdo18uEPa2;K&II}I6@ zZJdPSsTbBi6DOf~f(1e;lfnz=>lAV`?%N)?Wp{yvf^&QVoZCJwd)R|Yh8&c&i>ZS| zWKNlR$bEaJnvi1xT*$B;L%tGbsXi3e?jZ7QV4ncFePD!sL`Sqo_vk*%1--m=oz{b` z<tbPIHxQ5WFyy>$<<g)$;{1Fm%*{@pbJ<qlDZ>B9WbCSF7bC(=hyRv>W;Dh)9S;$8 zzJ$jJs20m_Q)GC|Vync2gq^B2MpYjE5H6-8#vd{M&s-=DuRVQ$-R=<Q<7AYK(qiXd DT8v7) literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/base.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8052b4406be503f2cd478665a52e24cc5a40c51e GIT binary patch literal 807 zcmZuvO>fjN5VhlMHuOV_5NA#Zkwcpc+z_gYRBpX+i;zay*jv1EK59EfRD0Y056=80 zUwh&&aAL;kR$IhKGh@fk^WKbeetdku(5jzrzP{p&-P2}gDK5^?-CGQjNp4unE8Zqm z(uzuO_L<2<iaRESO1Gk#$@B{=X1@{53K16d()DKa3UoX4)`wi`8|`%8h38|Zn_em~ z+ACWd*U+7vCAc_4cds!hR&mLyL~@zju}VlGQ_QKH$qe&M&XF?@*@ZS(s-e4Nl*vD# zJ8E&mHw>@~MDxpnhs^b(ZB&tj)G4#F8Df4hn`8QOUix+@2R)qV&iUGylji$XxAxcX z=wo!aQJw5<`OUZHz0u2Z75QDcterX?euNxAciIEYNI{gvZx@rw)7@EvBacS;iCoV% zY|XcPl8Yi~P*G&T?Htij=@g#fHu50^fI9dOUp#v<9)Z9(o+DgLd>g(^c8v2Y<!kRB zNRvn!(yngRzto2S4_JW1J@yxm-98>)78xm}DgfaCpzY;oXnh25J=SJAvGih=blC+3 z>S-@f!<Obsf2gCE%Xuzx5x)@y7G8~hv{=~ESS|Hx2_3S2xmJyj(7lq8VH)IzNz+Gq JlQ_ti;xC=8up$5e literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/inject_meta_charset.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b688c377e552a5b616fa46dbed2f93ff8d94c16d GIT binary patch literal 1827 zcmZuyOK%%D5GJ`#$+E4+k2>vTVW0(caC~WdNSz?4?F0b|HARA?SU6a(mz1>fzC==v zZLAJO^8<Y7p(p~>I`&rd=yQKS&wI$Fr~HMYC_3cIiED%cXGzXC!<pgC=&SkpCW7Jr z^6B39a|r#VHkZSM#XXqf3m_CxoS+o@I3+$w4d1|s5^5x7YWWsM4-hq}^%7BwSws5= z!?&sZ7<HUCAd5OiwHO|VJQ+(C#A%UpS-CVmibb4fRePMpQBGNq#FFta5pS@P!IgOs z3Kl5^mxI9K9!%i@VaUf6`GjKMP^P>@zF8aLTlM9YeLqe>=jok?*^ot2c>DWXDU+cW z4MHxMytCWg{$}T4_rcx$eNTpcFV1A{4OmFMyyww88mBCikpZ`<p}s0A+c3o%5Q&EP zoRp}<Q-V<mtH7Wb{3fSzo3l_d;e}ppM6>D5#_f>zJ&})j#BO_Xz-DVt=7%ivgapC# z8k%Jgp*ZW;_{$wgc;Ll5Y`0@_8|>l^kjf2$IE!TvRPLn&yo4!O(yQ$He%=7!uZXwc z^Y^!#GA%ZXxY&p@A;Touh+g!wp&Wgt4)qL<SVnWcIgn}cc@iIN_H=;7W~>7osNe>( z;NB`uxC?sK6e?`UUBIV{bu?~W+7_wDRzoGCvOR(+Uc)KH6I`Mpq~4)BA$>G4&hYUc z5)a9_QKBi{L1*~+?-R2$DY=OzR%ub=knl&aH*cbIa|+1_`>&}z!Dl!d0^d0#XZU{z z7ZCr_#>75;4RTG8v!-YVJ%74K_Q=GUxRXZdfCUZy<ER{!rK|PMfz*Yvt(GaB((REg zL|YT`2q_eu2SiymG<rd;foG4(XQ;IKKXkE{J5=ko(z80#L>Fr<*)=b~>WdO=7Z=o^ zRxM3Gcx60AP=*e5=?$eN#&6G-s704w5zPmyM(f)DCGGzO$X|(&)(x?R8;o<Cu1v9# z(zpHeKHbM_r9%I96@7+BKR?s{(^YsiOl^JBpMY^nbBZw<t(T_KJ6Z=Ef)e?#>$?SK zfvUF3lqUtN+{ZHH@=4gQ%q&b<Wh$QU#90k;chf?iXtv6;`;|#U8CK3L-=3T{2T~Rr zY&4FKPFqo)Nhsb8rMW}80ILs9S0p=@I)lG_+Xp@o9fL1G=JB>7%RoSeufVsmcQXo? zcE}ZgN?N~B<U(rGI<79HYqbZR2Wrns@)wL(7Bsh1R7Q~(l^qrZ)KRC&Rnk`$6q{sz zQx{J!A7`|36d&rnvUF3>H~SwCLJ=qz1MOlkb12ZUYp95cB8-@Jp|Xy`WXyD7*JK{9 z;;Lya!4%&CLD<AiY?4*%!mo{8(!_0I;*Vfw;ugLE)Wpkh-iEbJ)_}JFCvD&X2heMz zg>8M})@V3uk*hVXW6<r`su?K@At22lNOL+))VdV}qj8wbI8G2i&kX|IHngo*>{l&{ zYbR85Q=LL6qD*z?bi?a*9HqQBmSf1PfUAECu6j0C-KRqDp67jPD|f3l>#llS-LRHP G%lHq1(9t;n literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/lint.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4931536102fdf3c609848f3e5b3609dd04a41e9b GIT binary patch literal 2591 zcmZuzOK%)S5bmDG?(Ex1oK0*V8juKVMC=>@A%jpz;-E;#2OJV<lrSDo_uAu~$GW@M zv8}a);z*G=?S%^$>?0CF`~VJ!V}1deD=1Ppa^yr+&#t|JjMd%MUDZ`zRrOZ+dZSS# z@Oj@~y8ls=kUwxU`79u=!H}CUF~Vp}66(>!@QlRtOp0elY$dj518p)ZE+u8J47ANk zv6EE1N>cTzdS8Zp&8q?J9MyU4n0mF(2&=H_W5TMuywx}~y#}kTl1}|OSR)-XZw2cz ziwBDPQPR(Z${iN%L^8_Kd}feFVaB*0M~aIemK~Z`6yH_8+UxV@6cy0iS`Q?DZs5kq zt7(vM*$+Z4^ZHH}vE`U2JXLtLrO$6{1|kSSpUg>!7$zUa0Y7;eCQdxch-WbBnXLST zbSZlNxZ+vp^<(1MPl!dl5_sa|rCU)93imfYkHC_vHo2>^9#37V1P>Con+cZ-kqKF? zy71lZx{-3bQOcwnq<drDyKwk+9J?ZjB!_c%ZS7Mjxlj;_WxTz%wou%^6Pg++A-GP4 zoQI7fiVn%4abyhXF{NZ^42f?t3OJ4ZZ*Kq`#lfgsATHD)q@_S?xH21vkS}Qm3i<^< z{v$2;_8=16PXZNgM(KvHf(^OkKHTIG0O5kqX{JDdI~H^&f-VZ4DqHDTxh)5Mh)@GO z$Q|F0(n$G!e*UE<;LTW)$KAYCU=%ZO3txushjAdK@BcvlxxT29{$fAsUx`wwf;hes zKHNyR)b@LLsE5D9Q<jOvO_jv&$I<#?S7%W!#*oE@{+?)o-m@^Iei_aT-ES3PTbLjW z@d@Hrfnmc4VaOH8$Obu}BXjq<B3l%4L5}H7GBO`rJurswrsl|jIW(EkD~+gFffEx> zELbgA?V-g;&yim!b7(2+&;ZJQMB&u#ner>7fn#e<tU0#k?2b7GE6ovAf_vW-_r!Og zr_9Q8q-Thq;il6o!D=$6XUJbrCauG+GT9Zh_<cyWDlpTd>d+e6T?60KZXZyB{-fG4 zxk(<Z-8b$V2iAdoP%2Q5sH{(LYx)E^?B>S^HFnrv*7!7f*nK$Wmb7QjaJT*J9vRW} zZ$MP-86!hfUmh#C{b<VSBdu4*3pk^(-ig&C&7D~NsgQ*{{B{~8*!@|=2`N?^8M35o zR%eZ&9nm&9q!6<=F+L+xT!RSJkI6xKST5oONKJVS^#b+}0DDtozgk4@zyYKV`Zy&u z15zz`4Tkvoe^QhDJD6oavZfK6YzFOsb?2y|n#UBlCmPdVLEjl|^)Jv@yeb=C72N-E z@_ICl`7zkpIjHiQ`*e!?R9iCGxiJ^L8o#^=_Vg}Tn$<|Ez|*#-ebfG**Zj+xk8g9z z_p}Ys)zM;YMu+Akx<lhGp=5jZ9^iu7bzvp9u;xRBcUDy()SX}>cb1dB+C!>xQuT8S zNl}O2VQ#TN1-XU4Z*dV0#05MpEvF3b+}dBb3+=(>MSp-Ih0TXEH;`^2QPjRA_pNuJ zUUg({!jhM7WC`{YY&BDzq_v7I=k!3lfu_ngvk+0|PJgf-N8xRjJ91Ado&W_nRHXL2 z)+!fK5J&r5=qkVe>X&IR%^s%X+KUP_2y|a|TB3}uoK#BaJ5VXB&@i#ir6Ctshw|o& ztpj2ag-T$V68N8hu9<l$==Y%p<~Fp~1RU&VeW=7rM14^Mp-x4dfyHZNAmxt(C39Q% zHqk~kb2wq&$?csW9&o%4*%7bc`RvJb9;r((y#_<ZFcE6eHg#wfh67ZcHesBl7irT# zx=H8ZuSsWMw2eY)vVR?<^eufpt7nv}jwR>m>(qr)yw^6{#&p@%;p)&koig?rd@C3| z-%m0&h>@=Q{`Me<$DFe7vn=#|-3zn_d1KsWLLSG!IB~K=#X0axXkRfs_y%POCdamD zv!+wF(rKc#?m!KobNT}RYZ2JM1@@S{1-)ru+?N()w5xNeAG6MSUI{auWhJLliK)u1 htt?8liBm)cg?Mu3<HEsDuwh9=Hfz)&&@(Wq=D!pGu5<tZ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/optionaltags.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..26eae2aa302aa83828ee4558772afe89893b45eb GIT binary patch literal 2718 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 LD<hEwqiOyNP2!7I literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/sanitizer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4659964aaf5979fe663189d8a6a9800d783b51e GIT binary patch literal 16393 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/__pycache__/whitespace.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0510bcb0f4dce77f421acd02ac55bd2baee74b77 GIT binary patch literal 1311 zcmZ8hPjA~c6elT4mK-|{g0x+>9t;c}U@WaK8(I`au{QI%QxMF<R%j~(MPw2=)Sr;F zn+DD)ML$3fz0N!COYDR2x>LSFPkT?Uo1zpRCB8r8`@P?zo_4!!0wezGn?L{Mg#3q# z)qpkm0mPIr2_mQ>1&wLJVpe#uM^VQVkGb#!SAG%10qA@Ys8$iiVG+d<tXqq=jQ*x^ zB>7@ZgfhBGVAXj>L?qg;iD=7U(!KQJu2>VD*CbvSY)l5-D>#!3Jl9JPOr@q)CV5d; z+PYBWv)trW={BZio>f97Dz{Rn%IsZH45E%7q()vbTrjt;Gm+YKq+}sWYh2INX(o4% zQ=MiIXB;{A|F~mbe4F8stML*14rnBasUR^EH1;GHOn663`ZBnrx5y=pTY?K8QV&G{ zskdD4Q?6j=^C!ENQfY0Z>AyUN9Gipt@+_0J?dN5`)^ewB<(W;jOn3TeDf%YUIT+<C zSr2?%xbn#m9}dh81yeQ)m;}9`XYVYT&;^@Afqx_~-dwOb6KtDYcymv9Crm$`Q}Y0H ze4EV4#5)O4BmDd1f|mQ>6M)b2IYklv1Jpi*h#6Q~V3|Q=xJ~p-MELcHl()h97OZWs zzO{U5zobj+oc%^9Io<pn+61bywx=<9$L*^c5RCz|{WU#uyi5zJeKZB5QlP3g{)`}w z{Jp1r*S=<L;OhW_^cqHnNrEkqB<@C2<9#iS)H8X_dG>*cq_LX;cic#I7>7{b#?|?@ zI+3MbhyDH``YU+7|9NPOdRXW6-Mln5RqAf`@~E8H)9+B(NHUY9sPypI7V3MI9}Ev0 z>do+)@O$+ueG|6Z05M;}L@1}5G=yi9wpj;ci{X2No%fcVb8m%bZxA6ktPy}~CrMF> zslxA0lAKOc^}*6g5>aKKjt+HoE=wb=<0>~+hj5<0g%jq`;QC~`jXEr02gG1OLr89m zHM)=8hQwjF?V=NUTC$*mLZ9JPWqW!Hba2x;<NYVQqjB=f=-KGG^UU-B?;<wu=SO}4 z0e5gWyrYC_Tn~B(@NjCU8USjvXb&em+A%FP{;C?*U6fVG2wdkSzzALVq{>Uz%BrHy nmDFFOH)3mc|0DzCRwHs3K3dlEF(Ncb{T2(63E*Vi+uZ&i$Q4Yl literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py new file mode 100644 index 0000000..5ba926e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/alphabeticalattributes.py @@ -0,0 +1,29 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + +from collections import OrderedDict + + +def _attr_key(attr): + """Return an appropriate key for an attribute for sorting + + Attributes have a namespace that can be either ``None`` or a string. We + can't compare the two because they're different types, so we convert + ``None`` to an empty string first. + + """ + return (attr[0][0] or ''), attr[0][1] + + +class Filter(base.Filter): + """Alphabetizes attributes for elements""" + def __iter__(self): + for token in base.Filter.__iter__(self): + if token["type"] in ("StartTag", "EmptyTag"): + attrs = OrderedDict() + for name, value in sorted(token["data"].items(), + key=_attr_key): + attrs[name] = value + token["data"] = attrs + yield token diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py new file mode 100644 index 0000000..c7dbaed --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/base.py @@ -0,0 +1,12 @@ +from __future__ import absolute_import, division, unicode_literals + + +class Filter(object): + def __init__(self, source): + self.source = source + + def __iter__(self): + return iter(self.source) + + def __getattr__(self, name): + return getattr(self.source, name) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py new file mode 100644 index 0000000..aefb5c8 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/inject_meta_charset.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Injects ``<meta charset=ENCODING>`` tag into head of document""" + def __init__(self, source, encoding): + """Creates a Filter + + :arg source: the source token stream + + :arg encoding: the encoding to set + + """ + base.Filter.__init__(self, source) + self.encoding = encoding + + def __iter__(self): + state = "pre_head" + meta_found = (self.encoding is None) + pending = [] + + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag": + if token["name"].lower() == "head": + state = "in_head" + + elif type == "EmptyTag": + if token["name"].lower() == "meta": + # replace charset with actual encoding + has_http_equiv_content_type = False + for (namespace, name), value in token["data"].items(): + if namespace is not None: + continue + elif name.lower() == 'charset': + token["data"][(namespace, name)] = self.encoding + meta_found = True + break + elif name == 'http-equiv' and value.lower() == 'content-type': + has_http_equiv_content_type = True + else: + if has_http_equiv_content_type and (None, "content") in token["data"]: + token["data"][(None, "content")] = 'text/html; charset=%s' % self.encoding + meta_found = True + + elif token["name"].lower() == "head" and not meta_found: + # insert meta into empty head + yield {"type": "StartTag", "name": "head", + "data": token["data"]} + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + yield {"type": "EndTag", "name": "head"} + meta_found = True + continue + + elif type == "EndTag": + if token["name"].lower() == "head" and pending: + # insert meta into head (if necessary) and flush pending queue + yield pending.pop(0) + if not meta_found: + yield {"type": "EmptyTag", "name": "meta", + "data": {(None, "charset"): self.encoding}} + while pending: + yield pending.pop(0) + meta_found = True + state = "post_head" + + if state == "in_head": + pending.append(token) + else: + yield token diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py new file mode 100644 index 0000000..fcc07ee --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/lint.py @@ -0,0 +1,93 @@ +from __future__ import absolute_import, division, unicode_literals + +from pip._vendor.six import text_type + +from . import base +from ..constants import namespaces, voidElements + +from ..constants import spaceCharacters +spaceCharacters = "".join(spaceCharacters) + + +class Filter(base.Filter): + """Lints the token stream for errors + + If it finds any errors, it'll raise an ``AssertionError``. + + """ + def __init__(self, source, require_matching_tags=True): + """Creates a Filter + + :arg source: the source token stream + + :arg require_matching_tags: whether or not to require matching tags + + """ + super(Filter, self).__init__(source) + self.require_matching_tags = require_matching_tags + + def __iter__(self): + open_elements = [] + for token in base.Filter.__iter__(self): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(token["data"], dict) + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert type == "EmptyTag" + else: + assert type == "StartTag" + if type == "StartTag" and self.require_matching_tags: + open_elements.append((namespace, name)) + for (namespace, name), value in token["data"].items(): + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + assert isinstance(value, text_type) + + elif type == "EndTag": + namespace = token["namespace"] + name = token["name"] + assert namespace is None or isinstance(namespace, text_type) + assert namespace != "" + assert isinstance(name, text_type) + assert name != "" + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + assert False, "Void element reported as EndTag token: %(tag)s" % {"tag": name} + elif self.require_matching_tags: + start = open_elements.pop() + assert start == (namespace, name) + + elif type == "Comment": + data = token["data"] + assert isinstance(data, text_type) + + elif type in ("Characters", "SpaceCharacters"): + data = token["data"] + assert isinstance(data, text_type) + assert data != "" + if type == "SpaceCharacters": + assert data.strip(spaceCharacters) == "" + + elif type == "Doctype": + name = token["name"] + assert name is None or isinstance(name, text_type) + assert token["publicId"] is None or isinstance(name, text_type) + assert token["systemId"] is None or isinstance(name, text_type) + + elif type == "Entity": + assert isinstance(token["name"], text_type) + + elif type == "SerializerError": + assert isinstance(token["data"], text_type) + + else: + assert False, "Unknown token type: %(type)s" % {"type": type} + + yield token diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py new file mode 100644 index 0000000..4a86501 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/optionaltags.py @@ -0,0 +1,207 @@ +from __future__ import absolute_import, division, unicode_literals + +from . import base + + +class Filter(base.Filter): + """Removes optional tags from the token stream""" + def slider(self): + previous1 = previous2 = None + for token in self.source: + if previous1 is not None: + yield previous2, previous1, token + previous2 = previous1 + previous1 = token + if previous1 is not None: + yield previous2, previous1, None + + def __iter__(self): + for previous, token, next in self.slider(): + type = token["type"] + if type == "StartTag": + if (token["data"] or + not self.is_optional_start(token["name"], previous, next)): + yield token + elif type == "EndTag": + if not self.is_optional_end(token["name"], next): + yield token + else: + yield token + + def is_optional_start(self, tagname, previous, next): + type = next and next["type"] or None + if tagname in 'html': + # An html element's start tag may be omitted if the first thing + # inside the html element is not a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname == 'head': + # A head element's start tag may be omitted if the first thing + # inside the head element is an element. + # XXX: we also omit the start tag if the head element is empty + if type in ("StartTag", "EmptyTag"): + return True + elif type == "EndTag": + return next["name"] == "head" + elif tagname == 'body': + # A body element's start tag may be omitted if the first thing + # inside the body element is not a space character or a comment, + # except if the first thing inside the body element is a script + # or style element and the node immediately preceding the body + # element is a head element whose end tag has been omitted. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we do not look at the preceding event, so we never omit + # the body element's start tag if it's followed by a script or + # a style element. + return next["name"] not in ('script', 'style') + else: + return True + elif tagname == 'colgroup': + # A colgroup element's start tag may be omitted if the first thing + # inside the colgroup element is a col element, and if the element + # is not immediately preceded by another colgroup element whose + # end tag has been omitted. + if type in ("StartTag", "EmptyTag"): + # XXX: we do not look at the preceding event, so instead we never + # omit the colgroup element's end tag when it is immediately + # followed by another colgroup element. See is_optional_end. + return next["name"] == "col" + else: + return False + elif tagname == 'tbody': + # A tbody element's start tag may be omitted if the first thing + # inside the tbody element is a tr element, and if the element is + # not immediately preceded by a tbody, thead, or tfoot element + # whose end tag has been omitted. + if type == "StartTag": + # omit the thead and tfoot elements' end tag when they are + # immediately followed by a tbody element. See is_optional_end. + if previous and previous['type'] == 'EndTag' and \ + previous['name'] in ('tbody', 'thead', 'tfoot'): + return False + return next["name"] == 'tr' + else: + return False + return False + + def is_optional_end(self, tagname, next): + type = next and next["type"] or None + if tagname in ('html', 'head', 'body'): + # An html element's end tag may be omitted if the html element + # is not immediately followed by a space character or a comment. + return type not in ("Comment", "SpaceCharacters") + elif tagname in ('li', 'optgroup', 'tr'): + # A li element's end tag may be omitted if the li element is + # immediately followed by another li element or if there is + # no more content in the parent element. + # An optgroup element's end tag may be omitted if the optgroup + # element is immediately followed by another optgroup element, + # or if there is no more content in the parent element. + # A tr element's end tag may be omitted if the tr element is + # immediately followed by another tr element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] == tagname + else: + return type == "EndTag" or type is None + elif tagname in ('dt', 'dd'): + # A dt element's end tag may be omitted if the dt element is + # immediately followed by another dt element or a dd element. + # A dd element's end tag may be omitted if the dd element is + # immediately followed by another dd element or a dt element, + # or if there is no more content in the parent element. + if type == "StartTag": + return next["name"] in ('dt', 'dd') + elif tagname == 'dd': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'p': + # A p element's end tag may be omitted if the p element is + # immediately followed by an address, article, aside, + # blockquote, datagrid, dialog, dir, div, dl, fieldset, + # footer, form, h1, h2, h3, h4, h5, h6, header, hr, menu, + # nav, ol, p, pre, section, table, or ul, element, or if + # there is no more content in the parent element. + if type in ("StartTag", "EmptyTag"): + return next["name"] in ('address', 'article', 'aside', + 'blockquote', 'datagrid', 'dialog', + 'dir', 'div', 'dl', 'fieldset', 'footer', + 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', + 'header', 'hr', 'menu', 'nav', 'ol', + 'p', 'pre', 'section', 'table', 'ul') + else: + return type == "EndTag" or type is None + elif tagname == 'option': + # An option element's end tag may be omitted if the option + # element is immediately followed by another option element, + # or if it is immediately followed by an <code>optgroup</code> + # element, or if there is no more content in the parent + # element. + if type == "StartTag": + return next["name"] in ('option', 'optgroup') + else: + return type == "EndTag" or type is None + elif tagname in ('rt', 'rp'): + # An rt element's end tag may be omitted if the rt element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + # An rp element's end tag may be omitted if the rp element is + # immediately followed by an rt or rp element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('rt', 'rp') + else: + return type == "EndTag" or type is None + elif tagname == 'colgroup': + # A colgroup element's end tag may be omitted if the colgroup + # element is not immediately followed by a space character or + # a comment. + if type in ("Comment", "SpaceCharacters"): + return False + elif type == "StartTag": + # XXX: we also look for an immediately following colgroup + # element. See is_optional_start. + return next["name"] != 'colgroup' + else: + return True + elif tagname in ('thead', 'tbody'): + # A thead element's end tag may be omitted if the thead element + # is immediately followed by a tbody or tfoot element. + # A tbody element's end tag may be omitted if the tbody element + # is immediately followed by a tbody or tfoot element, or if + # there is no more content in the parent element. + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] in ['tbody', 'tfoot'] + elif tagname == 'tbody': + return type == "EndTag" or type is None + else: + return False + elif tagname == 'tfoot': + # A tfoot element's end tag may be omitted if the tfoot element + # is immediately followed by a tbody element, or if there is no + # more content in the parent element. + # XXX: we never omit the end tag when the following element is + # a tbody. See is_optional_start. + if type == "StartTag": + return next["name"] == 'tbody' + else: + return type == "EndTag" or type is None + elif tagname in ('td', 'th'): + # A td element's end tag may be omitted if the td element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + # A th element's end tag may be omitted if the th element is + # immediately followed by a td or th element, or if there is + # no more content in the parent element. + if type == "StartTag": + return next["name"] in ('td', 'th') + else: + return type == "EndTag" or type is None + return False diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py new file mode 100644 index 0000000..af8e77b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/sanitizer.py @@ -0,0 +1,896 @@ +from __future__ import absolute_import, division, unicode_literals + +import re +from xml.sax.saxutils import escape, unescape + +from pip._vendor.six.moves import urllib_parse as urlparse + +from . import base +from ..constants import namespaces, prefixes + +__all__ = ["Filter"] + + +allowed_elements = frozenset(( + (namespaces['html'], 'a'), + (namespaces['html'], 'abbr'), + (namespaces['html'], 'acronym'), + (namespaces['html'], 'address'), + (namespaces['html'], 'area'), + (namespaces['html'], 'article'), + (namespaces['html'], 'aside'), + (namespaces['html'], 'audio'), + (namespaces['html'], 'b'), + (namespaces['html'], 'big'), + (namespaces['html'], 'blockquote'), + (namespaces['html'], 'br'), + (namespaces['html'], 'button'), + (namespaces['html'], 'canvas'), + (namespaces['html'], 'caption'), + (namespaces['html'], 'center'), + (namespaces['html'], 'cite'), + (namespaces['html'], 'code'), + (namespaces['html'], 'col'), + (namespaces['html'], 'colgroup'), + (namespaces['html'], 'command'), + (namespaces['html'], 'datagrid'), + (namespaces['html'], 'datalist'), + (namespaces['html'], 'dd'), + (namespaces['html'], 'del'), + (namespaces['html'], 'details'), + (namespaces['html'], 'dfn'), + (namespaces['html'], 'dialog'), + (namespaces['html'], 'dir'), + (namespaces['html'], 'div'), + (namespaces['html'], 'dl'), + (namespaces['html'], 'dt'), + (namespaces['html'], 'em'), + (namespaces['html'], 'event-source'), + (namespaces['html'], 'fieldset'), + (namespaces['html'], 'figcaption'), + (namespaces['html'], 'figure'), + (namespaces['html'], 'footer'), + (namespaces['html'], 'font'), + (namespaces['html'], 'form'), + (namespaces['html'], 'header'), + (namespaces['html'], 'h1'), + (namespaces['html'], 'h2'), + (namespaces['html'], 'h3'), + (namespaces['html'], 'h4'), + (namespaces['html'], 'h5'), + (namespaces['html'], 'h6'), + (namespaces['html'], 'hr'), + (namespaces['html'], 'i'), + (namespaces['html'], 'img'), + (namespaces['html'], 'input'), + (namespaces['html'], 'ins'), + (namespaces['html'], 'keygen'), + (namespaces['html'], 'kbd'), + (namespaces['html'], 'label'), + (namespaces['html'], 'legend'), + (namespaces['html'], 'li'), + (namespaces['html'], 'm'), + (namespaces['html'], 'map'), + (namespaces['html'], 'menu'), + (namespaces['html'], 'meter'), + (namespaces['html'], 'multicol'), + (namespaces['html'], 'nav'), + (namespaces['html'], 'nextid'), + (namespaces['html'], 'ol'), + (namespaces['html'], 'output'), + (namespaces['html'], 'optgroup'), + (namespaces['html'], 'option'), + (namespaces['html'], 'p'), + (namespaces['html'], 'pre'), + (namespaces['html'], 'progress'), + (namespaces['html'], 'q'), + (namespaces['html'], 's'), + (namespaces['html'], 'samp'), + (namespaces['html'], 'section'), + (namespaces['html'], 'select'), + (namespaces['html'], 'small'), + (namespaces['html'], 'sound'), + (namespaces['html'], 'source'), + (namespaces['html'], 'spacer'), + (namespaces['html'], 'span'), + (namespaces['html'], 'strike'), + (namespaces['html'], 'strong'), + (namespaces['html'], 'sub'), + (namespaces['html'], 'sup'), + (namespaces['html'], 'table'), + (namespaces['html'], 'tbody'), + (namespaces['html'], 'td'), + (namespaces['html'], 'textarea'), + (namespaces['html'], 'time'), + (namespaces['html'], 'tfoot'), + (namespaces['html'], 'th'), + (namespaces['html'], 'thead'), + (namespaces['html'], 'tr'), + (namespaces['html'], 'tt'), + (namespaces['html'], 'u'), + (namespaces['html'], 'ul'), + (namespaces['html'], 'var'), + (namespaces['html'], 'video'), + (namespaces['mathml'], 'maction'), + (namespaces['mathml'], 'math'), + (namespaces['mathml'], 'merror'), + (namespaces['mathml'], 'mfrac'), + (namespaces['mathml'], 'mi'), + (namespaces['mathml'], 'mmultiscripts'), + (namespaces['mathml'], 'mn'), + (namespaces['mathml'], 'mo'), + (namespaces['mathml'], 'mover'), + (namespaces['mathml'], 'mpadded'), + (namespaces['mathml'], 'mphantom'), + (namespaces['mathml'], 'mprescripts'), + (namespaces['mathml'], 'mroot'), + (namespaces['mathml'], 'mrow'), + (namespaces['mathml'], 'mspace'), + (namespaces['mathml'], 'msqrt'), + (namespaces['mathml'], 'mstyle'), + (namespaces['mathml'], 'msub'), + (namespaces['mathml'], 'msubsup'), + (namespaces['mathml'], 'msup'), + (namespaces['mathml'], 'mtable'), + (namespaces['mathml'], 'mtd'), + (namespaces['mathml'], 'mtext'), + (namespaces['mathml'], 'mtr'), + (namespaces['mathml'], 'munder'), + (namespaces['mathml'], 'munderover'), + (namespaces['mathml'], 'none'), + (namespaces['svg'], 'a'), + (namespaces['svg'], 'animate'), + (namespaces['svg'], 'animateColor'), + (namespaces['svg'], 'animateMotion'), + (namespaces['svg'], 'animateTransform'), + (namespaces['svg'], 'clipPath'), + (namespaces['svg'], 'circle'), + (namespaces['svg'], 'defs'), + (namespaces['svg'], 'desc'), + (namespaces['svg'], 'ellipse'), + (namespaces['svg'], 'font-face'), + (namespaces['svg'], 'font-face-name'), + (namespaces['svg'], 'font-face-src'), + (namespaces['svg'], 'g'), + (namespaces['svg'], 'glyph'), + (namespaces['svg'], 'hkern'), + (namespaces['svg'], 'linearGradient'), + (namespaces['svg'], 'line'), + (namespaces['svg'], 'marker'), + (namespaces['svg'], 'metadata'), + (namespaces['svg'], 'missing-glyph'), + (namespaces['svg'], 'mpath'), + (namespaces['svg'], 'path'), + (namespaces['svg'], 'polygon'), + (namespaces['svg'], 'polyline'), + (namespaces['svg'], 'radialGradient'), + (namespaces['svg'], 'rect'), + (namespaces['svg'], 'set'), + (namespaces['svg'], 'stop'), + (namespaces['svg'], 'svg'), + (namespaces['svg'], 'switch'), + (namespaces['svg'], 'text'), + (namespaces['svg'], 'title'), + (namespaces['svg'], 'tspan'), + (namespaces['svg'], 'use'), +)) + +allowed_attributes = frozenset(( + # HTML attributes + (None, 'abbr'), + (None, 'accept'), + (None, 'accept-charset'), + (None, 'accesskey'), + (None, 'action'), + (None, 'align'), + (None, 'alt'), + (None, 'autocomplete'), + (None, 'autofocus'), + (None, 'axis'), + (None, 'background'), + (None, 'balance'), + (None, 'bgcolor'), + (None, 'bgproperties'), + (None, 'border'), + (None, 'bordercolor'), + (None, 'bordercolordark'), + (None, 'bordercolorlight'), + (None, 'bottompadding'), + (None, 'cellpadding'), + (None, 'cellspacing'), + (None, 'ch'), + (None, 'challenge'), + (None, 'char'), + (None, 'charoff'), + (None, 'choff'), + (None, 'charset'), + (None, 'checked'), + (None, 'cite'), + (None, 'class'), + (None, 'clear'), + (None, 'color'), + (None, 'cols'), + (None, 'colspan'), + (None, 'compact'), + (None, 'contenteditable'), + (None, 'controls'), + (None, 'coords'), + (None, 'data'), + (None, 'datafld'), + (None, 'datapagesize'), + (None, 'datasrc'), + (None, 'datetime'), + (None, 'default'), + (None, 'delay'), + (None, 'dir'), + (None, 'disabled'), + (None, 'draggable'), + (None, 'dynsrc'), + (None, 'enctype'), + (None, 'end'), + (None, 'face'), + (None, 'for'), + (None, 'form'), + (None, 'frame'), + (None, 'galleryimg'), + (None, 'gutter'), + (None, 'headers'), + (None, 'height'), + (None, 'hidefocus'), + (None, 'hidden'), + (None, 'high'), + (None, 'href'), + (None, 'hreflang'), + (None, 'hspace'), + (None, 'icon'), + (None, 'id'), + (None, 'inputmode'), + (None, 'ismap'), + (None, 'keytype'), + (None, 'label'), + (None, 'leftspacing'), + (None, 'lang'), + (None, 'list'), + (None, 'longdesc'), + (None, 'loop'), + (None, 'loopcount'), + (None, 'loopend'), + (None, 'loopstart'), + (None, 'low'), + (None, 'lowsrc'), + (None, 'max'), + (None, 'maxlength'), + (None, 'media'), + (None, 'method'), + (None, 'min'), + (None, 'multiple'), + (None, 'name'), + (None, 'nohref'), + (None, 'noshade'), + (None, 'nowrap'), + (None, 'open'), + (None, 'optimum'), + (None, 'pattern'), + (None, 'ping'), + (None, 'point-size'), + (None, 'poster'), + (None, 'pqg'), + (None, 'preload'), + (None, 'prompt'), + (None, 'radiogroup'), + (None, 'readonly'), + (None, 'rel'), + (None, 'repeat-max'), + (None, 'repeat-min'), + (None, 'replace'), + (None, 'required'), + (None, 'rev'), + (None, 'rightspacing'), + (None, 'rows'), + (None, 'rowspan'), + (None, 'rules'), + (None, 'scope'), + (None, 'selected'), + (None, 'shape'), + (None, 'size'), + (None, 'span'), + (None, 'src'), + (None, 'start'), + (None, 'step'), + (None, 'style'), + (None, 'summary'), + (None, 'suppress'), + (None, 'tabindex'), + (None, 'target'), + (None, 'template'), + (None, 'title'), + (None, 'toppadding'), + (None, 'type'), + (None, 'unselectable'), + (None, 'usemap'), + (None, 'urn'), + (None, 'valign'), + (None, 'value'), + (None, 'variable'), + (None, 'volume'), + (None, 'vspace'), + (None, 'vrml'), + (None, 'width'), + (None, 'wrap'), + (namespaces['xml'], 'lang'), + # MathML attributes + (None, 'actiontype'), + (None, 'align'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnalign'), + (None, 'columnlines'), + (None, 'columnspacing'), + (None, 'columnspan'), + (None, 'depth'), + (None, 'display'), + (None, 'displaystyle'), + (None, 'equalcolumns'), + (None, 'equalrows'), + (None, 'fence'), + (None, 'fontstyle'), + (None, 'fontweight'), + (None, 'frame'), + (None, 'height'), + (None, 'linethickness'), + (None, 'lspace'), + (None, 'mathbackground'), + (None, 'mathcolor'), + (None, 'mathvariant'), + (None, 'mathvariant'), + (None, 'maxsize'), + (None, 'minsize'), + (None, 'other'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowalign'), + (None, 'rowlines'), + (None, 'rowspacing'), + (None, 'rowspan'), + (None, 'rspace'), + (None, 'scriptlevel'), + (None, 'selection'), + (None, 'separator'), + (None, 'stretchy'), + (None, 'width'), + (None, 'width'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'type'), + # SVG attributes + (None, 'accent-height'), + (None, 'accumulate'), + (None, 'additive'), + (None, 'alphabetic'), + (None, 'arabic-form'), + (None, 'ascent'), + (None, 'attributeName'), + (None, 'attributeType'), + (None, 'baseProfile'), + (None, 'bbox'), + (None, 'begin'), + (None, 'by'), + (None, 'calcMode'), + (None, 'cap-height'), + (None, 'class'), + (None, 'clip-path'), + (None, 'color'), + (None, 'color-rendering'), + (None, 'content'), + (None, 'cx'), + (None, 'cy'), + (None, 'd'), + (None, 'dx'), + (None, 'dy'), + (None, 'descent'), + (None, 'display'), + (None, 'dur'), + (None, 'end'), + (None, 'fill'), + (None, 'fill-opacity'), + (None, 'fill-rule'), + (None, 'font-family'), + (None, 'font-size'), + (None, 'font-stretch'), + (None, 'font-style'), + (None, 'font-variant'), + (None, 'font-weight'), + (None, 'from'), + (None, 'fx'), + (None, 'fy'), + (None, 'g1'), + (None, 'g2'), + (None, 'glyph-name'), + (None, 'gradientUnits'), + (None, 'hanging'), + (None, 'height'), + (None, 'horiz-adv-x'), + (None, 'horiz-origin-x'), + (None, 'id'), + (None, 'ideographic'), + (None, 'k'), + (None, 'keyPoints'), + (None, 'keySplines'), + (None, 'keyTimes'), + (None, 'lang'), + (None, 'marker-end'), + (None, 'marker-mid'), + (None, 'marker-start'), + (None, 'markerHeight'), + (None, 'markerUnits'), + (None, 'markerWidth'), + (None, 'mathematical'), + (None, 'max'), + (None, 'min'), + (None, 'name'), + (None, 'offset'), + (None, 'opacity'), + (None, 'orient'), + (None, 'origin'), + (None, 'overline-position'), + (None, 'overline-thickness'), + (None, 'panose-1'), + (None, 'path'), + (None, 'pathLength'), + (None, 'points'), + (None, 'preserveAspectRatio'), + (None, 'r'), + (None, 'refX'), + (None, 'refY'), + (None, 'repeatCount'), + (None, 'repeatDur'), + (None, 'requiredExtensions'), + (None, 'requiredFeatures'), + (None, 'restart'), + (None, 'rotate'), + (None, 'rx'), + (None, 'ry'), + (None, 'slope'), + (None, 'stemh'), + (None, 'stemv'), + (None, 'stop-color'), + (None, 'stop-opacity'), + (None, 'strikethrough-position'), + (None, 'strikethrough-thickness'), + (None, 'stroke'), + (None, 'stroke-dasharray'), + (None, 'stroke-dashoffset'), + (None, 'stroke-linecap'), + (None, 'stroke-linejoin'), + (None, 'stroke-miterlimit'), + (None, 'stroke-opacity'), + (None, 'stroke-width'), + (None, 'systemLanguage'), + (None, 'target'), + (None, 'text-anchor'), + (None, 'to'), + (None, 'transform'), + (None, 'type'), + (None, 'u1'), + (None, 'u2'), + (None, 'underline-position'), + (None, 'underline-thickness'), + (None, 'unicode'), + (None, 'unicode-range'), + (None, 'units-per-em'), + (None, 'values'), + (None, 'version'), + (None, 'viewBox'), + (None, 'visibility'), + (None, 'width'), + (None, 'widths'), + (None, 'x'), + (None, 'x-height'), + (None, 'x1'), + (None, 'x2'), + (namespaces['xlink'], 'actuate'), + (namespaces['xlink'], 'arcrole'), + (namespaces['xlink'], 'href'), + (namespaces['xlink'], 'role'), + (namespaces['xlink'], 'show'), + (namespaces['xlink'], 'title'), + (namespaces['xlink'], 'type'), + (namespaces['xml'], 'base'), + (namespaces['xml'], 'lang'), + (namespaces['xml'], 'space'), + (None, 'y'), + (None, 'y1'), + (None, 'y2'), + (None, 'zoomAndPan'), +)) + +attr_val_is_uri = frozenset(( + (None, 'href'), + (None, 'src'), + (None, 'cite'), + (None, 'action'), + (None, 'longdesc'), + (None, 'poster'), + (None, 'background'), + (None, 'datasrc'), + (None, 'dynsrc'), + (None, 'lowsrc'), + (None, 'ping'), + (namespaces['xlink'], 'href'), + (namespaces['xml'], 'base'), +)) + +svg_attr_val_allows_ref = frozenset(( + (None, 'clip-path'), + (None, 'color-profile'), + (None, 'cursor'), + (None, 'fill'), + (None, 'filter'), + (None, 'marker'), + (None, 'marker-start'), + (None, 'marker-mid'), + (None, 'marker-end'), + (None, 'mask'), + (None, 'stroke'), +)) + +svg_allow_local_href = frozenset(( + (None, 'altGlyph'), + (None, 'animate'), + (None, 'animateColor'), + (None, 'animateMotion'), + (None, 'animateTransform'), + (None, 'cursor'), + (None, 'feImage'), + (None, 'filter'), + (None, 'linearGradient'), + (None, 'pattern'), + (None, 'radialGradient'), + (None, 'textpath'), + (None, 'tref'), + (None, 'set'), + (None, 'use') +)) + +allowed_css_properties = frozenset(( + 'azimuth', + 'background-color', + 'border-bottom-color', + 'border-collapse', + 'border-color', + 'border-left-color', + 'border-right-color', + 'border-top-color', + 'clear', + 'color', + 'cursor', + 'direction', + 'display', + 'elevation', + 'float', + 'font', + 'font-family', + 'font-size', + 'font-style', + 'font-variant', + 'font-weight', + 'height', + 'letter-spacing', + 'line-height', + 'overflow', + 'pause', + 'pause-after', + 'pause-before', + 'pitch', + 'pitch-range', + 'richness', + 'speak', + 'speak-header', + 'speak-numeral', + 'speak-punctuation', + 'speech-rate', + 'stress', + 'text-align', + 'text-decoration', + 'text-indent', + 'unicode-bidi', + 'vertical-align', + 'voice-family', + 'volume', + 'white-space', + 'width', +)) + +allowed_css_keywords = frozenset(( + 'auto', + 'aqua', + 'black', + 'block', + 'blue', + 'bold', + 'both', + 'bottom', + 'brown', + 'center', + 'collapse', + 'dashed', + 'dotted', + 'fuchsia', + 'gray', + 'green', + '!important', + 'italic', + 'left', + 'lime', + 'maroon', + 'medium', + 'none', + 'navy', + 'normal', + 'nowrap', + 'olive', + 'pointer', + 'purple', + 'red', + 'right', + 'solid', + 'silver', + 'teal', + 'top', + 'transparent', + 'underline', + 'white', + 'yellow', +)) + +allowed_svg_properties = frozenset(( + 'fill', + 'fill-opacity', + 'fill-rule', + 'stroke', + 'stroke-width', + 'stroke-linecap', + 'stroke-linejoin', + 'stroke-opacity', +)) + +allowed_protocols = frozenset(( + 'ed2k', + 'ftp', + 'http', + 'https', + 'irc', + 'mailto', + 'news', + 'gopher', + 'nntp', + 'telnet', + 'webcal', + 'xmpp', + 'callto', + 'feed', + 'urn', + 'aim', + 'rsync', + 'tag', + 'ssh', + 'sftp', + 'rtsp', + 'afs', + 'data', +)) + +allowed_content_types = frozenset(( + 'image/png', + 'image/jpeg', + 'image/gif', + 'image/webp', + 'image/bmp', + 'text/plain', +)) + + +data_content_type = re.compile(r''' + ^ + # Match a content type <application>/<type> + (?P<content_type>[-a-zA-Z0-9.]+/[-a-zA-Z0-9.]+) + # Match any character set and encoding + (?:(?:;charset=(?:[-a-zA-Z0-9]+)(?:;(?:base64))?) + |(?:;(?:base64))?(?:;charset=(?:[-a-zA-Z0-9]+))?) + # Assume the rest is data + ,.* + $ + ''', + re.VERBOSE) + + +class Filter(base.Filter): + """Sanitizes token stream of XHTML+MathML+SVG and of inline style attributes""" + def __init__(self, + source, + allowed_elements=allowed_elements, + allowed_attributes=allowed_attributes, + allowed_css_properties=allowed_css_properties, + allowed_css_keywords=allowed_css_keywords, + allowed_svg_properties=allowed_svg_properties, + allowed_protocols=allowed_protocols, + allowed_content_types=allowed_content_types, + attr_val_is_uri=attr_val_is_uri, + svg_attr_val_allows_ref=svg_attr_val_allows_ref, + svg_allow_local_href=svg_allow_local_href): + """Creates a Filter + + :arg allowed_elements: set of elements to allow--everything else will + be escaped + + :arg allowed_attributes: set of attributes to allow in + elements--everything else will be stripped + + :arg allowed_css_properties: set of CSS properties to allow--everything + else will be stripped + + :arg allowed_css_keywords: set of CSS keywords to allow--everything + else will be stripped + + :arg allowed_svg_properties: set of SVG properties to allow--everything + else will be removed + + :arg allowed_protocols: set of allowed protocols for URIs + + :arg allowed_content_types: set of allowed content types for ``data`` URIs. + + :arg attr_val_is_uri: set of attributes that have URI values--values + that have a scheme not listed in ``allowed_protocols`` are removed + + :arg svg_attr_val_allows_ref: set of SVG attributes that can have + references + + :arg svg_allow_local_href: set of SVG elements that can have local + hrefs--these are removed + + """ + super(Filter, self).__init__(source) + self.allowed_elements = allowed_elements + self.allowed_attributes = allowed_attributes + self.allowed_css_properties = allowed_css_properties + self.allowed_css_keywords = allowed_css_keywords + self.allowed_svg_properties = allowed_svg_properties + self.allowed_protocols = allowed_protocols + self.allowed_content_types = allowed_content_types + self.attr_val_is_uri = attr_val_is_uri + self.svg_attr_val_allows_ref = svg_attr_val_allows_ref + self.svg_allow_local_href = svg_allow_local_href + + def __iter__(self): + for token in base.Filter.__iter__(self): + token = self.sanitize_token(token) + if token: + yield token + + # Sanitize the +html+, escaping all elements not in ALLOWED_ELEMENTS, and + # stripping out all attributes not in ALLOWED_ATTRIBUTES. Style attributes + # are parsed, and a restricted set, specified by ALLOWED_CSS_PROPERTIES and + # ALLOWED_CSS_KEYWORDS, are allowed through. attributes in ATTR_VAL_IS_URI + # are scanned, and only URI schemes specified in ALLOWED_PROTOCOLS are + # allowed. + # + # sanitize_html('<script> do_nasty_stuff() </script>') + # => <script> do_nasty_stuff() </script> + # sanitize_html('<a href="javascript: sucker();">Click here for $100</a>') + # => <a>Click here for $100</a> + def sanitize_token(self, token): + + # accommodate filters which use token_type differently + token_type = token["type"] + if token_type in ("StartTag", "EndTag", "EmptyTag"): + name = token["name"] + namespace = token["namespace"] + if ((namespace, name) in self.allowed_elements or + (namespace is None and + (namespaces["html"], name) in self.allowed_elements)): + return self.allowed_token(token) + else: + return self.disallowed_token(token) + elif token_type == "Comment": + pass + else: + return token + + def allowed_token(self, token): + if "data" in token: + attrs = token["data"] + attr_names = set(attrs.keys()) + + # Remove forbidden attributes + for to_remove in (attr_names - self.allowed_attributes): + del token["data"][to_remove] + attr_names.remove(to_remove) + + # Remove attributes with disallowed URL values + for attr in (attr_names & self.attr_val_is_uri): + assert attr in attrs + # I don't have a clue where this regexp comes from or why it matches those + # characters, nor why we call unescape. I just know it's always been here. + # Should you be worried by this comment in a sanitizer? Yes. On the other hand, all + # this will do is remove *more* than it otherwise would. + val_unescaped = re.sub("[`\x00-\x20\x7f-\xa0\\s]+", '', + unescape(attrs[attr])).lower() + # remove replacement characters from unescaped characters + val_unescaped = val_unescaped.replace("\ufffd", "") + try: + uri = urlparse.urlparse(val_unescaped) + except ValueError: + uri = None + del attrs[attr] + if uri and uri.scheme: + if uri.scheme not in self.allowed_protocols: + del attrs[attr] + if uri.scheme == 'data': + m = data_content_type.match(uri.path) + if not m: + del attrs[attr] + elif m.group('content_type') not in self.allowed_content_types: + del attrs[attr] + + for attr in self.svg_attr_val_allows_ref: + if attr in attrs: + attrs[attr] = re.sub(r'url\s*\(\s*[^#\s][^)]+?\)', + ' ', + unescape(attrs[attr])) + if (token["name"] in self.svg_allow_local_href and + (namespaces['xlink'], 'href') in attrs and re.search(r'^\s*[^#\s].*', + attrs[(namespaces['xlink'], 'href')])): + del attrs[(namespaces['xlink'], 'href')] + if (None, 'style') in attrs: + attrs[(None, 'style')] = self.sanitize_css(attrs[(None, 'style')]) + token["data"] = attrs + return token + + def disallowed_token(self, token): + token_type = token["type"] + if token_type == "EndTag": + token["data"] = "</%s>" % token["name"] + elif token["data"]: + assert token_type in ("StartTag", "EmptyTag") + attrs = [] + for (ns, name), v in token["data"].items(): + attrs.append(' %s="%s"' % (name if ns is None else "%s:%s" % (prefixes[ns], name), escape(v))) + token["data"] = "<%s%s>" % (token["name"], ''.join(attrs)) + else: + token["data"] = "<%s>" % token["name"] + if token.get("selfClosing"): + token["data"] = token["data"][:-1] + "/>" + + token["type"] = "Characters" + + del token["name"] + return token + + def sanitize_css(self, style): + # disallow urls + style = re.compile(r'url\s*\(\s*[^\s)]+?\s*\)\s*').sub(' ', style) + + # gauntlet + if not re.match(r"""^([:,;#%.\sa-zA-Z0-9!]|\w-\w|'[\s\w]+'|"[\s\w]+"|\([\d,\s]+\))*$""", style): + return '' + if not re.match(r"^\s*([-\w]+\s*:[^:;]*(;\s*|$))*$", style): + return '' + + clean = [] + for prop, value in re.findall(r"([-\w]+)\s*:\s*([^:;]*)", style): + if not value: + continue + if prop.lower() in self.allowed_css_properties: + clean.append(prop + ': ' + value + ';') + elif prop.split('-')[0].lower() in ['background', 'border', 'margin', + 'padding']: + for keyword in value.split(): + if keyword not in self.allowed_css_keywords and \ + not re.match(r"^(#[0-9a-fA-F]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$", keyword): # noqa + break + else: + clean.append(prop + ': ' + value + ';') + elif prop.lower() in self.allowed_svg_properties: + clean.append(prop + ': ' + value + ';') + + return ' '.join(clean) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py new file mode 100644 index 0000000..0d12584 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/filters/whitespace.py @@ -0,0 +1,38 @@ +from __future__ import absolute_import, division, unicode_literals + +import re + +from . import base +from ..constants import rcdataElements, spaceCharacters +spaceCharacters = "".join(spaceCharacters) + +SPACES_REGEX = re.compile("[%s]+" % spaceCharacters) + + +class Filter(base.Filter): + """Collapses whitespace except in pre, textarea, and script elements""" + spacePreserveElements = frozenset(["pre", "textarea"] + list(rcdataElements)) + + def __iter__(self): + preserve = 0 + for token in base.Filter.__iter__(self): + type = token["type"] + if type == "StartTag" \ + and (preserve or token["name"] in self.spacePreserveElements): + preserve += 1 + + elif type == "EndTag" and preserve: + preserve -= 1 + + elif not preserve and type == "SpaceCharacters" and token["data"]: + # Test on token["data"] above to not introduce spaces where there were not + token["data"] = " " + + elif not preserve and type == "Characters": + token["data"] = collapse_spaces(token["data"]) + + yield token + + +def collapse_spaces(text): + return SPACES_REGEX.sub(' ', text) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py new file mode 100644 index 0000000..ae41a13 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/html5parser.py @@ -0,0 +1,2791 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import with_metaclass, viewkeys + +import types +from collections import OrderedDict + +from . import _inputstream +from . import _tokenizer + +from . import treebuilders +from .treebuilders.base import Marker + +from . import _utils +from .constants import ( + spaceCharacters, asciiUpper2Lower, + specialElements, headingElements, cdataElements, rcdataElements, + tokenTypes, tagTokenTypes, + namespaces, + htmlIntegrationPointElements, mathmlTextIntegrationPointElements, + adjustForeignAttributes as adjustForeignAttributesMap, + adjustMathMLAttributes, adjustSVGAttributes, + E, + _ReparseException +) + + +def parse(doc, treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML document as a string or file-like object into a tree + + :arg doc: the document to parse as a string or file-like object + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import parse + >>> parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parse(doc, **kwargs) + + +def parseFragment(doc, container="div", treebuilder="etree", namespaceHTMLElements=True, **kwargs): + """Parse an HTML fragment as a string or file-like object into a tree + + :arg doc: the fragment to parse as a string or file-like object + + :arg container: the container context to parse the fragment in + + :arg treebuilder: the treebuilder to use when parsing + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import parseFragment + >>> parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + tb = treebuilders.getTreeBuilder(treebuilder) + p = HTMLParser(tb, namespaceHTMLElements=namespaceHTMLElements) + return p.parseFragment(doc, container=container, **kwargs) + + +def method_decorator_metaclass(function): + class Decorated(type): + def __new__(meta, classname, bases, classDict): + for attributeName, attribute in classDict.items(): + if isinstance(attribute, types.FunctionType): + attribute = function(attribute) + + classDict[attributeName] = attribute + return type.__new__(meta, classname, bases, classDict) + return Decorated + + +class HTMLParser(object): + """HTML parser + + Generates a tree structure from a stream of (possibly malformed) HTML. + + """ + + def __init__(self, tree=None, strict=False, namespaceHTMLElements=True, debug=False): + """ + :arg tree: a treebuilder class controlling the type of tree that will be + returned. Built in treebuilders can be accessed through + html5lib.treebuilders.getTreeBuilder(treeType) + + :arg strict: raise an exception when a parse error is encountered + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + :arg debug: whether or not to enable debug mode which logs things + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() # generates parser with etree builder + >>> parser = HTMLParser('lxml', strict=True) # generates parser with lxml builder which is strict + + """ + + # Raise an exception on the first error encountered + self.strict = strict + + if tree is None: + tree = treebuilders.getTreeBuilder("etree") + self.tree = tree(namespaceHTMLElements) + self.errors = [] + + self.phases = dict([(name, cls(self, self.tree)) for name, cls in + getPhases(debug).items()]) + + def _parse(self, stream, innerHTML=False, container="div", scripting=False, **kwargs): + + self.innerHTMLMode = innerHTML + self.container = container + self.scripting = scripting + self.tokenizer = _tokenizer.HTMLTokenizer(stream, parser=self, **kwargs) + self.reset() + + try: + self.mainLoop() + except _ReparseException: + self.reset() + self.mainLoop() + + def reset(self): + self.tree.reset() + self.firstStartTag = False + self.errors = [] + self.log = [] # only used with debug mode + # "quirks" / "limited quirks" / "no quirks" + self.compatMode = "no quirks" + + if self.innerHTMLMode: + self.innerHTML = self.container.lower() + + if self.innerHTML in cdataElements: + self.tokenizer.state = self.tokenizer.rcdataState + elif self.innerHTML in rcdataElements: + self.tokenizer.state = self.tokenizer.rawtextState + elif self.innerHTML == 'plaintext': + self.tokenizer.state = self.tokenizer.plaintextState + else: + # state already is data state + # self.tokenizer.state = self.tokenizer.dataState + pass + self.phase = self.phases["beforeHtml"] + self.phase.insertHtmlElement() + self.resetInsertionMode() + else: + self.innerHTML = False # pylint:disable=redefined-variable-type + self.phase = self.phases["initial"] + + self.lastPhase = None + + self.beforeRCDataPhase = None + + self.framesetOK = True + + @property + def documentEncoding(self): + """Name of the character encoding that was used to decode the input stream, or + :obj:`None` if that is not determined yet + + """ + if not hasattr(self, 'tokenizer'): + return None + return self.tokenizer.stream.charEncoding[0].name + + def isHTMLIntegrationPoint(self, element): + if (element.name == "annotation-xml" and + element.namespace == namespaces["mathml"]): + return ("encoding" in element.attributes and + element.attributes["encoding"].translate( + asciiUpper2Lower) in + ("text/html", "application/xhtml+xml")) + else: + return (element.namespace, element.name) in htmlIntegrationPointElements + + def isMathMLTextIntegrationPoint(self, element): + return (element.namespace, element.name) in mathmlTextIntegrationPointElements + + def mainLoop(self): + CharactersToken = tokenTypes["Characters"] + SpaceCharactersToken = tokenTypes["SpaceCharacters"] + StartTagToken = tokenTypes["StartTag"] + EndTagToken = tokenTypes["EndTag"] + CommentToken = tokenTypes["Comment"] + DoctypeToken = tokenTypes["Doctype"] + ParseErrorToken = tokenTypes["ParseError"] + + for token in self.normalizedTokens(): + prev_token = None + new_token = token + while new_token is not None: + prev_token = new_token + currentNode = self.tree.openElements[-1] if self.tree.openElements else None + currentNodeNamespace = currentNode.namespace if currentNode else None + currentNodeName = currentNode.name if currentNode else None + + type = new_token["type"] + + if type == ParseErrorToken: + self.parseError(new_token["data"], new_token.get("datavars", {})) + new_token = None + else: + if (len(self.tree.openElements) == 0 or + currentNodeNamespace == self.tree.defaultNamespace or + (self.isMathMLTextIntegrationPoint(currentNode) and + ((type == StartTagToken and + token["name"] not in frozenset(["mglyph", "malignmark"])) or + type in (CharactersToken, SpaceCharactersToken))) or + (currentNodeNamespace == namespaces["mathml"] and + currentNodeName == "annotation-xml" and + type == StartTagToken and + token["name"] == "svg") or + (self.isHTMLIntegrationPoint(currentNode) and + type in (StartTagToken, CharactersToken, SpaceCharactersToken))): + phase = self.phase + else: + phase = self.phases["inForeignContent"] + + if type == CharactersToken: + new_token = phase.processCharacters(new_token) + elif type == SpaceCharactersToken: + new_token = phase.processSpaceCharacters(new_token) + elif type == StartTagToken: + new_token = phase.processStartTag(new_token) + elif type == EndTagToken: + new_token = phase.processEndTag(new_token) + elif type == CommentToken: + new_token = phase.processComment(new_token) + elif type == DoctypeToken: + new_token = phase.processDoctype(new_token) + + if (type == StartTagToken and prev_token["selfClosing"] and + not prev_token["selfClosingAcknowledged"]): + self.parseError("non-void-element-with-trailing-solidus", + {"name": prev_token["name"]}) + + # When the loop finishes it's EOF + reprocess = True + phases = [] + while reprocess: + phases.append(self.phase) + reprocess = self.phase.processEOF() + if reprocess: + assert self.phase not in phases + + def normalizedTokens(self): + for token in self.tokenizer: + yield self.normalizeToken(token) + + def parse(self, stream, *args, **kwargs): + """Parse a HTML document into a well-formed tree + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element). + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5parser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parse('<html><body><p>This is a doc</p></body></html>') + <Element u'{http://www.w3.org/1999/xhtml}html' at 0x7feac4909db0> + + """ + self._parse(stream, False, None, *args, **kwargs) + return self.tree.getDocument() + + def parseFragment(self, stream, *args, **kwargs): + """Parse a HTML fragment into a well-formed tree fragment + + :arg container: name of the element we're setting the innerHTML + property if set to None, default to 'div' + + :arg stream: a file-like object or string containing the HTML to be parsed + + The optional encoding parameter must be a string that indicates + the encoding. If specified, that encoding will be used, + regardless of any BOM or later declaration (such as in a meta + element) + + :arg scripting: treat noscript elements as if JavaScript was turned on + + :returns: parsed tree + + Example: + + >>> from html5lib.html5libparser import HTMLParser + >>> parser = HTMLParser() + >>> parser.parseFragment('<b>this is a fragment</b>') + <Element u'DOCUMENT_FRAGMENT' at 0x7feac484b090> + + """ + self._parse(stream, True, *args, **kwargs) + return self.tree.getFragment() + + def parseError(self, errorcode="XXX-undefined-error", datavars=None): + # XXX The idea is to make errorcode mandatory. + if datavars is None: + datavars = {} + self.errors.append((self.tokenizer.stream.position(), errorcode, datavars)) + if self.strict: + raise ParseError(E[errorcode] % datavars) + + def normalizeToken(self, token): + # HTML5 specific normalizations to the token stream + if token["type"] == tokenTypes["StartTag"]: + raw = token["data"] + token["data"] = OrderedDict(raw) + if len(raw) > len(token["data"]): + # we had some duplicated attribute, fix so first wins + token["data"].update(raw[::-1]) + + return token + + def adjustMathMLAttributes(self, token): + adjust_attributes(token, adjustMathMLAttributes) + + def adjustSVGAttributes(self, token): + adjust_attributes(token, adjustSVGAttributes) + + def adjustForeignAttributes(self, token): + adjust_attributes(token, adjustForeignAttributesMap) + + def reparseTokenNormal(self, token): + # pylint:disable=unused-argument + self.parser.phase() + + def resetInsertionMode(self): + # The name of this method is mostly historical. (It's also used in the + # specification.) + last = False + newModes = { + "select": "inSelect", + "td": "inCell", + "th": "inCell", + "tr": "inRow", + "tbody": "inTableBody", + "thead": "inTableBody", + "tfoot": "inTableBody", + "caption": "inCaption", + "colgroup": "inColumnGroup", + "table": "inTable", + "head": "inBody", + "body": "inBody", + "frameset": "inFrameset", + "html": "beforeHead" + } + for node in self.tree.openElements[::-1]: + nodeName = node.name + new_phase = None + if node == self.tree.openElements[0]: + assert self.innerHTML + last = True + nodeName = self.innerHTML + # Check for conditions that should only happen in the innerHTML + # case + if nodeName in ("select", "colgroup", "head", "html"): + assert self.innerHTML + + if not last and node.namespace != self.tree.defaultNamespace: + continue + + if nodeName in newModes: + new_phase = self.phases[newModes[nodeName]] + break + elif last: + new_phase = self.phases["inBody"] + break + + self.phase = new_phase + + def parseRCDataRawtext(self, token, contentType): + # Generic RCDATA/RAWTEXT Parsing algorithm + assert contentType in ("RAWTEXT", "RCDATA") + + self.tree.insertElement(token) + + if contentType == "RAWTEXT": + self.tokenizer.state = self.tokenizer.rawtextState + else: + self.tokenizer.state = self.tokenizer.rcdataState + + self.originalPhase = self.phase + + self.phase = self.phases["text"] + + +@_utils.memoize +def getPhases(debug): + def log(function): + """Logger that records which phase processes each token""" + type_names = dict((value, key) for key, value in + tokenTypes.items()) + + def wrapped(self, *args, **kwargs): + if function.__name__.startswith("process") and len(args) > 0: + token = args[0] + try: + info = {"type": type_names[token['type']]} + except: + raise + if token['type'] in tagTokenTypes: + info["name"] = token['name'] + + self.parser.log.append((self.parser.tokenizer.state.__name__, + self.parser.phase.__class__.__name__, + self.__class__.__name__, + function.__name__, + info)) + return function(self, *args, **kwargs) + else: + return function(self, *args, **kwargs) + return wrapped + + def getMetaclass(use_metaclass, metaclass_func): + if use_metaclass: + return method_decorator_metaclass(metaclass_func) + else: + return type + + # pylint:disable=unused-argument + class Phase(with_metaclass(getMetaclass(debug, log))): + """Base class for helper object that implements each phase of processing + """ + + def __init__(self, parser, tree): + self.parser = parser + self.tree = tree + + def processEOF(self): + raise NotImplementedError + + def processComment(self, token): + # For most phases the following is correct. Where it's not it will be + # overridden. + self.tree.insertComment(token, self.tree.openElements[-1]) + + def processDoctype(self, token): + self.parser.parseError("unexpected-doctype") + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processSpaceCharacters(self, token): + self.tree.insertText(token["data"]) + + def processStartTag(self, token): + return self.startTagHandler[token["name"]](token) + + def startTagHtml(self, token): + if not self.parser.firstStartTag and token["name"] == "html": + self.parser.parseError("non-html-root") + # XXX Need a check here to see if the first start tag token emitted is + # this token... If it's not, invoke self.parser.parseError(). + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[0].attributes: + self.tree.openElements[0].attributes[attr] = value + self.parser.firstStartTag = False + + def processEndTag(self, token): + return self.endTagHandler[token["name"]](token) + + class InitialPhase(Phase): + def processSpaceCharacters(self, token): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + correct = token["correct"] + + if (name != "html" or publicId is not None or + systemId is not None and systemId != "about:legacy-compat"): + self.parser.parseError("unknown-doctype") + + if publicId is None: + publicId = "" + + self.tree.insertDoctype(token) + + if publicId != "": + publicId = publicId.translate(asciiUpper2Lower) + + if (not correct or token["name"] != "html" or + publicId.startswith( + ("+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//", + "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//")) or + publicId in ("-//w3o//dtd w3 html strict 3.0//en//", + "-/w3c/dtd html 4.0 transitional/en", + "html") or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is None or + systemId and systemId.lower() == "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd"): + self.parser.compatMode = "quirks" + elif (publicId.startswith( + ("-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//")) or + publicId.startswith( + ("-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//")) and + systemId is not None): + self.parser.compatMode = "limited quirks" + + self.parser.phase = self.parser.phases["beforeHtml"] + + def anythingElse(self): + self.parser.compatMode = "quirks" + self.parser.phase = self.parser.phases["beforeHtml"] + + def processCharacters(self, token): + self.parser.parseError("expected-doctype-but-got-chars") + self.anythingElse() + return token + + def processStartTag(self, token): + self.parser.parseError("expected-doctype-but-got-start-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEndTag(self, token): + self.parser.parseError("expected-doctype-but-got-end-tag", + {"name": token["name"]}) + self.anythingElse() + return token + + def processEOF(self): + self.parser.parseError("expected-doctype-but-got-eof") + self.anythingElse() + return True + + class BeforeHtmlPhase(Phase): + # helper methods + def insertHtmlElement(self): + self.tree.insertRoot(impliedTagToken("html", "StartTag")) + self.parser.phase = self.parser.phases["beforeHead"] + + # other + def processEOF(self): + self.insertHtmlElement() + return True + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.insertHtmlElement() + return token + + def processStartTag(self, token): + if token["name"] == "html": + self.parser.firstStartTag = True + self.insertHtmlElement() + return token + + def processEndTag(self, token): + if token["name"] not in ("head", "body", "html", "br"): + self.parser.parseError("unexpected-end-tag-before-html", + {"name": token["name"]}) + else: + self.insertHtmlElement() + return token + + class BeforeHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("head", "body", "html", "br"), self.endTagImplyHead) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.startTagHead(impliedTagToken("head", "StartTag")) + return True + + def processSpaceCharacters(self, token): + pass + + def processCharacters(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.tree.insertElement(token) + self.tree.headPointer = self.tree.openElements[-1] + self.parser.phase = self.parser.phases["inHead"] + + def startTagOther(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagImplyHead(self, token): + self.startTagHead(impliedTagToken("head", "StartTag")) + return token + + def endTagOther(self, token): + self.parser.parseError("end-tag-after-implied-root", + {"name": token["name"]}) + + class InHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("title", self.startTagTitle), + (("noframes", "style"), self.startTagNoFramesStyle), + ("noscript", self.startTagNoscript), + ("script", self.startTagScript), + (("base", "basefont", "bgsound", "command", "link"), + self.startTagBaseLinkCommand), + ("meta", self.startTagMeta), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("head", self.endTagHead), + (("br", "html", "body"), self.endTagHtmlBodyBr) + ]) + self.endTagHandler.default = self.endTagOther + + # the real thing + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagHead(self, token): + self.parser.parseError("two-heads-are-not-better-than-one") + + def startTagBaseLinkCommand(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMeta(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + attributes = token["data"] + if self.parser.tokenizer.stream.charEncoding[1] == "tentative": + if "charset" in attributes: + self.parser.tokenizer.stream.changeEncoding(attributes["charset"]) + elif ("content" in attributes and + "http-equiv" in attributes and + attributes["http-equiv"].lower() == "content-type"): + # Encoding it as UTF-8 here is a hack, as really we should pass + # the abstract Unicode string, and just use the + # ContentAttrParser on that, but using UTF-8 allows all chars + # to be encoded and as a ASCII-superset works. + data = _inputstream.EncodingBytes(attributes["content"].encode("utf-8")) + parser = _inputstream.ContentAttrParser(data) + codec = parser.parse() + self.parser.tokenizer.stream.changeEncoding(codec) + + def startTagTitle(self, token): + self.parser.parseRCDataRawtext(token, "RCDATA") + + def startTagNoFramesStyle(self, token): + # Need to decide whether to implement the scripting-disabled case + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagNoscript(self, token): + if self.parser.scripting: + self.parser.parseRCDataRawtext(token, "RAWTEXT") + else: + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inHeadNoscript"] + + def startTagScript(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.scriptDataState + self.parser.originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["text"] + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHead(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "head", "Expected head got %s" % node.name + self.parser.phase = self.parser.phases["afterHead"] + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.endTagHead(impliedTagToken("head")) + + class InHeadNoscriptPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("basefont", "bgsound", "link", "meta", "noframes", "style"), self.startTagBaseLinkCommand), + (("head", "noscript"), self.startTagHeadNoscript), + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("noscript", self.endTagNoscript), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.parseError("eof-in-head-noscript") + self.anythingElse() + return True + + def processComment(self, token): + return self.parser.phases["inHead"].processComment(token) + + def processCharacters(self, token): + self.parser.parseError("char-in-head-noscript") + self.anythingElse() + return token + + def processSpaceCharacters(self, token): + return self.parser.phases["inHead"].processSpaceCharacters(token) + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBaseLinkCommand(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagHeadNoscript(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagNoscript(self, token): + node = self.parser.tree.openElements.pop() + assert node.name == "noscript", "Expected noscript got %s" % node.name + self.parser.phase = self.parser.phases["inHead"] + + def endTagBr(self, token): + self.parser.parseError("unexpected-inhead-noscript-tag", {"name": token["name"]}) + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + # Caller must raise parse error first! + self.endTagNoscript(impliedTagToken("noscript")) + + class AfterHeadPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("base", "basefont", "bgsound", "link", "meta", "noframes", "script", + "style", "title"), + self.startTagFromHead), + ("head", self.startTagHead) + ]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([(("body", "html", "br"), + self.endTagHtmlBodyBr)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.anythingElse() + return True + + def processCharacters(self, token): + self.anythingElse() + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagBody(self, token): + self.parser.framesetOK = False + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inBody"] + + def startTagFrameset(self, token): + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagFromHead(self, token): + self.parser.parseError("unexpected-start-tag-out-of-my-head", + {"name": token["name"]}) + self.tree.openElements.append(self.tree.headPointer) + self.parser.phases["inHead"].processStartTag(token) + for node in self.tree.openElements[::-1]: + if node.name == "head": + self.tree.openElements.remove(node) + break + + def startTagHead(self, token): + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + + def startTagOther(self, token): + self.anythingElse() + return token + + def endTagHtmlBodyBr(self, token): + self.anythingElse() + return token + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def anythingElse(self): + self.tree.insertElement(impliedTagToken("body", "StartTag")) + self.parser.phase = self.parser.phases["inBody"] + self.parser.framesetOK = True + + class InBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#parsing-main-inbody + # the really-really-really-very crazy mode + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + # Set this to the default handler + self.processSpaceCharacters = self.processSpaceCharactersNonPre + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("base", "basefont", "bgsound", "command", "link", "meta", + "script", "style", "title"), + self.startTagProcessInHead), + ("body", self.startTagBody), + ("frameset", self.startTagFrameset), + (("address", "article", "aside", "blockquote", "center", "details", + "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "main", "menu", "nav", "ol", "p", + "section", "summary", "ul"), + self.startTagCloseP), + (headingElements, self.startTagHeading), + (("pre", "listing"), self.startTagPreListing), + ("form", self.startTagForm), + (("li", "dd", "dt"), self.startTagListItem), + ("plaintext", self.startTagPlaintext), + ("a", self.startTagA), + (("b", "big", "code", "em", "font", "i", "s", "small", "strike", + "strong", "tt", "u"), self.startTagFormatting), + ("nobr", self.startTagNobr), + ("button", self.startTagButton), + (("applet", "marquee", "object"), self.startTagAppletMarqueeObject), + ("xmp", self.startTagXmp), + ("table", self.startTagTable), + (("area", "br", "embed", "img", "keygen", "wbr"), + self.startTagVoidFormatting), + (("param", "source", "track"), self.startTagParamSource), + ("input", self.startTagInput), + ("hr", self.startTagHr), + ("image", self.startTagImage), + ("isindex", self.startTagIsIndex), + ("textarea", self.startTagTextarea), + ("iframe", self.startTagIFrame), + ("noscript", self.startTagNoscript), + (("noembed", "noframes"), self.startTagRawtext), + ("select", self.startTagSelect), + (("rp", "rt"), self.startTagRpRt), + (("option", "optgroup"), self.startTagOpt), + (("math"), self.startTagMath), + (("svg"), self.startTagSvg), + (("caption", "col", "colgroup", "frame", "head", + "tbody", "td", "tfoot", "th", "thead", + "tr"), self.startTagMisplaced) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("body", self.endTagBody), + ("html", self.endTagHtml), + (("address", "article", "aside", "blockquote", "button", "center", + "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", + "footer", "header", "hgroup", "listing", "main", "menu", "nav", "ol", "pre", + "section", "summary", "ul"), self.endTagBlock), + ("form", self.endTagForm), + ("p", self.endTagP), + (("dd", "dt", "li"), self.endTagListItem), + (headingElements, self.endTagHeading), + (("a", "b", "big", "code", "em", "font", "i", "nobr", "s", "small", + "strike", "strong", "tt", "u"), self.endTagFormatting), + (("applet", "marquee", "object"), self.endTagAppletMarqueeObject), + ("br", self.endTagBr), + ]) + self.endTagHandler.default = self.endTagOther + + def isMatchingFormattingElement(self, node1, node2): + return (node1.name == node2.name and + node1.namespace == node2.namespace and + node1.attributes == node2.attributes) + + # helper + def addFormattingElement(self, token): + self.tree.insertElement(token) + element = self.tree.openElements[-1] + + matchingElements = [] + for node in self.tree.activeFormattingElements[::-1]: + if node is Marker: + break + elif self.isMatchingFormattingElement(node, element): + matchingElements.append(node) + + assert len(matchingElements) <= 3 + if len(matchingElements) == 3: + self.tree.activeFormattingElements.remove(matchingElements[-1]) + self.tree.activeFormattingElements.append(element) + + # the real deal + def processEOF(self): + allowed_elements = frozenset(("dd", "dt", "li", "p", "tbody", "td", + "tfoot", "th", "thead", "tr", "body", + "html")) + for node in self.tree.openElements[::-1]: + if node.name not in allowed_elements: + self.parser.parseError("expected-closing-tag-but-got-eof") + break + # Stop parsing + + def processSpaceCharactersDropNewline(self, token): + # Sometimes (start of <pre>, <listing>, and <textarea> blocks) we + # want to drop leading newlines + data = token["data"] + self.processSpaceCharacters = self.processSpaceCharactersNonPre + if (data.startswith("\n") and + self.tree.openElements[-1].name in ("pre", "listing", "textarea") and + not self.tree.openElements[-1].hasContent()): + data = data[1:] + if data: + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(data) + + def processCharacters(self, token): + if token["data"] == "\u0000": + # The tokenizer should always emit null on its own + return + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + # This must be bad for performance + if (self.parser.framesetOK and + any([char not in spaceCharacters + for char in token["data"]])): + self.parser.framesetOK = False + + def processSpaceCharactersNonPre(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertText(token["data"]) + + def startTagProcessInHead(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagBody(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "body"}) + if (len(self.tree.openElements) == 1 or + self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + else: + self.parser.framesetOK = False + for attr, value in token["data"].items(): + if attr not in self.tree.openElements[1].attributes: + self.tree.openElements[1].attributes[attr] = value + + def startTagFrameset(self, token): + self.parser.parseError("unexpected-start-tag", {"name": "frameset"}) + if (len(self.tree.openElements) == 1 or self.tree.openElements[1].name != "body"): + assert self.parser.innerHTML + elif not self.parser.framesetOK: + pass + else: + if self.tree.openElements[1].parent: + self.tree.openElements[1].parent.removeChild(self.tree.openElements[1]) + while self.tree.openElements[-1].name != "html": + self.tree.openElements.pop() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inFrameset"] + + def startTagCloseP(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + + def startTagPreListing(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + + def startTagForm(self, token): + if self.tree.formPointer: + self.parser.parseError("unexpected-start-tag", {"name": "form"}) + else: + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + + def startTagListItem(self, token): + self.parser.framesetOK = False + + stopNamesMap = {"li": ["li"], + "dt": ["dt", "dd"], + "dd": ["dt", "dd"]} + stopNames = stopNamesMap[token["name"]] + for node in reversed(self.tree.openElements): + if node.name in stopNames: + self.parser.phase.processEndTag( + impliedTagToken(node.name, "EndTag")) + break + if (node.nameTuple in specialElements and + node.name not in ("address", "div", "p")): + break + + if self.tree.elementInScope("p", variant="button"): + self.parser.phase.processEndTag( + impliedTagToken("p", "EndTag")) + + self.tree.insertElement(token) + + def startTagPlaintext(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.plaintextState + + def startTagHeading(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + if self.tree.openElements[-1].name in headingElements: + self.parser.parseError("unexpected-start-tag", {"name": token["name"]}) + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagA(self, token): + afeAElement = self.tree.elementInActiveFormattingElements("a") + if afeAElement: + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "a", "endName": "a"}) + self.endTagFormatting(impliedTagToken("a")) + if afeAElement in self.tree.openElements: + self.tree.openElements.remove(afeAElement) + if afeAElement in self.tree.activeFormattingElements: + self.tree.activeFormattingElements.remove(afeAElement) + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagNobr(self, token): + self.tree.reconstructActiveFormattingElements() + if self.tree.elementInScope("nobr"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "nobr", "endName": "nobr"}) + self.processEndTag(impliedTagToken("nobr")) + # XXX Need tests that trigger the following + self.tree.reconstructActiveFormattingElements() + self.addFormattingElement(token) + + def startTagButton(self, token): + if self.tree.elementInScope("button"): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "button", "endName": "button"}) + self.processEndTag(impliedTagToken("button")) + return token + else: + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + + def startTagAppletMarqueeObject(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.activeFormattingElements.append(Marker) + self.parser.framesetOK = False + + def startTagXmp(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.reconstructActiveFormattingElements() + self.parser.framesetOK = False + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagTable(self, token): + if self.parser.compatMode != "quirks": + if self.tree.elementInScope("p", variant="button"): + self.processEndTag(impliedTagToken("p")) + self.tree.insertElement(token) + self.parser.framesetOK = False + self.parser.phase = self.parser.phases["inTable"] + + def startTagVoidFormatting(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagInput(self, token): + framesetOK = self.parser.framesetOK + self.startTagVoidFormatting(token) + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + # input type=hidden doesn't change framesetOK + self.parser.framesetOK = framesetOK + + def startTagParamSource(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagHr(self, token): + if self.tree.elementInScope("p", variant="button"): + self.endTagP(impliedTagToken("p")) + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + self.parser.framesetOK = False + + def startTagImage(self, token): + # No really... + self.parser.parseError("unexpected-start-tag-treated-as", + {"originalName": "image", "newName": "img"}) + self.processStartTag(impliedTagToken("img", "StartTag", + attributes=token["data"], + selfClosing=token["selfClosing"])) + + def startTagIsIndex(self, token): + self.parser.parseError("deprecated-tag", {"name": "isindex"}) + if self.tree.formPointer: + return + form_attrs = {} + if "action" in token["data"]: + form_attrs["action"] = token["data"]["action"] + self.processStartTag(impliedTagToken("form", "StartTag", + attributes=form_attrs)) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processStartTag(impliedTagToken("label", "StartTag")) + # XXX Localization ... + if "prompt" in token["data"]: + prompt = token["data"]["prompt"] + else: + prompt = "This is a searchable index. Enter search keywords: " + self.processCharacters( + {"type": tokenTypes["Characters"], "data": prompt}) + attributes = token["data"].copy() + if "action" in attributes: + del attributes["action"] + if "prompt" in attributes: + del attributes["prompt"] + attributes["name"] = "isindex" + self.processStartTag(impliedTagToken("input", "StartTag", + attributes=attributes, + selfClosing=token["selfClosing"])) + self.processEndTag(impliedTagToken("label")) + self.processStartTag(impliedTagToken("hr", "StartTag")) + self.processEndTag(impliedTagToken("form")) + + def startTagTextarea(self, token): + self.tree.insertElement(token) + self.parser.tokenizer.state = self.parser.tokenizer.rcdataState + self.processSpaceCharacters = self.processSpaceCharactersDropNewline + self.parser.framesetOK = False + + def startTagIFrame(self, token): + self.parser.framesetOK = False + self.startTagRawtext(token) + + def startTagNoscript(self, token): + if self.parser.scripting: + self.startTagRawtext(token) + else: + self.startTagOther(token) + + def startTagRawtext(self, token): + """iframe, noembed noframes, noscript(if scripting enabled)""" + self.parser.parseRCDataRawtext(token, "RAWTEXT") + + def startTagOpt(self, token): + if self.tree.openElements[-1].name == "option": + self.parser.phase.processEndTag(impliedTagToken("option")) + self.tree.reconstructActiveFormattingElements() + self.parser.tree.insertElement(token) + + def startTagSelect(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + self.parser.framesetOK = False + if self.parser.phase in (self.parser.phases["inTable"], + self.parser.phases["inCaption"], + self.parser.phases["inColumnGroup"], + self.parser.phases["inTableBody"], + self.parser.phases["inRow"], + self.parser.phases["inCell"]): + self.parser.phase = self.parser.phases["inSelectInTable"] + else: + self.parser.phase = self.parser.phases["inSelect"] + + def startTagRpRt(self, token): + if self.tree.elementInScope("ruby"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "ruby": + self.parser.parseError() + self.tree.insertElement(token) + + def startTagMath(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustMathMLAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["mathml"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagSvg(self, token): + self.tree.reconstructActiveFormattingElements() + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = namespaces["svg"] + self.tree.insertElement(token) + # Need to get the parse error right for the case where the token + # has a namespace not equal to the xmlns attribute + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagMisplaced(self, token): + """ Elements that should be children of other elements that have a + different insertion mode; here they are ignored + "caption", "col", "colgroup", "frame", "frameset", "head", + "option", "optgroup", "tbody", "td", "tfoot", "th", "thead", + "tr", "noscript" + """ + self.parser.parseError("unexpected-start-tag-ignored", {"name": token["name"]}) + + def startTagOther(self, token): + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(token) + + def endTagP(self, token): + if not self.tree.elementInScope("p", variant="button"): + self.startTagCloseP(impliedTagToken("p", "StartTag")) + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + self.endTagP(impliedTagToken("p", "EndTag")) + else: + self.tree.generateImpliedEndTags("p") + if self.tree.openElements[-1].name != "p": + self.parser.parseError("unexpected-end-tag", {"name": "p"}) + node = self.tree.openElements.pop() + while node.name != "p": + node = self.tree.openElements.pop() + + def endTagBody(self, token): + if not self.tree.elementInScope("body"): + self.parser.parseError() + return + elif self.tree.openElements[-1].name != "body": + for node in self.tree.openElements[2:]: + if node.name not in frozenset(("dd", "dt", "li", "optgroup", + "option", "p", "rp", "rt", + "tbody", "td", "tfoot", + "th", "thead", "tr", "body", + "html")): + # Not sure this is the correct name for the parse error + self.parser.parseError( + "expected-one-end-tag-but-got-another", + {"gotName": "body", "expectedName": node.name}) + break + self.parser.phase = self.parser.phases["afterBody"] + + def endTagHtml(self, token): + # We repeat the test for the body end tag token being ignored here + if self.tree.elementInScope("body"): + self.endTagBody(impliedTagToken("body")) + return token + + def endTagBlock(self, token): + # Put us back in the right whitespace handling mode + if token["name"] == "pre": + self.processSpaceCharacters = self.processSpaceCharactersNonPre + inScope = self.tree.elementInScope(token["name"]) + if inScope: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + if inScope: + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagForm(self, token): + node = self.tree.formPointer + self.tree.formPointer = None + if node is None or not self.tree.elementInScope(node): + self.parser.parseError("unexpected-end-tag", + {"name": "form"}) + else: + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1] != node: + self.parser.parseError("end-tag-too-early-ignored", + {"name": "form"}) + self.tree.openElements.remove(node) + + def endTagListItem(self, token): + if token["name"] == "li": + variant = "list" + else: + variant = None + if not self.tree.elementInScope(token["name"], variant=variant): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + else: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError( + "end-tag-too-early", + {"name": token["name"]}) + node = self.tree.openElements.pop() + while node.name != token["name"]: + node = self.tree.openElements.pop() + + def endTagHeading(self, token): + for item in headingElements: + if self.tree.elementInScope(item): + self.tree.generateImpliedEndTags() + break + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + for item in headingElements: + if self.tree.elementInScope(item): + item = self.tree.openElements.pop() + while item.name not in headingElements: + item = self.tree.openElements.pop() + break + + def endTagFormatting(self, token): + """The much-feared adoption agency algorithm""" + # http://svn.whatwg.org/webapps/complete.html#adoptionAgency revision 7867 + # XXX Better parseError messages appreciated. + + # Step 1 + outerLoopCounter = 0 + + # Step 2 + while outerLoopCounter < 8: + + # Step 3 + outerLoopCounter += 1 + + # Step 4: + + # Let the formatting element be the last element in + # the list of active formatting elements that: + # - is between the end of the list and the last scope + # marker in the list, if any, or the start of the list + # otherwise, and + # - has the same tag name as the token. + formattingElement = self.tree.elementInActiveFormattingElements( + token["name"]) + if (not formattingElement or + (formattingElement in self.tree.openElements and + not self.tree.elementInScope(formattingElement.name))): + # If there is no such node, then abort these steps + # and instead act as described in the "any other + # end tag" entry below. + self.endTagOther(token) + return + + # Otherwise, if there is such a node, but that node is + # not in the stack of open elements, then this is a + # parse error; remove the element from the list, and + # abort these steps. + elif formattingElement not in self.tree.openElements: + self.parser.parseError("adoption-agency-1.2", {"name": token["name"]}) + self.tree.activeFormattingElements.remove(formattingElement) + return + + # Otherwise, if there is such a node, and that node is + # also in the stack of open elements, but the element + # is not in scope, then this is a parse error; ignore + # the token, and abort these steps. + elif not self.tree.elementInScope(formattingElement.name): + self.parser.parseError("adoption-agency-4.4", {"name": token["name"]}) + return + + # Otherwise, there is a formatting element and that + # element is in the stack and is in scope. If the + # element is not the current node, this is a parse + # error. In any case, proceed with the algorithm as + # written in the following steps. + else: + if formattingElement != self.tree.openElements[-1]: + self.parser.parseError("adoption-agency-1.3", {"name": token["name"]}) + + # Step 5: + + # Let the furthest block be the topmost node in the + # stack of open elements that is lower in the stack + # than the formatting element, and is an element in + # the special category. There might not be one. + afeIndex = self.tree.openElements.index(formattingElement) + furthestBlock = None + for element in self.tree.openElements[afeIndex:]: + if element.nameTuple in specialElements: + furthestBlock = element + break + + # Step 6: + + # If there is no furthest block, then the UA must + # first pop all the nodes from the bottom of the stack + # of open elements, from the current node up to and + # including the formatting element, then remove the + # formatting element from the list of active + # formatting elements, and finally abort these steps. + if furthestBlock is None: + element = self.tree.openElements.pop() + while element != formattingElement: + element = self.tree.openElements.pop() + self.tree.activeFormattingElements.remove(element) + return + + # Step 7 + commonAncestor = self.tree.openElements[afeIndex - 1] + + # Step 8: + # The bookmark is supposed to help us identify where to reinsert + # nodes in step 15. We have to ensure that we reinsert nodes after + # the node before the active formatting element. Note the bookmark + # can move in step 9.7 + bookmark = self.tree.activeFormattingElements.index(formattingElement) + + # Step 9 + lastNode = node = furthestBlock + innerLoopCounter = 0 + + index = self.tree.openElements.index(node) + while innerLoopCounter < 3: + innerLoopCounter += 1 + # Node is element before node in open elements + index -= 1 + node = self.tree.openElements[index] + if node not in self.tree.activeFormattingElements: + self.tree.openElements.remove(node) + continue + # Step 9.6 + if node == formattingElement: + break + # Step 9.7 + if lastNode == furthestBlock: + bookmark = self.tree.activeFormattingElements.index(node) + 1 + # Step 9.8 + clone = node.cloneNode() + # Replace node with clone + self.tree.activeFormattingElements[ + self.tree.activeFormattingElements.index(node)] = clone + self.tree.openElements[ + self.tree.openElements.index(node)] = clone + node = clone + # Step 9.9 + # Remove lastNode from its parents, if any + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + node.appendChild(lastNode) + # Step 9.10 + lastNode = node + + # Step 10 + # Foster parent lastNode if commonAncestor is a + # table, tbody, tfoot, thead, or tr we need to foster + # parent the lastNode + if lastNode.parent: + lastNode.parent.removeChild(lastNode) + + if commonAncestor.name in frozenset(("table", "tbody", "tfoot", "thead", "tr")): + parent, insertBefore = self.tree.getTableMisnestedNodePosition() + parent.insertBefore(lastNode, insertBefore) + else: + commonAncestor.appendChild(lastNode) + + # Step 11 + clone = formattingElement.cloneNode() + + # Step 12 + furthestBlock.reparentChildren(clone) + + # Step 13 + furthestBlock.appendChild(clone) + + # Step 14 + self.tree.activeFormattingElements.remove(formattingElement) + self.tree.activeFormattingElements.insert(bookmark, clone) + + # Step 15 + self.tree.openElements.remove(formattingElement) + self.tree.openElements.insert( + self.tree.openElements.index(furthestBlock) + 1, clone) + + def endTagAppletMarqueeObject(self, token): + if self.tree.elementInScope(token["name"]): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("end-tag-too-early", {"name": token["name"]}) + + if self.tree.elementInScope(token["name"]): + element = self.tree.openElements.pop() + while element.name != token["name"]: + element = self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + + def endTagBr(self, token): + self.parser.parseError("unexpected-end-tag-treated-as", + {"originalName": "br", "newName": "br element"}) + self.tree.reconstructActiveFormattingElements() + self.tree.insertElement(impliedTagToken("br", "StartTag")) + self.tree.openElements.pop() + + def endTagOther(self, token): + for node in self.tree.openElements[::-1]: + if node.name == token["name"]: + self.tree.generateImpliedEndTags(exclude=token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + while self.tree.openElements.pop() != node: + pass + break + else: + if node.nameTuple in specialElements: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + break + + class TextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([]) + self.startTagHandler.default = self.startTagOther + self.endTagHandler = _utils.MethodDispatcher([ + ("script", self.endTagScript)]) + self.endTagHandler.default = self.endTagOther + + def processCharacters(self, token): + self.tree.insertText(token["data"]) + + def processEOF(self): + self.parser.parseError("expected-named-closing-tag-but-got-eof", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + return True + + def startTagOther(self, token): + assert False, "Tried to process start tag %s in RCDATA/RAWTEXT mode" % token['name'] + + def endTagScript(self, token): + node = self.tree.openElements.pop() + assert node.name == "script" + self.parser.phase = self.parser.originalPhase + # The rest of this method is all stuff that only happens if + # document.write works + + def endTagOther(self, token): + self.tree.openElements.pop() + self.parser.phase = self.parser.originalPhase + + class InTablePhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-table + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("caption", self.startTagCaption), + ("colgroup", self.startTagColgroup), + ("col", self.startTagCol), + (("tbody", "tfoot", "thead"), self.startTagRowGroup), + (("td", "th", "tr"), self.startTagImplyTbody), + ("table", self.startTagTable), + (("style", "script"), self.startTagStyleScript), + ("input", self.startTagInput), + ("form", self.startTagForm) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("table", self.endTagTable), + (("body", "caption", "col", "colgroup", "html", "tbody", "td", + "tfoot", "th", "thead", "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods + def clearStackToTableContext(self): + # "clear the stack back to a table context" + while self.tree.openElements[-1].name not in ("table", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + # When the current node is <html> it's an innerHTML case + + # processing methods + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-table") + else: + assert self.parser.innerHTML + # Stop parsing + + def processSpaceCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processSpaceCharacters(token) + + def processCharacters(self, token): + originalPhase = self.parser.phase + self.parser.phase = self.parser.phases["inTableText"] + self.parser.phase.originalPhase = originalPhase + self.parser.phase.processCharacters(token) + + def insertText(self, token): + # If we get here there must be at least one non-whitespace character + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processCharacters(token) + self.tree.insertFromTable = False + + def startTagCaption(self, token): + self.clearStackToTableContext() + self.tree.activeFormattingElements.append(Marker) + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCaption"] + + def startTagColgroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inColumnGroup"] + + def startTagCol(self, token): + self.startTagColgroup(impliedTagToken("colgroup", "StartTag")) + return token + + def startTagRowGroup(self, token): + self.clearStackToTableContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inTableBody"] + + def startTagImplyTbody(self, token): + self.startTagRowGroup(impliedTagToken("tbody", "StartTag")) + return token + + def startTagTable(self, token): + self.parser.parseError("unexpected-start-tag-implies-end-tag", + {"startName": "table", "endName": "table"}) + self.parser.phase.processEndTag(impliedTagToken("table")) + if not self.parser.innerHTML: + return token + + def startTagStyleScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagInput(self, token): + if ("type" in token["data"] and + token["data"]["type"].translate(asciiUpper2Lower) == "hidden"): + self.parser.parseError("unexpected-hidden-input-in-table") + self.tree.insertElement(token) + # XXX associate with form + self.tree.openElements.pop() + else: + self.startTagOther(token) + + def startTagForm(self, token): + self.parser.parseError("unexpected-form-in-table") + if self.tree.formPointer is None: + self.tree.insertElement(token) + self.tree.formPointer = self.tree.openElements[-1] + self.tree.openElements.pop() + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processStartTag(token) + self.tree.insertFromTable = False + + def endTagTable(self, token): + if self.tree.elementInScope("table", variant="table"): + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "table": + self.parser.parseError("end-tag-too-early-named", + {"gotName": "table", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "table": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-implies-table-voodoo", {"name": token["name"]}) + # Do the table magic! + self.tree.insertFromTable = True + self.parser.phases["inBody"].processEndTag(token) + self.tree.insertFromTable = False + + class InTableTextPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.originalPhase = None + self.characterTokens = [] + + def flushCharacters(self): + data = "".join([item["data"] for item in self.characterTokens]) + if any([item not in spaceCharacters for item in data]): + token = {"type": tokenTypes["Characters"], "data": data} + self.parser.phases["inTable"].insertText(token) + elif data: + self.tree.insertText(data) + self.characterTokens = [] + + def processComment(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEOF(self): + self.flushCharacters() + self.parser.phase = self.originalPhase + return True + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.characterTokens.append(token) + + def processSpaceCharacters(self, token): + # pretty sure we should never reach here + self.characterTokens.append(token) + # assert False + + def processStartTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + def processEndTag(self, token): + self.flushCharacters() + self.parser.phase = self.originalPhase + return token + + class InCaptionPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-caption + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.startTagTableElement) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("caption", self.endTagCaption), + ("table", self.endTagTable), + (("body", "col", "colgroup", "html", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + def ignoreEndTagCaption(self): + return not self.tree.elementInScope("caption", variant="table") + + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableElement(self, token): + self.parser.parseError() + # XXX Have to duplicate logic here to find out if the tag is ignored + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagCaption(self, token): + if not self.ignoreEndTagCaption(): + # AT this code is quite similar to endTagTable in "InTable" + self.tree.generateImpliedEndTags() + if self.tree.openElements[-1].name != "caption": + self.parser.parseError("expected-one-end-tag-but-got-another", + {"gotName": "caption", + "expectedName": self.tree.openElements[-1].name}) + while self.tree.openElements[-1].name != "caption": + self.tree.openElements.pop() + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inTable"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + self.parser.parseError() + ignoreEndTag = self.ignoreEndTagCaption() + self.parser.phase.processEndTag(impliedTagToken("caption")) + if not ignoreEndTag: + return token + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + class InColumnGroupPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-column + + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("col", self.startTagCol) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("colgroup", self.endTagColgroup), + ("col", self.endTagCol) + ]) + self.endTagHandler.default = self.endTagOther + + def ignoreEndTagColgroup(self): + return self.tree.openElements[-1].name == "html" + + def processEOF(self): + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + return + else: + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return True + + def processCharacters(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def startTagCol(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def startTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + def endTagColgroup(self, token): + if self.ignoreEndTagColgroup(): + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + else: + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + + def endTagCol(self, token): + self.parser.parseError("no-end-tag", {"name": "col"}) + + def endTagOther(self, token): + ignoreEndTag = self.ignoreEndTagColgroup() + self.endTagColgroup(impliedTagToken("colgroup")) + if not ignoreEndTag: + return token + + class InTableBodyPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-table0 + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("tr", self.startTagTr), + (("td", "th"), self.startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead"), + self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), + ("table", self.endTagTable), + (("body", "caption", "col", "colgroup", "html", "td", "th", + "tr"), self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods + def clearStackToTableBodyContext(self): + while self.tree.openElements[-1].name not in ("tbody", "tfoot", + "thead", "html"): + # self.parser.parseError("unexpected-implied-end-tag-in-table", + # {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "html": + assert self.parser.innerHTML + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTr(self, token): + self.clearStackToTableBodyContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inRow"] + + def startTagTableCell(self, token): + self.parser.parseError("unexpected-cell-in-table-body", + {"name": token["name"]}) + self.startTagTr(impliedTagToken("tr", "StartTag")) + return token + + def startTagTableOther(self, token): + # XXX AT Any ideas on how to share this with endTagTable? + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.clearStackToTableBodyContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTable"] + else: + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagTable(self, token): + if (self.tree.elementInScope("tbody", variant="table") or + self.tree.elementInScope("thead", variant="table") or + self.tree.elementInScope("tfoot", variant="table")): + self.clearStackToTableBodyContext() + self.endTagTableRowGroup( + impliedTagToken(self.tree.openElements[-1].name)) + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-body", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + class InRowPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-row + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("td", "th"), self.startTagTableCell), + (("caption", "col", "colgroup", "tbody", "tfoot", "thead", + "tr"), self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("tr", self.endTagTr), + ("table", self.endTagTable), + (("tbody", "tfoot", "thead"), self.endTagTableRowGroup), + (("body", "caption", "col", "colgroup", "html", "td", "th"), + self.endTagIgnore) + ]) + self.endTagHandler.default = self.endTagOther + + # helper methods (XXX unify this with other table helper methods) + def clearStackToTableRowContext(self): + while self.tree.openElements[-1].name not in ("tr", "html"): + self.parser.parseError("unexpected-implied-end-tag-in-table-row", + {"name": self.tree.openElements[-1].name}) + self.tree.openElements.pop() + + def ignoreEndTagTr(self): + return not self.tree.elementInScope("tr", variant="table") + + # the rest + def processEOF(self): + self.parser.phases["inTable"].processEOF() + + def processSpaceCharacters(self, token): + return self.parser.phases["inTable"].processSpaceCharacters(token) + + def processCharacters(self, token): + return self.parser.phases["inTable"].processCharacters(token) + + def startTagTableCell(self, token): + self.clearStackToTableRowContext() + self.tree.insertElement(token) + self.parser.phase = self.parser.phases["inCell"] + self.tree.activeFormattingElements.append(Marker) + + def startTagTableOther(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def startTagOther(self, token): + return self.parser.phases["inTable"].processStartTag(token) + + def endTagTr(self, token): + if not self.ignoreEndTagTr(): + self.clearStackToTableRowContext() + self.tree.openElements.pop() + self.parser.phase = self.parser.phases["inTableBody"] + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagTable(self, token): + ignoreEndTag = self.ignoreEndTagTr() + self.endTagTr(impliedTagToken("tr")) + # Reprocess the current tag if the tr end tag was not ignored + # XXX how are we sure it's always ignored in the innerHTML case? + if not ignoreEndTag: + return token + + def endTagTableRowGroup(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagTr(impliedTagToken("tr")) + return token + else: + self.parser.parseError() + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag-in-table-row", + {"name": token["name"]}) + + def endTagOther(self, token): + return self.parser.phases["inTable"].processEndTag(token) + + class InCellPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-cell + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + (("caption", "col", "colgroup", "tbody", "td", "tfoot", "th", + "thead", "tr"), self.startTagTableOther) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("td", "th"), self.endTagTableCell), + (("body", "caption", "col", "colgroup", "html"), self.endTagIgnore), + (("table", "tbody", "tfoot", "thead", "tr"), self.endTagImply) + ]) + self.endTagHandler.default = self.endTagOther + + # helper + def closeCell(self): + if self.tree.elementInScope("td", variant="table"): + self.endTagTableCell(impliedTagToken("td")) + elif self.tree.elementInScope("th", variant="table"): + self.endTagTableCell(impliedTagToken("th")) + + # the rest + def processEOF(self): + self.parser.phases["inBody"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inBody"].processCharacters(token) + + def startTagTableOther(self, token): + if (self.tree.elementInScope("td", variant="table") or + self.tree.elementInScope("th", variant="table")): + self.closeCell() + return token + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def startTagOther(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def endTagTableCell(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.tree.generateImpliedEndTags(token["name"]) + if self.tree.openElements[-1].name != token["name"]: + self.parser.parseError("unexpected-cell-end-tag", + {"name": token["name"]}) + while True: + node = self.tree.openElements.pop() + if node.name == token["name"]: + break + else: + self.tree.openElements.pop() + self.tree.clearActiveFormattingElements() + self.parser.phase = self.parser.phases["inRow"] + else: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagIgnore(self, token): + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + def endTagImply(self, token): + if self.tree.elementInScope(token["name"], variant="table"): + self.closeCell() + return token + else: + # sometimes innerHTML case + self.parser.parseError() + + def endTagOther(self, token): + return self.parser.phases["inBody"].processEndTag(token) + + class InSelectPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("option", self.startTagOption), + ("optgroup", self.startTagOptgroup), + ("select", self.startTagSelect), + (("input", "keygen", "textarea"), self.startTagInput), + ("script", self.startTagScript) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("option", self.endTagOption), + ("optgroup", self.endTagOptgroup), + ("select", self.endTagSelect) + ]) + self.endTagHandler.default = self.endTagOther + + # http://www.whatwg.org/specs/web-apps/current-work/#in-select + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-select") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + if token["data"] == "\u0000": + return + self.tree.insertText(token["data"]) + + def startTagOption(self, token): + # We need to imply </option> if <option> is the current node. + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagOptgroup(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + self.tree.insertElement(token) + + def startTagSelect(self, token): + self.parser.parseError("unexpected-select-in-select") + self.endTagSelect(impliedTagToken("select")) + + def startTagInput(self, token): + self.parser.parseError("unexpected-input-in-select") + if self.tree.elementInScope("select", variant="select"): + self.endTagSelect(impliedTagToken("select")) + return token + else: + assert self.parser.innerHTML + + def startTagScript(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-select", + {"name": token["name"]}) + + def endTagOption(self, token): + if self.tree.openElements[-1].name == "option": + self.tree.openElements.pop() + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "option"}) + + def endTagOptgroup(self, token): + # </optgroup> implicitly closes <option> + if (self.tree.openElements[-1].name == "option" and + self.tree.openElements[-2].name == "optgroup"): + self.tree.openElements.pop() + # It also closes </optgroup> + if self.tree.openElements[-1].name == "optgroup": + self.tree.openElements.pop() + # But nothing else + else: + self.parser.parseError("unexpected-end-tag-in-select", + {"name": "optgroup"}) + + def endTagSelect(self, token): + if self.tree.elementInScope("select", variant="select"): + node = self.tree.openElements.pop() + while node.name != "select": + node = self.tree.openElements.pop() + self.parser.resetInsertionMode() + else: + # innerHTML case + assert self.parser.innerHTML + self.parser.parseError() + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-select", + {"name": token["name"]}) + + class InSelectInTablePhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + self.startTagTable) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + (("caption", "table", "tbody", "tfoot", "thead", "tr", "td", "th"), + self.endTagTable) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + self.parser.phases["inSelect"].processEOF() + + def processCharacters(self, token): + return self.parser.phases["inSelect"].processCharacters(token) + + def startTagTable(self, token): + self.parser.parseError("unexpected-table-element-start-tag-in-select-in-table", {"name": token["name"]}) + self.endTagOther(impliedTagToken("select")) + return token + + def startTagOther(self, token): + return self.parser.phases["inSelect"].processStartTag(token) + + def endTagTable(self, token): + self.parser.parseError("unexpected-table-element-end-tag-in-select-in-table", {"name": token["name"]}) + if self.tree.elementInScope(token["name"], variant="table"): + self.endTagOther(impliedTagToken("select")) + return token + + def endTagOther(self, token): + return self.parser.phases["inSelect"].processEndTag(token) + + class InForeignContentPhase(Phase): + breakoutElements = frozenset(["b", "big", "blockquote", "body", "br", + "center", "code", "dd", "div", "dl", "dt", + "em", "embed", "h1", "h2", "h3", + "h4", "h5", "h6", "head", "hr", "i", "img", + "li", "listing", "menu", "meta", "nobr", + "ol", "p", "pre", "ruby", "s", "small", + "span", "strong", "strike", "sub", "sup", + "table", "tt", "u", "ul", "var"]) + + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + def adjustSVGTagNames(self, token): + replacements = {"altglyph": "altGlyph", + "altglyphdef": "altGlyphDef", + "altglyphitem": "altGlyphItem", + "animatecolor": "animateColor", + "animatemotion": "animateMotion", + "animatetransform": "animateTransform", + "clippath": "clipPath", + "feblend": "feBlend", + "fecolormatrix": "feColorMatrix", + "fecomponenttransfer": "feComponentTransfer", + "fecomposite": "feComposite", + "feconvolvematrix": "feConvolveMatrix", + "fediffuselighting": "feDiffuseLighting", + "fedisplacementmap": "feDisplacementMap", + "fedistantlight": "feDistantLight", + "feflood": "feFlood", + "fefunca": "feFuncA", + "fefuncb": "feFuncB", + "fefuncg": "feFuncG", + "fefuncr": "feFuncR", + "fegaussianblur": "feGaussianBlur", + "feimage": "feImage", + "femerge": "feMerge", + "femergenode": "feMergeNode", + "femorphology": "feMorphology", + "feoffset": "feOffset", + "fepointlight": "fePointLight", + "fespecularlighting": "feSpecularLighting", + "fespotlight": "feSpotLight", + "fetile": "feTile", + "feturbulence": "feTurbulence", + "foreignobject": "foreignObject", + "glyphref": "glyphRef", + "lineargradient": "linearGradient", + "radialgradient": "radialGradient", + "textpath": "textPath"} + + if token["name"] in replacements: + token["name"] = replacements[token["name"]] + + def processCharacters(self, token): + if token["data"] == "\u0000": + token["data"] = "\uFFFD" + elif (self.parser.framesetOK and + any(char not in spaceCharacters for char in token["data"])): + self.parser.framesetOK = False + Phase.processCharacters(self, token) + + def processStartTag(self, token): + currentNode = self.tree.openElements[-1] + if (token["name"] in self.breakoutElements or + (token["name"] == "font" and + set(token["data"].keys()) & set(["color", "face", "size"]))): + self.parser.parseError("unexpected-html-element-in-foreign-content", + {"name": token["name"]}) + while (self.tree.openElements[-1].namespace != + self.tree.defaultNamespace and + not self.parser.isHTMLIntegrationPoint(self.tree.openElements[-1]) and + not self.parser.isMathMLTextIntegrationPoint(self.tree.openElements[-1])): + self.tree.openElements.pop() + return token + + else: + if currentNode.namespace == namespaces["mathml"]: + self.parser.adjustMathMLAttributes(token) + elif currentNode.namespace == namespaces["svg"]: + self.adjustSVGTagNames(token) + self.parser.adjustSVGAttributes(token) + self.parser.adjustForeignAttributes(token) + token["namespace"] = currentNode.namespace + self.tree.insertElement(token) + if token["selfClosing"]: + self.tree.openElements.pop() + token["selfClosingAcknowledged"] = True + + def processEndTag(self, token): + nodeIndex = len(self.tree.openElements) - 1 + node = self.tree.openElements[-1] + if node.name.translate(asciiUpper2Lower) != token["name"]: + self.parser.parseError("unexpected-end-tag", {"name": token["name"]}) + + while True: + if node.name.translate(asciiUpper2Lower) == token["name"]: + # XXX this isn't in the spec but it seems necessary + if self.parser.phase == self.parser.phases["inTableText"]: + self.parser.phase.flushCharacters() + self.parser.phase = self.parser.phase.originalPhase + while self.tree.openElements.pop() != node: + assert self.tree.openElements + new_token = None + break + nodeIndex -= 1 + + node = self.tree.openElements[nodeIndex] + if node.namespace != self.tree.defaultNamespace: + continue + else: + new_token = self.parser.phase.processEndTag(token) + break + return new_token + + class AfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([("html", self.endTagHtml)]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + # Stop parsing + pass + + def processComment(self, token): + # This is needed because data is to be appended to the <html> element + # here and not to whatever is currently open. + self.tree.insertComment(token, self.tree.openElements[0]) + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-body") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def endTagHtml(self, name): + if self.parser.innerHTML: + self.parser.parseError("unexpected-end-tag-after-body-innerhtml") + else: + self.parser.phase = self.parser.phases["afterAfterBody"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-body", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class InFramesetPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#in-frameset + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("frameset", self.startTagFrameset), + ("frame", self.startTagFrame), + ("noframes", self.startTagNoframes) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("frameset", self.endTagFrameset) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + if self.tree.openElements[-1].name != "html": + self.parser.parseError("eof-in-frameset") + else: + assert self.parser.innerHTML + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-in-frameset") + + def startTagFrameset(self, token): + self.tree.insertElement(token) + + def startTagFrame(self, token): + self.tree.insertElement(token) + self.tree.openElements.pop() + + def startTagNoframes(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-in-frameset", + {"name": token["name"]}) + + def endTagFrameset(self, token): + if self.tree.openElements[-1].name == "html": + # innerHTML case + self.parser.parseError("unexpected-frameset-in-frameset-innerhtml") + else: + self.tree.openElements.pop() + if (not self.parser.innerHTML and + self.tree.openElements[-1].name != "frameset"): + # If we're not in innerHTML mode and the current node is not a + # "frameset" element (anymore) then switch. + self.parser.phase = self.parser.phases["afterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-in-frameset", + {"name": token["name"]}) + + class AfterFramesetPhase(Phase): + # http://www.whatwg.org/specs/web-apps/current-work/#after3 + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("noframes", self.startTagNoframes) + ]) + self.startTagHandler.default = self.startTagOther + + self.endTagHandler = _utils.MethodDispatcher([ + ("html", self.endTagHtml) + ]) + self.endTagHandler.default = self.endTagOther + + def processEOF(self): + # Stop parsing + pass + + def processCharacters(self, token): + self.parser.parseError("unexpected-char-after-frameset") + + def startTagNoframes(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("unexpected-start-tag-after-frameset", + {"name": token["name"]}) + + def endTagHtml(self, token): + self.parser.phase = self.parser.phases["afterAfterFrameset"] + + def endTagOther(self, token): + self.parser.parseError("unexpected-end-tag-after-frameset", + {"name": token["name"]}) + + class AfterAfterBodyPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + self.parser.phase = self.parser.phases["inBody"] + return token + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + self.parser.phase = self.parser.phases["inBody"] + return token + + class AfterAfterFramesetPhase(Phase): + def __init__(self, parser, tree): + Phase.__init__(self, parser, tree) + + self.startTagHandler = _utils.MethodDispatcher([ + ("html", self.startTagHtml), + ("noframes", self.startTagNoFrames) + ]) + self.startTagHandler.default = self.startTagOther + + def processEOF(self): + pass + + def processComment(self, token): + self.tree.insertComment(token, self.tree.document) + + def processSpaceCharacters(self, token): + return self.parser.phases["inBody"].processSpaceCharacters(token) + + def processCharacters(self, token): + self.parser.parseError("expected-eof-but-got-char") + + def startTagHtml(self, token): + return self.parser.phases["inBody"].processStartTag(token) + + def startTagNoFrames(self, token): + return self.parser.phases["inHead"].processStartTag(token) + + def startTagOther(self, token): + self.parser.parseError("expected-eof-but-got-start-tag", + {"name": token["name"]}) + + def processEndTag(self, token): + self.parser.parseError("expected-eof-but-got-end-tag", + {"name": token["name"]}) + # pylint:enable=unused-argument + + return { + "initial": InitialPhase, + "beforeHtml": BeforeHtmlPhase, + "beforeHead": BeforeHeadPhase, + "inHead": InHeadPhase, + "inHeadNoscript": InHeadNoscriptPhase, + "afterHead": AfterHeadPhase, + "inBody": InBodyPhase, + "text": TextPhase, + "inTable": InTablePhase, + "inTableText": InTableTextPhase, + "inCaption": InCaptionPhase, + "inColumnGroup": InColumnGroupPhase, + "inTableBody": InTableBodyPhase, + "inRow": InRowPhase, + "inCell": InCellPhase, + "inSelect": InSelectPhase, + "inSelectInTable": InSelectInTablePhase, + "inForeignContent": InForeignContentPhase, + "afterBody": AfterBodyPhase, + "inFrameset": InFramesetPhase, + "afterFrameset": AfterFramesetPhase, + "afterAfterBody": AfterAfterBodyPhase, + "afterAfterFrameset": AfterAfterFramesetPhase, + # XXX after after frameset + } + + +def adjust_attributes(token, replacements): + needs_adjustment = viewkeys(token['data']) & viewkeys(replacements) + if needs_adjustment: + token['data'] = OrderedDict((replacements.get(k, k), v) + for k, v in token['data'].items()) + + +def impliedTagToken(name, type="EndTag", attributes=None, + selfClosing=False): + if attributes is None: + attributes = {} + return {"type": tokenTypes[type], "name": name, "data": attributes, + "selfClosing": selfClosing} + + +class ParseError(Exception): + """Error in parsed document""" + pass diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py new file mode 100644 index 0000000..53f4d44 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/serializer.py @@ -0,0 +1,409 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +import re + +from codecs import register_error, xmlcharrefreplace_errors + +from .constants import voidElements, booleanAttributes, spaceCharacters +from .constants import rcdataElements, entities, xmlEntities +from . import treewalkers, _utils +from xml.sax.saxutils import escape + +_quoteAttributeSpecChars = "".join(spaceCharacters) + "\"'=<>`" +_quoteAttributeSpec = re.compile("[" + _quoteAttributeSpecChars + "]") +_quoteAttributeLegacy = re.compile("[" + _quoteAttributeSpecChars + + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n" + "\x0b\x0c\r\x0e\x0f\x10\x11\x12\x13\x14\x15" + "\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f" + "\x20\x2f\x60\xa0\u1680\u180e\u180f\u2000" + "\u2001\u2002\u2003\u2004\u2005\u2006\u2007" + "\u2008\u2009\u200a\u2028\u2029\u202f\u205f" + "\u3000]") + + +_encode_entity_map = {} +_is_ucs4 = len("\U0010FFFF") == 1 +for k, v in list(entities.items()): + # skip multi-character entities + if ((_is_ucs4 and len(v) > 1) or + (not _is_ucs4 and len(v) > 2)): + continue + if v != "&": + if len(v) == 2: + v = _utils.surrogatePairToCodepoint(v) + else: + v = ord(v) + if v not in _encode_entity_map or k.islower(): + # prefer < over < and similarly for &, >, etc. + _encode_entity_map[v] = k + + +def htmlentityreplace_errors(exc): + if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): + res = [] + codepoints = [] + skip = False + for i, c in enumerate(exc.object[exc.start:exc.end]): + if skip: + skip = False + continue + index = i + exc.start + if _utils.isSurrogatePair(exc.object[index:min([exc.end, index + 2])]): + codepoint = _utils.surrogatePairToCodepoint(exc.object[index:index + 2]) + skip = True + else: + codepoint = ord(c) + codepoints.append(codepoint) + for cp in codepoints: + e = _encode_entity_map.get(cp) + if e: + res.append("&") + res.append(e) + if not e.endswith(";"): + res.append(";") + else: + res.append("&#x%s;" % (hex(cp)[2:])) + return ("".join(res), exc.end) + else: + return xmlcharrefreplace_errors(exc) + + +register_error("htmlentityreplace", htmlentityreplace_errors) + + +def serialize(input, tree="etree", encoding=None, **serializer_opts): + """Serializes the input token stream using the specified treewalker + + :arg input: the token stream to serialize + + :arg tree: the treewalker to use + + :arg encoding: the encoding to use + + :arg serializer_opts: any options to pass to the + :py:class:`html5lib.serializer.HTMLSerializer` that gets created + + :returns: the tree serialized as a string + + Example: + + >>> from html5lib.html5parser import parse + >>> from html5lib.serializer import serialize + >>> token_stream = parse('<html><body><p>Hi!</p></body></html>') + >>> serialize(token_stream, omit_optional_tags=False) + '<html><head></head><body><p>Hi!</p></body></html>' + + """ + # XXX: Should we cache this? + walker = treewalkers.getTreeWalker(tree) + s = HTMLSerializer(**serializer_opts) + return s.render(walker(input), encoding) + + +class HTMLSerializer(object): + + # attribute quoting options + quote_attr_values = "legacy" # be secure by default + quote_char = '"' + use_best_quote_char = True + + # tag syntax options + omit_optional_tags = True + minimize_boolean_attributes = True + use_trailing_solidus = False + space_before_trailing_solidus = True + + # escaping options + escape_lt_in_attrs = False + escape_rcdata = False + resolve_entities = True + + # miscellaneous options + alphabetical_attributes = False + inject_meta_charset = True + strip_whitespace = False + sanitize = False + + options = ("quote_attr_values", "quote_char", "use_best_quote_char", + "omit_optional_tags", "minimize_boolean_attributes", + "use_trailing_solidus", "space_before_trailing_solidus", + "escape_lt_in_attrs", "escape_rcdata", "resolve_entities", + "alphabetical_attributes", "inject_meta_charset", + "strip_whitespace", "sanitize") + + def __init__(self, **kwargs): + """Initialize HTMLSerializer + + :arg inject_meta_charset: Whether or not to inject the meta charset. + + Defaults to ``True``. + + :arg quote_attr_values: Whether to quote attribute values that don't + require quoting per legacy browser behavior (``"legacy"``), when + required by the standard (``"spec"``), or always (``"always"``). + + Defaults to ``"legacy"``. + + :arg quote_char: Use given quote character for attribute quoting. + + Defaults to ``"`` which will use double quotes unless attribute + value contains a double quote, in which case single quotes are + used. + + :arg escape_lt_in_attrs: Whether or not to escape ``<`` in attribute + values. + + Defaults to ``False``. + + :arg escape_rcdata: Whether to escape characters that need to be + escaped within normal elements within rcdata elements such as + style. + + Defaults to ``False``. + + :arg resolve_entities: Whether to resolve named character entities that + appear in the source tree. The XML predefined entities < > + & " ' are unaffected by this setting. + + Defaults to ``True``. + + :arg strip_whitespace: Whether to remove semantically meaningless + whitespace. (This compresses all whitespace to a single space + except within ``pre``.) + + Defaults to ``False``. + + :arg minimize_boolean_attributes: Shortens boolean attributes to give + just the attribute value, for example:: + + <input disabled="disabled"> + + becomes:: + + <input disabled> + + Defaults to ``True``. + + :arg use_trailing_solidus: Includes a close-tag slash at the end of the + start tag of void elements (empty elements whose end tag is + forbidden). E.g. ``<hr/>``. + + Defaults to ``False``. + + :arg space_before_trailing_solidus: Places a space immediately before + the closing slash in a tag using a trailing solidus. E.g. + ``<hr />``. Requires ``use_trailing_solidus=True``. + + Defaults to ``True``. + + :arg sanitize: Strip all unsafe or unknown constructs from output. + See :py:class:`html5lib.filters.sanitizer.Filter`. + + Defaults to ``False``. + + :arg omit_optional_tags: Omit start/end tags that are optional. + + Defaults to ``True``. + + :arg alphabetical_attributes: Reorder attributes to be in alphabetical order. + + Defaults to ``False``. + + """ + unexpected_args = frozenset(kwargs) - frozenset(self.options) + if len(unexpected_args) > 0: + raise TypeError("__init__() got an unexpected keyword argument '%s'" % next(iter(unexpected_args))) + if 'quote_char' in kwargs: + self.use_best_quote_char = False + for attr in self.options: + setattr(self, attr, kwargs.get(attr, getattr(self, attr))) + self.errors = [] + self.strict = False + + def encode(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "htmlentityreplace") + else: + return string + + def encodeStrict(self, string): + assert(isinstance(string, text_type)) + if self.encoding: + return string.encode(self.encoding, "strict") + else: + return string + + def serialize(self, treewalker, encoding=None): + # pylint:disable=too-many-nested-blocks + self.encoding = encoding + in_cdata = False + self.errors = [] + + if encoding and self.inject_meta_charset: + from .filters.inject_meta_charset import Filter + treewalker = Filter(treewalker, encoding) + # Alphabetical attributes is here under the assumption that none of + # the later filters add or change order of attributes; it needs to be + # before the sanitizer so escaped elements come out correctly + if self.alphabetical_attributes: + from .filters.alphabeticalattributes import Filter + treewalker = Filter(treewalker) + # WhitespaceFilter should be used before OptionalTagFilter + # for maximum efficiently of this latter filter + if self.strip_whitespace: + from .filters.whitespace import Filter + treewalker = Filter(treewalker) + if self.sanitize: + from .filters.sanitizer import Filter + treewalker = Filter(treewalker) + if self.omit_optional_tags: + from .filters.optionaltags import Filter + treewalker = Filter(treewalker) + + for token in treewalker: + type = token["type"] + if type == "Doctype": + doctype = "<!DOCTYPE %s" % token["name"] + + if token["publicId"]: + doctype += ' PUBLIC "%s"' % token["publicId"] + elif token["systemId"]: + doctype += " SYSTEM" + if token["systemId"]: + if token["systemId"].find('"') >= 0: + if token["systemId"].find("'") >= 0: + self.serializeError("System identifer contains both single and double quote characters") + quote_char = "'" + else: + quote_char = '"' + doctype += " %s%s%s" % (quote_char, token["systemId"], quote_char) + + doctype += ">" + yield self.encodeStrict(doctype) + + elif type in ("Characters", "SpaceCharacters"): + if type == "SpaceCharacters" or in_cdata: + if in_cdata and token["data"].find("</") >= 0: + self.serializeError("Unexpected </ in CDATA") + yield self.encode(token["data"]) + else: + yield self.encode(escape(token["data"])) + + elif type in ("StartTag", "EmptyTag"): + name = token["name"] + yield self.encodeStrict("<%s" % name) + if name in rcdataElements and not self.escape_rcdata: + in_cdata = True + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + for (_, attr_name), attr_value in token["data"].items(): + # TODO: Add namespace support here + k = attr_name + v = attr_value + yield self.encodeStrict(' ') + + yield self.encodeStrict(k) + if not self.minimize_boolean_attributes or \ + (k not in booleanAttributes.get(name, tuple()) and + k not in booleanAttributes.get("", tuple())): + yield self.encodeStrict("=") + if self.quote_attr_values == "always" or len(v) == 0: + quote_attr = True + elif self.quote_attr_values == "spec": + quote_attr = _quoteAttributeSpec.search(v) is not None + elif self.quote_attr_values == "legacy": + quote_attr = _quoteAttributeLegacy.search(v) is not None + else: + raise ValueError("quote_attr_values must be one of: " + "'always', 'spec', or 'legacy'") + v = v.replace("&", "&") + if self.escape_lt_in_attrs: + v = v.replace("<", "<") + if quote_attr: + quote_char = self.quote_char + if self.use_best_quote_char: + if "'" in v and '"' not in v: + quote_char = '"' + elif '"' in v and "'" not in v: + quote_char = "'" + if quote_char == "'": + v = v.replace("'", "'") + else: + v = v.replace('"', """) + yield self.encodeStrict(quote_char) + yield self.encode(v) + yield self.encodeStrict(quote_char) + else: + yield self.encode(v) + if name in voidElements and self.use_trailing_solidus: + if self.space_before_trailing_solidus: + yield self.encodeStrict(" /") + else: + yield self.encodeStrict("/") + yield self.encode(">") + + elif type == "EndTag": + name = token["name"] + if name in rcdataElements: + in_cdata = False + elif in_cdata: + self.serializeError("Unexpected child element of a CDATA element") + yield self.encodeStrict("</%s>" % name) + + elif type == "Comment": + data = token["data"] + if data.find("--") >= 0: + self.serializeError("Comment contains --") + yield self.encodeStrict("<!--%s-->" % token["data"]) + + elif type == "Entity": + name = token["name"] + key = name + ";" + if key not in entities: + self.serializeError("Entity %s not recognized" % name) + if self.resolve_entities and key not in xmlEntities: + data = entities[key] + else: + data = "&%s;" % name + yield self.encodeStrict(data) + + else: + self.serializeError(token["data"]) + + def render(self, treewalker, encoding=None): + """Serializes the stream from the treewalker into a string + + :arg treewalker: the treewalker to serialize + + :arg encoding: the string encoding to use + + :returns: the serialized tree + + Example: + + >>> from html5lib import parse, getTreeWalker + >>> from html5lib.serializer import HTMLSerializer + >>> token_stream = parse('<html><body>Hi!</body></html>') + >>> walker = getTreeWalker('etree') + >>> serializer = HTMLSerializer(omit_optional_tags=False) + >>> serializer.render(walker(token_stream)) + '<html><head></head><body>Hi!</body></html>' + + """ + if encoding: + return b"".join(list(self.serialize(treewalker, encoding))) + else: + return "".join(list(self.serialize(treewalker))) + + def serializeError(self, data="XXX ERROR MESSAGE NEEDED"): + # XXX The idea is to make data mandatory. + self.errors.append(data) + if self.strict: + raise SerializeError + + +class SerializeError(Exception): + """Error in serialized tree""" + pass diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py new file mode 100644 index 0000000..7ef5959 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__init__.py @@ -0,0 +1,30 @@ +"""Tree adapters let you convert from one tree structure to another + +Example: + +.. code-block:: python + + from pip._vendor import html5lib + from pip._vendor.html5lib.treeadapters import genshi + + doc = '<html><body>Hi!</body></html>' + treebuilder = html5lib.getTreeBuilder('etree') + parser = html5lib.HTMLParser(tree=treebuilder) + tree = parser.parse(doc) + TreeWalker = html5lib.getTreeWalker('etree') + + genshi_tree = genshi.to_genshi(TreeWalker(tree)) + +""" +from __future__ import absolute_import, division, unicode_literals + +from . import sax + +__all__ = ["sax"] + +try: + from . import genshi # noqa +except ImportError: + pass +else: + __all__.append("genshi") diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a660f4d7f09f5270bd1de6091a6709f31c901dfa GIT binary patch literal 896 zcmZuvPjAyO6t|Nu?XrIr+6OQf+8ml*;4*a;nlxz$n2@M6h!9p<d#$Ns2gfPvrvXlg zZ^JoPPWuX+cuv}lNjUP$`}g}j+wYwn9E1o~^7YAwA09%#ov~dVP@cmsK7wE<K@2lb z;>=6D%uoERm9#KoK5NOHEJy;-cjh>0ue;z2z}HDS7+oQC+(LYJ8JbIs-1i=-{db7B zzlE&*9RsTK7Dc=1FO1N{a86Q|=9Zg+NN&kmmt>~ZiW^I=jn0TxoLHAuSX0hyX~5JZ zRoX7N3B&W7G|MGF3Bx!BAmf9n)U)Nu3CY)Xp;Z_X(h%h$kLijlrVSBUuA#ufX7ZU7 z)Bokf+hFXf-<@%ToO4wyL`}~0jGU6*$mNemQ_a@n3-Nd~thLdwcK2Kb$1^R3WZVGY zj(*Oqdxo<n((iGX*NYq?PfhVK`C{_=)tlPecWI~paMlQC19=0C>t7!ZSjQ$1yGrHq zA>*ce6S%ML$~Tv!8_vdxt)`9EzvrvZ5=CKn3xk6qzdA~%g_fn|w0W<p!^BDyLaVA< zD&hJ>rGTcVvbcpgKoPF|BE2y|qX$h1(+2Z0+N;`>!YwGRLQ1boHw2U#7+++3Ct4sX zRD)e=DkX#+w%U79clz8IZK@#6bLjt1WDXt5i9augHp_=F8v~&V3&_Fj%Upf3pPxEs zy*EQschXJE&^^d@Acm9*B`l?JzOFi>OtVt*@gtxvx*%Hk*xUC4&%<4Ohy(90WYP_X literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/genshi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7e048d100a2eb689148a868f00319e44b4e709b7 GIT binary patch literal 1493 zcmah}OK%%D5GJ_~tyYq)D5(LZ4ImUq0TqoE1n$K!jHa><1`?&Mgf?9y5Y|gd-e_MY zDJOPUC+7#ahn{O6dv1OWuRZzRQ!edrCD|!@2nCLY!<mnqnUDKzt>z*a-tS+$_|rz{ zFTGd|0?Icq#S;(|Q5>NddpIT@i4D)d+D0NXwmd7gJ-b*Nur7I}*zugW?3H8JbK{Cv zfjyI2Z;@A}_5ig@SAdAxhFbRzL>kQ`8-;O}a;Y2|9)}`K6IGujVUSWbibBb_ABi?m z*7tosX3BajB^PZ=S%cx@ABM{4_4kxH>^&c<Quo=@r@cNXd(XPVpTFw`SRVxgvMXi) z|Kd4VCuok(@tdt2?V)r0^2<5N3B^q`H*$lLsm&kd_yU2=XrfDuQF1rO{E5WWydXKg z#MBxaKO$V<K!gnu@4&m%M4VG+p@A$n(U@$YxtVAitmdXPs7otvm)IBPCEVZ)pW(SB zEotZG8P2USS>XeAbxQa<S}Sf=1O4yiIqD<llon_!q@yZetxd@}=5?uW1DXA2Zym6! zvb?w_$a+)X@fKuY-1r?;e?mD_jt~D|3)+D0-ah@Un<mGM%a-4goUxWnL7T8d9EOF# zbz3mDeLiWu_M<7|+bwwrZs5CE>xh{s0=40KSKEUnb|{xHoXHta#I`;Gm?Bf&O2@0? z5}=S+I4V<~WDIEJb`O2-2S6*K)(4p%un!C-^`)<Xoc*hRVDMYO7l?5N(&uvMPn6S( zGkK!5asq4=I{wuD<-VBT7s}M8Yt9)EYr!07&TWC1pd7vY>IIqOIgwCBil75{TIQcq z;M4|6Y_LIBfB|GoekDgH)YIge!~NA6S9;aPTm!=sBAXAD>BECi*0CSW*dK`Bg`M~N z9T{hxEX*E+iI9F2JqTV;l2`I*OB;(hI%Ww?dFN2Z(brLU(9sR>sh{b}bQb;E%ue3B zJ5eZPkjB~WJ%ASa!(ijndomp@opz!$fG4`UdE?1%gO{><3Du=4b<;RziG+8V2D%N( z$z}&p80=H!h!Y`MyifaWSJ{4+!L4{%N1LzGFyZ>;Dhs{>vEU`pi_E#BHU0786%cJ( z*$e7Gm)RSsESXMO!mHZh6A;SMH4;T_7UENFEnnxLk;M)O<d}F3JMgPx6F0C)w7yZu z2EGIOwS_c@iyN@Bh8u=SY|Psb-*4BHI~t8=Kub0naa}I1slZJTUS(OcAmwb4icWBm lS&@`Z{U);l@`G#Z=JMk1&Q6@tS;TfVA%q6GL+bc5<6ke9cI^NF literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/__pycache__/sax.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc089e92fe8b547e44b8b880235b581f9192fed8 GIT binary patch literal 1443 zcmah}OK&4Z5bmD0$B&pOD`ZY10V{mS+J}Whw2H`P6Ttxs$)KQ7kkxT_>{<6b+})En zEBnIo1NaBT+z|f*apDK`35nBk;>3Xy)#Gduq($_oYpSchdQSB`Z8k#$EB^lB>7O1# zznjDB<pA?BY&iu&5yc#(IL4_JTd5t}*vKsIq;Bj2Z&QbRsUQ1k5C<3~D6TCYGXFYU zqi5*rcTVlN9yj79t5bJY6Z@>mYOMYQ&G%0b^{D?Xid)njqHgdCqM@#>x5$~yd8yba zNsC-49nj<=kx8EEc9|vPoU##56cdEYF4pY>r9^TDcsUq;nil+(W&BwBZ9<=yQXS`l zC6nw9r8{NzAF9FF*qY_ThQ6Rf*zyC6&=OyxHNt2SDST~Jwe6f*D{Ezg#$H-Wdu?Gf z-#$T$UzeuxpI6S(p}2!q?$V{!%o3l>`}02V_RJGMD5G^cNVzYql?OgNIJ+GL)a#&g zYx7=uYv?!F_+bARp!_$Xs>sH30H|O77gdA!zX2)$Uy#8XL*B+Z1nWQMeOi}&RillU z_!~U$Lp^V*I9yuB?mIkpPE2p=rZ=<+-?8=Lr$fSdG(7lfmnSn8jq^;gOhr?YQO-nk zMkJ$Ao<&M9c1idQWSdtQMzHpXnA`~VA~j|AaVn2W36i`5+-i*g!dx(+qD0+ua}#sV zWOJLq#>oby9d%VO?LW)MhJmpOhKdOF1)1pJC@s{L;T%d7(Y1`EOcrF!v}0J&fZ@>I zQAPm+mf_))2r`DrlzMAuaQ6iMVV<VYhT|98UuLr`zl8ep83PJo2i=BlN)s3IC=E=v z3c=2k#V933kz^C?!o;UiZ&#?#E8S-sm2e>q5tv+BmG+1;<6<z>4VKZnQ#iiMuXP|L zbPF!kkr27iZ9x9ZtFD9Obv9jJdz(+B{hO9*Z<C;CnZRyUi>OsRfeR^rMB-gI{e9e1 zY0)c^VmHYkJI;5<my_(dnm;zeYL6};R4#f`mGTdHa@I40K`1FqCwr1C9u-&GQ~3zk zCis*e0YO24w{hDFaR84~Q4b^@JVw*FrETCWt8D=qi}%5@yQRa?=)6>=V55;RS6<kL zm>*yK)*|JPOi*|WNP~&0!MX+m1_fkF3iETQ8ZI6Hr@afpOD08R%xgR!6FxBGVLDR< itU7Uzyl1R}CuvSg&i3Kwf~3LjSPe+i!8?#}!~O?_Rhjbu literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py new file mode 100644 index 0000000..61d5fb6 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/genshi.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName, Attrs +from genshi.core import START, END, TEXT, COMMENT, DOCTYPE + + +def to_genshi(walker): + """Convert a tree to a genshi tree + + :arg walker: the treewalker to use to walk the tree to convert it + + :returns: generator of genshi nodes + + """ + text = [] + for token in walker: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + text.append(token["data"]) + elif text: + yield TEXT, "".join(text), (None, -1, -1) + text = [] + + if type in ("StartTag", "EmptyTag"): + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + attrs = Attrs([(QName("{%s}%s" % attr if attr[0] is not None else attr[1]), value) + for attr, value in token["data"].items()]) + yield (START, (QName(name), attrs), (None, -1, -1)) + if type == "EmptyTag": + type = "EndTag" + + if type == "EndTag": + if token["namespace"]: + name = "{%s}%s" % (token["namespace"], token["name"]) + else: + name = token["name"] + + yield END, QName(name), (None, -1, -1) + + elif type == "Comment": + yield COMMENT, token["data"], (None, -1, -1) + + elif type == "Doctype": + yield DOCTYPE, (token["name"], token["publicId"], + token["systemId"]), (None, -1, -1) + + else: + pass # FIXME: What to do? + + if text: + yield TEXT, "".join(text), (None, -1, -1) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py new file mode 100644 index 0000000..f4ccea5 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treeadapters/sax.py @@ -0,0 +1,50 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.sax.xmlreader import AttributesNSImpl + +from ..constants import adjustForeignAttributes, unadjustForeignAttributes + +prefix_mapping = {} +for prefix, localName, namespace in adjustForeignAttributes.values(): + if prefix is not None: + prefix_mapping[prefix] = namespace + + +def to_sax(walker, handler): + """Call SAX-like content handler based on treewalker walker + + :arg walker: the treewalker to use to walk the tree to convert it + + :arg handler: SAX handler to use + + """ + handler.startDocument() + for prefix, namespace in prefix_mapping.items(): + handler.startPrefixMapping(prefix, namespace) + + for token in walker: + type = token["type"] + if type == "Doctype": + continue + elif type in ("StartTag", "EmptyTag"): + attrs = AttributesNSImpl(token["data"], + unadjustForeignAttributes) + handler.startElementNS((token["namespace"], token["name"]), + token["name"], + attrs) + if type == "EmptyTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type == "EndTag": + handler.endElementNS((token["namespace"], token["name"]), + token["name"]) + elif type in ("Characters", "SpaceCharacters"): + handler.characters(token["data"]) + elif type == "Comment": + pass + else: + assert False, "Unknown token type" + + for prefix, namespace in prefix_mapping.items(): + handler.endPrefixMapping(prefix) + handler.endDocument() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py new file mode 100644 index 0000000..d44447e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__init__.py @@ -0,0 +1,88 @@ +"""A collection of modules for building different kinds of trees from HTML +documents. + +To create a treebuilder for a new type of tree, you need to do +implement several things: + +1. A set of classes for various types of elements: Document, Doctype, Comment, + Element. These must implement the interface of ``base.treebuilders.Node`` + (although comment nodes have a different signature for their constructor, + see ``treebuilders.etree.Comment``) Textual content may also be implemented + as another node type, or not, as your tree implementation requires. + +2. A treebuilder object (called ``TreeBuilder`` by convention) that inherits + from ``treebuilders.base.TreeBuilder``. This has 4 required attributes: + + * ``documentClass`` - the class to use for the bottommost node of a document + * ``elementClass`` - the class to use for HTML Elements + * ``commentClass`` - the class to use for comments + * ``doctypeClass`` - the class to use for doctypes + + It also has one required method: + + * ``getDocument`` - Returns the root node of the complete document tree + +3. If you wish to run the unit tests, you must also create a ``testSerializer`` + method on your treebuilder which accepts a node and returns a string + containing Node and its children serialized according to the format used in + the unittests + +""" + +from __future__ import absolute_import, division, unicode_literals + +from .._utils import default_etree + +treeBuilderCache = {} + + +def getTreeBuilder(treeType, implementation=None, **kwargs): + """Get a TreeBuilder class for various types of trees with built-in support + + :arg treeType: the name of the tree type required (case-insensitive). Supported + values are: + + * "dom" - A generic builder for DOM implementations, defaulting to a + xml.dom.minidom based implementation. + * "etree" - A generic builder for tree implementations exposing an + ElementTree-like interface, defaulting to xml.etree.cElementTree if + available and xml.etree.ElementTree if not. + * "lxml" - A etree-based builder for lxml.etree, handling limitations + of lxml's implementation. + + :arg implementation: (Currently applies to the "etree" and "dom" tree + types). A module implementing the tree type e.g. xml.etree.ElementTree + or xml.etree.cElementTree. + + :arg kwargs: Any additional options to pass to the TreeBuilder when + creating it. + + Example: + + >>> from html5lib.treebuilders import getTreeBuilder + >>> builder = getTreeBuilder('etree') + + """ + + treeType = treeType.lower() + if treeType not in treeBuilderCache: + if treeType == "dom": + from . import dom + # Come up with a sane default (pref. from the stdlib) + if implementation is None: + from xml.dom import minidom + implementation = minidom + # NEVER cache here, caching is done in the dom submodule + return dom.getDomModule(implementation, **kwargs).TreeBuilder + elif treeType == "lxml": + from . import etree_lxml + treeBuilderCache[treeType] = etree_lxml.TreeBuilder + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeBuilder + else: + raise ValueError("""Unrecognised treebuilder "%s" """ % treeType) + return treeBuilderCache.get(treeType) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2a2ff0fd728f7c2ea28261696cc61f48f6691f3f GIT binary patch literal 3277 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/base.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2f5878faa958e3215b5bf471599f62faeac5e92e GIT binary patch literal 11200 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/dom.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..981e291bbfb9719cc5b3a5c1a0ea21539f124ae5 GIT binary patch literal 9230 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4615a21bcf13e14de4a8b6ff1f962d07363e288d GIT binary patch literal 11809 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 GUHo6NOPHGg literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/__pycache__/etree_lxml.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..607b23703c9714480200e386dc31e40a09a1403c GIT binary patch literal 11749 zcmb7KTZ|l6TCQ7nS65%=;_-OwI7zP)C!Q$2?2=7ZyT&B(C9!a3Eqk)w?M=4n>8hFO zo}TXUscPHP+XG9+A`T)_ctHrErRR|+UXVZt5CRDSPrwVS5-$i|@&E!UJP;wl_x-1; zyJtM!WV=<TPMve=od5sNe?RqRspJ{>Re$e=_g;F<F#eSf>CZvsbzI?3Q20jG@J-)p zo10eE+O(_orc-rHw%P4WH6!<IH7oaAHRn5irtNO#t9gvc`nk5ZS*RAI?xNkRdZ;^o z9`$0iB<&vR<!Tvq&N+qlBI<?ebdVj+_{BZ5IvW&+NBq*B*_x{!earC6{?tRmp9<!8 z?dmZ+Px~`?o{{GTf7U<p(5N2w=lr9%pFsb-e+>P{f_&>Kyz!K8-!>K(>VIV##yefV z*A6PHT~!HtTU%WfH9KpSXg#R3A8fYI1(6C+ZLX-g+CEoVMtjo_>Xr3Cp%zx6ZlxCn zm3mm&>^0WC?y9`nsYlIwqu1EG)eXbuN;`PDa=#g^cY6_D<3g*dzShM0>-EM)h;=rC zN~0G>-OWnS4mN{M<aO$s0oGZsN0k*7)Hf<CL3BR|Iu(Tx^)LuERDSn<Cj@8}0RfN^ zIKFfrGuAtuZiE-MR1k8`db>S>s6q_GZ&kvrpwV1yHqf^%NUV0-?e2X7SqH8g9V|d} z8+9VQrMkdoGyJCKEe8*x3dq;!ZW7>-=n_}F8ER;Pit1wh6r(HM#`YF)A|)!FZiN_n z-ko*eRPSsjuV9U6T~E<y^c3h8RD#WBRH;|4)T8<h(DP1RbuhyF6kKX7+VNC<CG56) zQBZ4cawB8cZ{BN$&2A^2?sb}tt{>Fe%_vaycDVE@_TE@DV`l|4{M6D9QwOF-f4<S} zgi#%M;UOdJz}8w5v<<)^%l*<1&wT#}JMX`=xO3**ON+5x5B&xqN`IXDbzI>biomFv zkSGhBZh<##;Y24cf+jsuZyA(nQ2zMioo`>p70#m=m;<9`3@nu9z(#5L1~}PV0`?Bc z7`t0NP`+{9kKJ%PjDpSU{-P5*VbESxWz3+aSWKh%eM8OS_W3*Kqs^`JTg|PrO(NQE zpKaV<>$IY~udq?B+P$FTch&jzXtVuw$ijKD%u27>_5&537n;;WTDG=hw^nO*no+Ix z93~I5C=4@;fB)ztis#Z%OMniq5cXOv_G-0Fkw?^vwc6cYy{&r`X(#Yb6i3)rLU9UL zNJ6=$JReT}moeaR^7{_90V>PS;+_ezL1x#463c<CZtSKoH^?pg@jluTlF>J~C2K6P zv3fHs0G}}XGAI=nYK?UeYY7YpE>bgi?I0S&?<HKJ>^<o<lde6YRf7xj$GeSd%oj$> z7@B*=&>EO6d(VXSOh9qeaSV)eYuF{oU^Q3w{SE{cL{A`Gv;?3ympmVUEH2cywy^z| ziNQI{C4@H2{@e(@i2?iQL|O@m<bnY})YLK62|OQ8hqzn=q_UP!>#GwB9vdyVf6UUN ztBzuvqJ*epEQDL0VeMHI5DL}Z3RJWmd*h9mz>{*Igqs#nTf`N*C|uKZT-&u3TlZnc zP2vWGucBBpJ~AVtWm2R+Ha{}_+=s@8=7-j*O;h+V|B>|w0_)qm7LDD|dSvdI<gTS< zD3aq)$&jw-N*8h)T&aiamlHLrNWRgQlg$Yep$xBJ?Fbb0&0XsgGyI0stzAp~<s)+l z6G{dEy{(q5`f_)|YjV$o*L+86*?D8f>YVU1`bm${V^(eU$xJZc1Jiep8FNrNtJb`s zXCCJEj2-*I!oVK7dtkMVy!sto-?8sLykk80t${7Ae-6xTJp-}Fm^|OS`{O%CM@8Pi zhzh$__!FrWiHj<ZT0e_Qt+Jm#Zusto6@C^?eP9Yq9$^AJMhZ{ojI<XB+k=w><BIYA z+>X6}<xkAJC+`@aSREHQPDe8vT<bUFy<$3FYc`!x=ve|hwt5}okMO>K?beZW>?daD z4+ZAA)=}Aw9~07OzIAN4z_s?w9cSQ>8d&kOfipbrm(iAynu}UCI?;M+kU4Jb<YbMh z1fJX@V|a3q-7~o##I5s;^iS)4>6Q6YNCfH`z+kDrTQhdt2MX&yJ$z=56!G7)cJe!3 zM5yu;Fj?vWAbEDrK!0W@FSD{gKZeSm9pnaiuCi0;c%u=8fjcw@g@Lzf5xP&TyXUa; zUyCXOch|&<FX$Bo<|BkT;iEj>NHD@X!#m{ES-|`sV+toD(VpVQw_h`MOz<4BncgX4 ze~Sa~zpVVfceFe_anF2rfjo@8OlK4YIkyzsQGHE41*z)ipYszV+%H}H%9U?lUjE+A ztCiE?rT($W$I7YG;VCID^)rLh;py;mv!ZgCK_s@HLmP+mXGim$rI$zR-Y=u`;#ba| z#k7^PXD`K0RByIbhRb{GLNgcS9H?K4v-K!a&6R#eI%Lf0@aH-G;#cC_dOc)6Mv01! zb3mZkS?$J!W(RIgr{2D@d?n6nm!Q`4tDg1=YCYAC^Rx$Icm@4x0g9K(sM+m>RoV+N z6CV60@qZdYY=>AYv$7opA?n*<T)YSS5BCZdAB&dX2tz1YJYQ9+tJHJADlR5oVJ(7V z19V|})M?U+(MQ#-UDaN0T-IJh>QuxYwxy<mwcx>4oY|~LjrBOQrn<c?mFKk3=)r39 z0RSnis_y1@H``0_Ak+)&%fQ9k4CAZ}$328A82F1N^)!34&5n<q0Iedw2860b;+Y!5 zIM)gFYE~!I7-aQQv8T5J?qw*RRGhh2Z}(u_+0L2ZipCkSFYv}nBuN-V*P3nYL~N;h z@ieH@thbx}AVFGNAhA2w0ou24g%JwFESjF>nXo_jmn};isG@m-PwYckHs`IA=7R0v zX#s5u=A3!bnngQX_%EBYR#7eoeQe>IXvfTR7<tNa&6AkXGpEttKLfm?+bM+V+{Jbm zp+I=)+(D>g(}V4%aay!h0k^nxeIKq)tJ~~g2+1udV%%G-zs-V}imi>y`&UE|YJ?J# znvPktX0LgcdIxR$3@?qY7~bbmf#Ef1YFD*4?S2FUF)((ajC^}&Jc81MnRWWFjIcs@ zkp>~C`jsYv71=OEA#lwY-P9|3Cr7K&)Kfmi@FFZ78Q$=1s1vhgsc*{NR?qAEj@c>t zF!<<mpfXJ;%*+5L-!ur_FuNxZc7_;{i(uN+Do6P6=3DtyGg0*);K>VrBt10PxlzwK zKQk;au6{^$<_(Kf@4J{ECY$rnz~v^5bt|v_LSVrBVj|~6g%)8V5krt#cmMhhsD*d) zlPifi@x&-|&JxU*o6LhaJn=9KOClr(6=t3~?sNzZ*LSGL6t`<cQf?qgdK*`G5(T~I z_vc_QfCT($Q-lAT)?J4lV?URuyo8xz>)Zt$%Ur>`6K)*0=yUI4yBS8%I$M{1m-EwC zhBy6c)YTjNWX2x%jHl@5Qk9&!c%Fz*cP*CHi?}H|ii%FVC|)W!#TY}KVL_83v{66D z+AA!mp41H%lyyCqqvhlm&=5ORCF&ZgaLUKhGImcXJim@B<f;ZlmkPpzm?vWGWFgvG zptF!6h`cpxLAXzSG4?S%a>BMxawowcd1E)7>DTZiUb101R=MI@ird-1HTqF>_zU|e z(#R{Yt4@$%x(HF0S#|N854>u@KkCC@erQ&UNi0_KbH0n13_hUm;XdUT{37nte#tN6 zK7*vrls}C(X8mIy8mp#1<Ig_KSC9Bd{5kZ`eTewEdK4VA5EmGRy{QA%rE3i`Ab(^+ z0?Fr)bfp^~Sp(>kk1aU$cFXZC-~QNijE@*|Lyl2q-!kCbo8sKNekRK8+8-HcOPzko zrt8C*Yq`7jj*T7$1D5ald9>%zo=3YQ@w+#Gbk_<|u~izD2Vng@1_=z5yd^{j?rN{y zChQ0m)F}XXIDN@iDSiE{&;nqC7PizGg}8`usSb1fGZVBJg_dL9e?uG&TDhftbfSYp z4hZj|0ELVVR~4HG6m(7^G7)>Co$x=n1wChr+j$K_ZSPnSu#GYZP`=|s=lIrf>YFTT z_Hk%waV;HjEzu^<DfK7+xq)-hxO?V~riruE&;IaqxN|zx{ucKS!5>vf?D)+_qys+@ zuCr{+M7^zc5KlF_focRJ)I<;$Gdd6#Geu1j+Z(~QC>9V~4Axli7*PHhu8>UzgwBCY zhINJDorIY6zxri~I->Z9xMaXAE+OtsR3e1(WCak@HVv>N7!jm<1*AiSDWr2y8<Wl! z(xDBcvzZ)fW$*_nFa8v=<<xhu7E%*6cq#OlYBfcgsXHvb%Yt;(q;fQ=zQ+cV>Iqb; zqU&#QC1#wyh*0O1pMg3fXqeT?92(ej8Ep#=?o;fI_Bi}g0z%@#X)3DkqjI?LJU~w> zJR=!qcFu+PP|m5AAU;xOn#k2@qQKd;pu)70az)Uns9dPCY~TiY^m_huBKt+Z1aU0D zS1~1b?Ly5JAdWNr(?6XyiK{r`7OE<;y>JVyz$0r&wPC{1FzJqH&Vd30?>vHC-KEMx zG>*kAs+2qvYT;JB5g_wc(t?pX;knc?CA)()XpWjI)CF+iBx@xp#P`sP29h++B_8`> z0`rd;5R$cNsb<aoxi5w4SVAV#UED~)`FT{JJOpQ82JEPKTDT+e#hO#gq{*+WdLN_X zj6^xe$swq@N*I>wYe+SY2%#DMISfs5VTZFfQf6RI#u@*Fp$TF|Xo4?|Sn~SF5uy{# z4Hd+Ss0d;}Mm$&WKb%XnsyYhjB<{dtstHg5EkgCr=uVS!UzXI#tNS1#RJS=7w+;j) z>i`y0)$p8valq@+X}huP{R>~0?KAsdAp8l-og)_G2}XG@PBJ19^R47*#{JlPt=-0; z=|rZwtidFEYA{J&KnUuO7x*`{{j3n~n_z4m3EoH~nRG-VBNa*PrP#$pnWv0t$J1K! zF0a>By@3cZR6ih;9)fMe&^%H}L=J`x#~pD|cf1+kpeg`g{1QeVl({C_KE;*fkYScC zd^w35FS?KJBblSodjv+%c4_3I2!j%AMXXcVxyHJw0UR4pj`(+6Db2sYV5VF#ky<7X zmJYQCKIT;ciwX<TQLC)2u^>Arl18A^c0((#Ly1Uy{sEU*de@xJ6f;HJvs|0yv?JTp zK>z5+?dLE228u~Tl7^))BUJl|8JRq3NKFU?%>5!ma9O8?58ohK>chBha;uP&NO(@q z6z7sD#c4`+uZ5YOz+N;8|AlMJUSFVPlKBr;=p>uyJ!b7wg}wt9hsu27TuZgluQfDd zsC{rgX8uJ(^9=95G4yAL69Uec57&mwzEc~v=tc|clj;)KJwYjoX6A(dLue9p_+@DZ zb;wtrbhy#s+FceE7Th+?+J~!#P4xdKuH;;!>=bdbq1d`OrM`|^T*iW89QA>?<mV*4 zqka+HqH5x!Ba`{|@;f&Y84bme6uFQI<6@w5dY9Yv5II7G;!J(YlcGsc%Ph!EsSAFW z4ezoLZ9=e~AgAOQdG(J_Nt|&cy3DLKcl5-w3uT-%TK&1hwBEi=CG%b849}xr&_^ZB zqy{#a$EuE;=fRIaJ)0`++!*>e!-MoFp3|B$Vf5=b_e6q^xj!oLq&1%Ac_`Xz2_-^B zFaL0!Q4zXqSYRDmBgAkKX!K_$F_NYC=>f8qphF%--p1Tbc+`{(S}HT6gxuIHN<Ti- z7_sMx$(8me==M=?v?PTfGE|Xb+p=zxg19sMyFIecj%+TD<CFZloJmTC<Zvp)%tfcC zeayKf&X!}kR{z)}gcIXN;Bj+lx`ZOMMmP+iR>5)EaR7&i)k4<p)W94fSZc}P1?o<e z8CcAtfeEZuR=t_@;{XONq^Gr{v!1!Qh||Q*i2X-uKoUQ37PcGbrLn_2l+N*J=NZv_ zatts|jgEIhaK4rdm?h5ib_}?eMF};_Qa*-#`o@SK7^l-45$xAdL8u748K*ONM1Uxv zBk~Vcc!8m&??e){3$xpuS3oHT8B5Rwhg7(4*y^T?%jj{;VWQn0ID7U^c94aL=<p)D zq)qSW3xoc1{3zhDuTSt9$5ymm0W&aV)<1ptpiZ}QmTxD+7IU$CUw`ir#tv(W%r2s& z{UCAmi^*`&Hj6oNnUMwPZUmhJz*P&{8v1md^)%wGj9ivfjKPP5^CY)~wu;d|{uVdJ zMe5B(lC5m^k596tRshMH`(igTr)<rusOU6GI4?0f5-Q<*WPTv5+L8oI_(Jk*4<))! zQbRC48O5+weT@YV_|<(DXHcY(8ZAPc-NL6kok(-p2s70~-^*jMn#T!1zw$Wz`_<Y$ zG$>z0C43V_0=}hQrj${c?rB-GBM15Im!r%u>swKd-bmy|$TII*Lr)SMX|~H=`t<+s z>%V?DGt~VS0@hA6{>Eq}*zO{O&+oJ*zby(E3z{-Ql&1jPL=N^>`1m6hWSuyJ@4W)0 zt<gO+Oj1rgWCOqRsWoWEkQ^D2FP_<_-`}Y>J6|O+IVmIEc`!!*=_itt<44lU^OKRZ z{xN3psh>ba92E;K!4ei&!jcmO(01OyF{q4aLFzX0;UyU-2h8g4F^=a5ptrQzTeo~@ zw25~d^*4Gv^ng9Yw|aY~pV`Q$AIlSToqmekVcyS09(N2q1>`#2J!JCsz4IqnEkD3f zE+M+hwY~HS$LyA05J)Y*ID(i7tkQ7<8s#%tp`5H>`BNMd6^A9!JI;fb0A(2my%p#n zV>mU)_|wc3Lf<&U=|Q$NL#>QM{W6b_hqHS$)JM=a$6D)1?WkU92glCCd4C3N#{j=O zaGAHnNk(Uo+sWgcW_I8Xa*}_{5Ap-2hU4YoaU6FOTjplH8s9zAIx&1|;E5$LS|=y! zPh;I@#6dW+q;6p|`^Cw#;(n=e^W8UZT)(UjjXyVE6ch5fd8+?vdcdrYWK%7Pug!2I z+`$KQoi%(G$Wtm`J`Jhd?R8;~tJ!xiT)6PH*ZPi}F*`4w4qxnBFTVJ>c}Wyp|E<F% zDA9}ho4b0&Z?3N53r0v3T{<3o9h9X0^B0%jzJ9xQ`|WSPd*e!N>FRf`-m1NE^XAnz zZq+nSH@<iNl6E}bBjQPBcJW!QOeG2v{WP)%+KEi`?#<px6Gn0s$Fb^wVCL|lVjJ=< zK4|RmfLEX0Xe}3FwQ2$1F{P)~5*@@PpeUcvX-|{-QO>lf9wH=t^oLM3JcfAM4_52F zwq#8t6{eMh!YlG^k|<KeQw#Nog=mL@&VYTud9zsSHV?zGdBlQiFuW2^w<hK$&Lxl9 z?vO-rULSJfXuDdJ)Az(vKA@k|EWj<y`WiJ0k7bOEPB~9QyD;grAZF;KJmEOlD&sg8 z;VPbSB4ihN{A=U<$L5i-2d@}j1X{CrD%$<|$F&m|TQsjpre|q!{$QZJ00`74EJ`eX zm4(oYyAhXC&qmYUV_O*?Vd_8tAH#M#IyF!CR(wvi&Dt-s*kwVJq>268sKup3?>2&V zJJr3j=zzcYAxBCau#DOt;0l>sU`l@Ux4au}7N2fqUC*8NGUcpj`NflQu2#d==`Rge zdr?o}t3yR!R?(U%nl<4@9M}iy0-tWNkgz4s8kM|`jTkjafK>G;a{5bQ?dWprxA0Z3 zqLG)NXl#YzY<Hy<;HX0AC}e$yqi(YxMib0HjP+T$dr^NEd5NTzsKv47u(xzX$Pe<j SinhbkKzlkjU3S0iF8)6pFwqhK literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py new file mode 100644 index 0000000..73973db --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/base.py @@ -0,0 +1,417 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from ..constants import scopingElements, tableInsertModeElements, namespaces + +# The scope markers are inserted when entering object elements, +# marquees, table cells, and table captions, and are used to prevent formatting +# from "leaking" into tables, object elements, and marquees. +Marker = None + +listElementsMap = { + None: (frozenset(scopingElements), False), + "button": (frozenset(scopingElements | set([(namespaces["html"], "button")])), False), + "list": (frozenset(scopingElements | set([(namespaces["html"], "ol"), + (namespaces["html"], "ul")])), False), + "table": (frozenset([(namespaces["html"], "html"), + (namespaces["html"], "table")]), False), + "select": (frozenset([(namespaces["html"], "optgroup"), + (namespaces["html"], "option")]), True) +} + + +class Node(object): + """Represents an item in the tree""" + def __init__(self, name): + """Creates a Node + + :arg name: The tag name associated with the node + + """ + # The tag name assocaited with the node + self.name = name + # The parent of the current node (or None for the document node) + self.parent = None + # The value of the current node (applies to text nodes and comments) + self.value = None + # A dict holding name -> value pairs for attributes of the node + self.attributes = {} + # A list of child nodes of the current node. This must include all + # elements but not necessarily other node types. + self.childNodes = [] + # A list of miscellaneous flags that can be set on the node. + self._flags = [] + + def __str__(self): + attributesStr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in + self.attributes.items()]) + if attributesStr: + return "<%s %s>" % (self.name, attributesStr) + else: + return "<%s>" % (self.name) + + def __repr__(self): + return "<%s>" % (self.name) + + def appendChild(self, node): + """Insert node as a child of the current node + + :arg node: the node to insert + + """ + raise NotImplementedError + + def insertText(self, data, insertBefore=None): + """Insert data as text in the current node, positioned before the + start of node insertBefore or to the end of the node's text. + + :arg data: the data to insert + + :arg insertBefore: True if you want to insert the text before the node + and False if you want to insert it after the node + + """ + raise NotImplementedError + + def insertBefore(self, node, refNode): + """Insert node as a child of the current node, before refNode in the + list of child nodes. Raises ValueError if refNode is not a child of + the current node + + :arg node: the node to insert + + :arg refNode: the child node to insert the node before + + """ + raise NotImplementedError + + def removeChild(self, node): + """Remove node from the children of the current node + + :arg node: the child node to remove + + """ + raise NotImplementedError + + def reparentChildren(self, newParent): + """Move all the children of the current node to newParent. + This is needed so that trees that don't store text as nodes move the + text in the correct way + + :arg newParent: the node to move all this node's children to + + """ + # XXX - should this method be made more general? + for child in self.childNodes: + newParent.appendChild(child) + self.childNodes = [] + + def cloneNode(self): + """Return a shallow copy of the current node i.e. a node with the same + name and attributes but with no parent or child nodes + """ + raise NotImplementedError + + def hasContent(self): + """Return true if the node has children or text, false otherwise + """ + raise NotImplementedError + + +class ActiveFormattingElements(list): + def append(self, node): + equalCount = 0 + if node != Marker: + for element in self[::-1]: + if element == Marker: + break + if self.nodesEqual(element, node): + equalCount += 1 + if equalCount == 3: + self.remove(element) + break + list.append(self, node) + + def nodesEqual(self, node1, node2): + if not node1.nameTuple == node2.nameTuple: + return False + + if not node1.attributes == node2.attributes: + return False + + return True + + +class TreeBuilder(object): + """Base treebuilder implementation + + * documentClass - the class to use for the bottommost node of a document + * elementClass - the class to use for HTML Elements + * commentClass - the class to use for comments + * doctypeClass - the class to use for doctypes + + """ + # pylint:disable=not-callable + + # Document class + documentClass = None + + # The class to use for creating a node + elementClass = None + + # The class to use for creating comments + commentClass = None + + # The class to use for creating doctypes + doctypeClass = None + + # Fragment class + fragmentClass = None + + def __init__(self, namespaceHTMLElements): + """Create a TreeBuilder + + :arg namespaceHTMLElements: whether or not to namespace HTML elements + + """ + if namespaceHTMLElements: + self.defaultNamespace = "http://www.w3.org/1999/xhtml" + else: + self.defaultNamespace = None + self.reset() + + def reset(self): + self.openElements = [] + self.activeFormattingElements = ActiveFormattingElements() + + # XXX - rename these to headElement, formElement + self.headPointer = None + self.formPointer = None + + self.insertFromTable = False + + self.document = self.documentClass() + + def elementInScope(self, target, variant=None): + + # If we pass a node in we match that. if we pass a string + # match any node with that name + exactNode = hasattr(target, "nameTuple") + if not exactNode: + if isinstance(target, text_type): + target = (namespaces["html"], target) + assert isinstance(target, tuple) + + listElements, invert = listElementsMap[variant] + + for node in reversed(self.openElements): + if exactNode and node == target: + return True + elif not exactNode and node.nameTuple == target: + return True + elif (invert ^ (node.nameTuple in listElements)): + return False + + assert False # We should never reach this point + + def reconstructActiveFormattingElements(self): + # Within this algorithm the order of steps described in the + # specification is not quite the same as the order of steps in the + # code. It should still do the same though. + + # Step 1: stop the algorithm when there's nothing to do. + if not self.activeFormattingElements: + return + + # Step 2 and step 3: we start with the last element. So i is -1. + i = len(self.activeFormattingElements) - 1 + entry = self.activeFormattingElements[i] + if entry == Marker or entry in self.openElements: + return + + # Step 6 + while entry != Marker and entry not in self.openElements: + if i == 0: + # This will be reset to 0 below + i = -1 + break + i -= 1 + # Step 5: let entry be one earlier in the list. + entry = self.activeFormattingElements[i] + + while True: + # Step 7 + i += 1 + + # Step 8 + entry = self.activeFormattingElements[i] + clone = entry.cloneNode() # Mainly to get a new copy of the attributes + + # Step 9 + element = self.insertElement({"type": "StartTag", + "name": clone.name, + "namespace": clone.namespace, + "data": clone.attributes}) + + # Step 10 + self.activeFormattingElements[i] = element + + # Step 11 + if element == self.activeFormattingElements[-1]: + break + + def clearActiveFormattingElements(self): + entry = self.activeFormattingElements.pop() + while self.activeFormattingElements and entry != Marker: + entry = self.activeFormattingElements.pop() + + def elementInActiveFormattingElements(self, name): + """Check if an element exists between the end of the active + formatting elements and the last marker. If it does, return it, else + return false""" + + for item in self.activeFormattingElements[::-1]: + # Check for Marker first because if it's a Marker it doesn't have a + # name attribute. + if item == Marker: + break + elif item.name == name: + return item + return False + + def insertRoot(self, token): + element = self.createElement(token) + self.openElements.append(element) + self.document.appendChild(element) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + doctype = self.doctypeClass(name, publicId, systemId) + self.document.appendChild(doctype) + + def insertComment(self, token, parent=None): + if parent is None: + parent = self.openElements[-1] + parent.appendChild(self.commentClass(token["data"])) + + def createElement(self, token): + """Create an element but don't insert it anywhere""" + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + return element + + def _getInsertFromTable(self): + return self._insertFromTable + + def _setInsertFromTable(self, value): + """Switch the function used to insert an element from the + normal one to the misnested table one and back again""" + self._insertFromTable = value + if value: + self.insertElement = self.insertElementTable + else: + self.insertElement = self.insertElementNormal + + insertFromTable = property(_getInsertFromTable, _setInsertFromTable) + + def insertElementNormal(self, token): + name = token["name"] + assert isinstance(name, text_type), "Element %s not unicode" % name + namespace = token.get("namespace", self.defaultNamespace) + element = self.elementClass(name, namespace) + element.attributes = token["data"] + self.openElements[-1].appendChild(element) + self.openElements.append(element) + return element + + def insertElementTable(self, token): + """Create an element and insert it into the tree""" + element = self.createElement(token) + if self.openElements[-1].name not in tableInsertModeElements: + return self.insertElementNormal(token) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + if insertBefore is None: + parent.appendChild(element) + else: + parent.insertBefore(element, insertBefore) + self.openElements.append(element) + return element + + def insertText(self, data, parent=None): + """Insert text data.""" + if parent is None: + parent = self.openElements[-1] + + if (not self.insertFromTable or (self.insertFromTable and + self.openElements[-1].name + not in tableInsertModeElements)): + parent.insertText(data) + else: + # We should be in the InTable mode. This means we want to do + # special magic element rearranging + parent, insertBefore = self.getTableMisnestedNodePosition() + parent.insertText(data, insertBefore) + + def getTableMisnestedNodePosition(self): + """Get the foster parent element, and sibling to insert before + (or None) when inserting a misnested table node""" + # The foster parent element is the one which comes before the most + # recently opened table element + # XXX - this is really inelegant + lastTable = None + fosterParent = None + insertBefore = None + for elm in self.openElements[::-1]: + if elm.name == "table": + lastTable = elm + break + if lastTable: + # XXX - we should really check that this parent is actually a + # node here + if lastTable.parent: + fosterParent = lastTable.parent + insertBefore = lastTable + else: + fosterParent = self.openElements[ + self.openElements.index(lastTable) - 1] + else: + fosterParent = self.openElements[0] + return fosterParent, insertBefore + + def generateImpliedEndTags(self, exclude=None): + name = self.openElements[-1].name + # XXX td, th and tr are not actually needed + if (name in frozenset(("dd", "dt", "li", "option", "optgroup", "p", "rp", "rt")) and + name != exclude): + self.openElements.pop() + # XXX This is not entirely what the specification says. We should + # investigate it more closely. + self.generateImpliedEndTags(exclude) + + def getDocument(self): + """Return the final tree""" + return self.document + + def getFragment(self): + """Return the final fragment""" + # assert self.innerHTML + fragment = self.fragmentClass() + self.openElements[0].reparentChildren(fragment) + return fragment + + def testSerializer(self, node): + """Serialize the subtree of node in the format required by unit tests + + :arg node: the node from which to start serializing + + """ + raise NotImplementedError diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py new file mode 100644 index 0000000..dcfac22 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/dom.py @@ -0,0 +1,236 @@ +from __future__ import absolute_import, division, unicode_literals + + +from collections import MutableMapping +from xml.dom import minidom, Node +import weakref + +from . import base +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + + +def getDomBuilder(DomImplementation): + Dom = DomImplementation + + class AttrList(MutableMapping): + def __init__(self, element): + self.element = element + + def __iter__(self): + return iter(self.element.attributes.keys()) + + def __setitem__(self, name, value): + if isinstance(name, tuple): + raise NotImplementedError + else: + attr = self.element.ownerDocument.createAttribute(name) + attr.value = value + self.element.attributes[name] = attr + + def __len__(self): + return len(self.element.attributes) + + def items(self): + return list(self.element.attributes.items()) + + def values(self): + return list(self.element.attributes.values()) + + def __getitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + return self.element.attributes[name].value + + def __delitem__(self, name): + if isinstance(name, tuple): + raise NotImplementedError + else: + del self.element.attributes[name] + + class NodeBuilder(base.Node): + def __init__(self, element): + base.Node.__init__(self, element.nodeName) + self.element = element + + namespace = property(lambda self: hasattr(self.element, "namespaceURI") and + self.element.namespaceURI or None) + + def appendChild(self, node): + node.parent = self + self.element.appendChild(node.element) + + def insertText(self, data, insertBefore=None): + text = self.element.ownerDocument.createTextNode(data) + if insertBefore: + self.element.insertBefore(text, insertBefore.element) + else: + self.element.appendChild(text) + + def insertBefore(self, node, refNode): + self.element.insertBefore(node.element, refNode.element) + node.parent = self + + def removeChild(self, node): + if node.element.parentNode == self.element: + self.element.removeChild(node.element) + node.parent = None + + def reparentChildren(self, newParent): + while self.element.hasChildNodes(): + child = self.element.firstChild + self.element.removeChild(child) + newParent.element.appendChild(child) + self.childNodes = [] + + def getAttributes(self): + return AttrList(self.element) + + def setAttributes(self, attributes): + if attributes: + for name, value in list(attributes.items()): + if isinstance(name, tuple): + if name[0] is not None: + qualifiedName = (name[0] + ":" + name[1]) + else: + qualifiedName = name[1] + self.element.setAttributeNS(name[2], qualifiedName, + value) + else: + self.element.setAttribute( + name, value) + attributes = property(getAttributes, setAttributes) + + def cloneNode(self): + return NodeBuilder(self.element.cloneNode(False)) + + def hasContent(self): + return self.element.hasChildNodes() + + def getNameTuple(self): + if self.namespace is None: + return namespaces["html"], self.name + else: + return self.namespace, self.name + + nameTuple = property(getNameTuple) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + def documentClass(self): + self.dom = Dom.getDOMImplementation().createDocument(None, None, None) + return weakref.proxy(self) + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + domimpl = Dom.getDOMImplementation() + doctype = domimpl.createDocumentType(name, publicId, systemId) + self.document.appendChild(NodeBuilder(doctype)) + if Dom == minidom: + doctype.ownerDocument = self.dom + + def elementClass(self, name, namespace=None): + if namespace is None and self.defaultNamespace is None: + node = self.dom.createElement(name) + else: + node = self.dom.createElementNS(namespace, name) + + return NodeBuilder(node) + + def commentClass(self, data): + return NodeBuilder(self.dom.createComment(data)) + + def fragmentClass(self): + return NodeBuilder(self.dom.createDocumentFragment()) + + def appendChild(self, node): + self.dom.appendChild(node.element) + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + return self.dom + + def getFragment(self): + return base.TreeBuilder.getFragment(self).element + + def insertText(self, data, parent=None): + data = data + if parent != self: + base.TreeBuilder.insertText(self, data, parent) + else: + # HACK: allow text nodes as children of the document node + if hasattr(self.dom, '_child_node_types'): + # pylint:disable=protected-access + if Node.TEXT_NODE not in self.dom._child_node_types: + self.dom._child_node_types = list(self.dom._child_node_types) + self.dom._child_node_types.append(Node.TEXT_NODE) + self.dom.appendChild(self.dom.createTextNode(data)) + + implementation = DomImplementation + name = None + + def testSerializer(element): + element.normalize() + rv = [] + + def serializeElement(element, indent=0): + if element.nodeType == Node.DOCUMENT_TYPE_NODE: + if element.name: + if element.publicId or element.systemId: + publicId = element.publicId or "" + systemId = element.systemId or "" + rv.append("""|%s<!DOCTYPE %s "%s" "%s">""" % + (' ' * indent, element.name, publicId, systemId)) + else: + rv.append("|%s<!DOCTYPE %s>" % (' ' * indent, element.name)) + else: + rv.append("|%s<!DOCTYPE >" % (' ' * indent,)) + elif element.nodeType == Node.DOCUMENT_NODE: + rv.append("#document") + elif element.nodeType == Node.DOCUMENT_FRAGMENT_NODE: + rv.append("#document-fragment") + elif element.nodeType == Node.COMMENT_NODE: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.nodeValue)) + elif element.nodeType == Node.TEXT_NODE: + rv.append("|%s\"%s\"" % (' ' * indent, element.nodeValue)) + else: + if (hasattr(element, "namespaceURI") and + element.namespaceURI is not None): + name = "%s %s" % (constants.prefixes[element.namespaceURI], + element.nodeName) + else: + name = element.nodeName + rv.append("|%s<%s>" % (' ' * indent, name)) + if element.hasAttributes(): + attributes = [] + for i in range(len(element.attributes)): + attr = element.attributes.item(i) + name = attr.nodeName + value = attr.value + ns = attr.namespaceURI + if ns: + name = "%s %s" % (constants.prefixes[ns], attr.localName) + else: + name = attr.nodeName + attributes.append((name, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + indent += 2 + for child in element.childNodes: + serializeElement(child, indent) + serializeElement(element, 0) + + return "\n".join(rv) + + return locals() + + +# The actual means to get a module! +getDomModule = moduleFactoryFactory(getDomBuilder) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py new file mode 100644 index 0000000..0dedf44 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree.py @@ -0,0 +1,340 @@ +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +from pip._vendor.six import text_type + +import re + +from . import base +from .. import _ihatexml +from .. import constants +from ..constants import namespaces +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation, fullTree=False): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class Element(base.Node): + def __init__(self, name, namespace=None): + self._name = name + self._namespace = namespace + self._element = ElementTree.Element(self._getETreeTag(name, + namespace)) + if namespace is None: + self.nameTuple = namespaces["html"], self._name + else: + self.nameTuple = self._namespace, self._name + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getETreeTag(self, name, namespace): + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + return etree_tag + + def _setName(self, name): + self._name = name + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getName(self): + return self._name + + name = property(_getName, _setName) + + def _setNamespace(self, namespace): + self._namespace = namespace + self._element.tag = self._getETreeTag(self._name, self._namespace) + + def _getNamespace(self): + return self._namespace + + namespace = property(_getNamespace, _setNamespace) + + def _getAttributes(self): + return self._element.attrib + + def _setAttributes(self, attributes): + # Delete existing attributes first + # XXX - there may be a better way to do this... + for key in list(self._element.attrib.keys()): + del self._element.attrib[key] + for key, value in attributes.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], key[1]) + else: + name = key + self._element.set(name, value) + + attributes = property(_getAttributes, _setAttributes) + + def _getChildNodes(self): + return self._childNodes + + def _setChildNodes(self, value): + del self._element[:] + self._childNodes = [] + for element in value: + self.insertChild(element) + + childNodes = property(_getChildNodes, _setChildNodes) + + def hasContent(self): + """Return true if the node has children or text""" + return bool(self._element.text or len(self._element)) + + def appendChild(self, node): + self._childNodes.append(node) + self._element.append(node._element) + node.parent = self + + def insertBefore(self, node, refNode): + index = list(self._element).index(refNode._element) + self._element.insert(index, node._element) + node.parent = self + + def removeChild(self, node): + self._childNodes.remove(node) + self._element.remove(node._element) + node.parent = None + + def insertText(self, data, insertBefore=None): + if not(len(self._element)): + if not self._element.text: + self._element.text = "" + self._element.text += data + elif insertBefore is None: + # Insert the text as the tail of the last child element + if not self._element[-1].tail: + self._element[-1].tail = "" + self._element[-1].tail += data + else: + # Insert the text before the specified node + children = list(self._element) + index = children.index(insertBefore._element) + if index > 0: + if not self._element[index - 1].tail: + self._element[index - 1].tail = "" + self._element[index - 1].tail += data + else: + if not self._element.text: + self._element.text = "" + self._element.text += data + + def cloneNode(self): + element = type(self)(self.name, self.namespace) + for name, value in self.attributes.items(): + element.attributes[name] = value + return element + + def reparentChildren(self, newParent): + if newParent.childNodes: + newParent.childNodes[-1]._element.tail += self._element.text + else: + if not newParent._element.text: + newParent._element.text = "" + if self._element.text is not None: + newParent._element.text += self._element.text + self._element.text = "" + base.Node.reparentChildren(self, newParent) + + class Comment(Element): + def __init__(self, data): + # Use the superclass constructor to set all properties on the + # wrapper element + self._element = ElementTree.Comment(data) + self.parent = None + self._childNodes = [] + self._flags = [] + + def _getData(self): + return self._element.text + + def _setData(self, value): + self._element.text = value + + data = property(_getData, _setData) + + class DocumentType(Element): + def __init__(self, name, publicId, systemId): + Element.__init__(self, "<!DOCTYPE>") + self._element.text = name + self.publicId = publicId + self.systemId = systemId + + def _getPublicId(self): + return self._element.get("publicId", "") + + def _setPublicId(self, value): + if value is not None: + self._element.set("publicId", value) + + publicId = property(_getPublicId, _setPublicId) + + def _getSystemId(self): + return self._element.get("systemId", "") + + def _setSystemId(self, value): + if value is not None: + self._element.set("systemId", value) + + systemId = property(_getSystemId, _setSystemId) + + class Document(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_ROOT") + + class DocumentFragment(Element): + def __init__(self): + Element.__init__(self, "DOCUMENT_FRAGMENT") + + def testSerializer(element): + rv = [] + + def serializeElement(element, indent=0): + if not(hasattr(element, "tag")): + element = element.getroot() + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + rv.append("#document") + if element.text is not None: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + elif element.tag == ElementTreeCommentType: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + else: + assert isinstance(element.tag, text_type), \ + "Expected unicode, got %s, %s" % (type(element.tag), element.tag) + nsmatch = tag_regexp.match(element.tag) + + if nsmatch is None: + name = element.tag + else: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + name = "%s %s" % (prefix, name) + rv.append("|%s<%s>" % (' ' * indent, name)) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = name + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + def tostring(element): # pylint:disable=unused-variable + """Serialize an element and its child nodes to a string""" + rv = [] + filter = _ihatexml.InfosetFilter() + + def serializeElement(element): + if isinstance(element, ElementTree.ElementTree): + element = element.getroot() + + if element.tag == "<!DOCTYPE>": + if element.get("publicId") or element.get("systemId"): + publicId = element.get("publicId") or "" + systemId = element.get("systemId") or "" + rv.append("""<!DOCTYPE %s PUBLIC "%s" "%s">""" % + (element.text, publicId, systemId)) + else: + rv.append("<!DOCTYPE %s>" % (element.text,)) + elif element.tag == "DOCUMENT_ROOT": + if element.text is not None: + rv.append(element.text) + if element.tail is not None: + raise TypeError("Document node cannot have tail") + if hasattr(element, "attrib") and len(element.attrib): + raise TypeError("Document node cannot have attributes") + + for child in element: + serializeElement(child) + + elif element.tag == ElementTreeCommentType: + rv.append("<!--%s-->" % (element.text,)) + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (filter.fromXmlName(element.tag),)) + else: + attr = " ".join(["%s=\"%s\"" % ( + filter.fromXmlName(name), value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + class TreeBuilder(base.TreeBuilder): # pylint:disable=unused-variable + documentClass = Document + doctypeClass = DocumentType + elementClass = Element + commentClass = Comment + fragmentClass = DocumentFragment + implementation = ElementTreeImplementation + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._element + else: + if self.defaultNamespace is not None: + return self.document._element.find( + "{%s}html" % self.defaultNamespace) + else: + return self.document._element.find("html") + + def getFragment(self): + return base.TreeBuilder.getFragment(self)._element + + return locals() + + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py new file mode 100644 index 0000000..ca12a99 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treebuilders/etree_lxml.py @@ -0,0 +1,366 @@ +"""Module for supporting the lxml.etree library. The idea here is to use as much +of the native library as possible, without using fragile hacks like custom element +names that break between releases. The downside of this is that we cannot represent +all possible trees; specifically the following are known to cause problems: + +Text or comments as siblings of the root element +Docypes with no name + +When any of these things occur, we emit a DataLossWarning +""" + +from __future__ import absolute_import, division, unicode_literals +# pylint:disable=protected-access + +import warnings +import re +import sys + +from . import base +from ..constants import DataLossWarning +from .. import constants +from . import etree as etree_builders +from .. import _ihatexml + +import lxml.etree as etree + + +fullTree = True +tag_regexp = re.compile("{([^}]*)}(.*)") + +comment_type = etree.Comment("asd").tag + + +class DocumentType(object): + def __init__(self, name, publicId, systemId): + self.name = name + self.publicId = publicId + self.systemId = systemId + + +class Document(object): + def __init__(self): + self._elementTree = None + self._childNodes = [] + + def appendChild(self, element): + self._elementTree.getroot().addnext(element._element) + + def _getChildNodes(self): + return self._childNodes + + childNodes = property(_getChildNodes) + + +def testSerializer(element): + rv = [] + infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + + def serializeElement(element, indent=0): + if not hasattr(element, "tag"): + if hasattr(element, "getroot"): + # Full tree case + rv.append("#document") + if element.docinfo.internalDTD: + if not (element.docinfo.public_id or + element.docinfo.system_url): + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + else: + dtd_str = """<!DOCTYPE %s "%s" "%s">""" % ( + element.docinfo.root_name, + element.docinfo.public_id, + element.docinfo.system_url) + rv.append("|%s%s" % (' ' * (indent + 2), dtd_str)) + next_element = element.getroot() + while next_element.getprevious() is not None: + next_element = next_element.getprevious() + while next_element is not None: + serializeElement(next_element, indent + 2) + next_element = next_element.getnext() + elif isinstance(element, str) or isinstance(element, bytes): + # Text in a fragment + assert isinstance(element, str) or sys.version_info[0] == 2 + rv.append("|%s\"%s\"" % (' ' * indent, element)) + else: + # Fragment case + rv.append("#document-fragment") + for next_element in element: + serializeElement(next_element, indent + 2) + elif element.tag == comment_type: + rv.append("|%s<!-- %s -->" % (' ' * indent, element.text)) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * indent, element.tail)) + else: + assert isinstance(element, etree._Element) + nsmatch = etree_builders.tag_regexp.match(element.tag) + if nsmatch is not None: + ns = nsmatch.group(1) + tag = nsmatch.group(2) + prefix = constants.prefixes[ns] + rv.append("|%s<%s %s>" % (' ' * indent, prefix, + infosetFilter.fromXmlName(tag))) + else: + rv.append("|%s<%s>" % (' ' * indent, + infosetFilter.fromXmlName(element.tag))) + + if hasattr(element, "attrib"): + attributes = [] + for name, value in element.attrib.items(): + nsmatch = tag_regexp.match(name) + if nsmatch is not None: + ns, name = nsmatch.groups() + name = infosetFilter.fromXmlName(name) + prefix = constants.prefixes[ns] + attr_string = "%s %s" % (prefix, name) + else: + attr_string = infosetFilter.fromXmlName(name) + attributes.append((attr_string, value)) + + for name, value in sorted(attributes): + rv.append('|%s%s="%s"' % (' ' * (indent + 2), name, value)) + + if element.text: + rv.append("|%s\"%s\"" % (' ' * (indent + 2), element.text)) + indent += 2 + for child in element: + serializeElement(child, indent) + if hasattr(element, "tail") and element.tail: + rv.append("|%s\"%s\"" % (' ' * (indent - 2), element.tail)) + serializeElement(element, 0) + + return "\n".join(rv) + + +def tostring(element): + """Serialize an element and its child nodes to a string""" + rv = [] + + def serializeElement(element): + if not hasattr(element, "tag"): + if element.docinfo.internalDTD: + if element.docinfo.doctype: + dtd_str = element.docinfo.doctype + else: + dtd_str = "<!DOCTYPE %s>" % element.docinfo.root_name + rv.append(dtd_str) + serializeElement(element.getroot()) + + elif element.tag == comment_type: + rv.append("<!--%s-->" % (element.text,)) + + else: + # This is assumed to be an ordinary element + if not element.attrib: + rv.append("<%s>" % (element.tag,)) + else: + attr = " ".join(["%s=\"%s\"" % (name, value) + for name, value in element.attrib.items()]) + rv.append("<%s %s>" % (element.tag, attr)) + if element.text: + rv.append(element.text) + + for child in element: + serializeElement(child) + + rv.append("</%s>" % (element.tag,)) + + if hasattr(element, "tail") and element.tail: + rv.append(element.tail) + + serializeElement(element) + + return "".join(rv) + + +class TreeBuilder(base.TreeBuilder): + documentClass = Document + doctypeClass = DocumentType + elementClass = None + commentClass = None + fragmentClass = Document + implementation = etree + + def __init__(self, namespaceHTMLElements, fullTree=False): + builder = etree_builders.getETreeModule(etree, fullTree=fullTree) + infosetFilter = self.infosetFilter = _ihatexml.InfosetFilter(preventDoubleDashComments=True) + self.namespaceHTMLElements = namespaceHTMLElements + + class Attributes(dict): + def __init__(self, element, value=None): + if value is None: + value = {} + self._element = element + dict.__init__(self, value) # pylint:disable=non-parent-init-called + for key, value in self.items(): + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + def __setitem__(self, key, value): + dict.__setitem__(self, key, value) + if isinstance(key, tuple): + name = "{%s}%s" % (key[2], infosetFilter.coerceAttribute(key[1])) + else: + name = infosetFilter.coerceAttribute(key) + self._element._element.attrib[name] = value + + class Element(builder.Element): + def __init__(self, name, namespace): + name = infosetFilter.coerceElement(name) + builder.Element.__init__(self, name, namespace=namespace) + self._attributes = Attributes(self) + + def _setName(self, name): + self._name = infosetFilter.coerceElement(name) + self._element.tag = self._getETreeTag( + self._name, self._namespace) + + def _getName(self): + return infosetFilter.fromXmlName(self._name) + + name = property(_getName, _setName) + + def _getAttributes(self): + return self._attributes + + def _setAttributes(self, attributes): + self._attributes = Attributes(self, attributes) + + attributes = property(_getAttributes, _setAttributes) + + def insertText(self, data, insertBefore=None): + data = infosetFilter.coerceCharacters(data) + builder.Element.insertText(self, data, insertBefore) + + def appendChild(self, child): + builder.Element.appendChild(self, child) + + class Comment(builder.Comment): + def __init__(self, data): + data = infosetFilter.coerceComment(data) + builder.Comment.__init__(self, data) + + def _setData(self, data): + data = infosetFilter.coerceComment(data) + self._element.text = data + + def _getData(self): + return self._element.text + + data = property(_getData, _setData) + + self.elementClass = Element + self.commentClass = Comment + # self.fragmentClass = builder.DocumentFragment + base.TreeBuilder.__init__(self, namespaceHTMLElements) + + def reset(self): + base.TreeBuilder.reset(self) + self.insertComment = self.insertCommentInitial + self.initial_comments = [] + self.doctype = None + + def testSerializer(self, element): + return testSerializer(element) + + def getDocument(self): + if fullTree: + return self.document._elementTree + else: + return self.document._elementTree.getroot() + + def getFragment(self): + fragment = [] + element = self.openElements[0]._element + if element.text: + fragment.append(element.text) + fragment.extend(list(element)) + if element.tail: + fragment.append(element.tail) + return fragment + + def insertDoctype(self, token): + name = token["name"] + publicId = token["publicId"] + systemId = token["systemId"] + + if not name: + warnings.warn("lxml cannot represent empty doctype", DataLossWarning) + self.doctype = None + else: + coercedName = self.infosetFilter.coerceElement(name) + if coercedName != name: + warnings.warn("lxml cannot represent non-xml doctype", DataLossWarning) + + doctype = self.doctypeClass(coercedName, publicId, systemId) + self.doctype = doctype + + def insertCommentInitial(self, data, parent=None): + assert parent is None or parent is self.document + assert self.document._elementTree is None + self.initial_comments.append(data) + + def insertCommentMain(self, data, parent=None): + if (parent == self.document and + self.document._elementTree.getroot()[-1].tag == comment_type): + warnings.warn("lxml cannot represent adjacent comments beyond the root elements", DataLossWarning) + super(TreeBuilder, self).insertComment(data, parent) + + def insertRoot(self, token): + # Because of the way libxml2 works, it doesn't seem to be possible to + # alter information like the doctype after the tree has been parsed. + # Therefore we need to use the built-in parser to create our initial + # tree, after which we can add elements like normal + docStr = "" + if self.doctype: + assert self.doctype.name + docStr += "<!DOCTYPE %s" % self.doctype.name + if (self.doctype.publicId is not None or + self.doctype.systemId is not None): + docStr += (' PUBLIC "%s" ' % + (self.infosetFilter.coercePubid(self.doctype.publicId or ""))) + if self.doctype.systemId: + sysid = self.doctype.systemId + if sysid.find("'") >= 0 and sysid.find('"') >= 0: + warnings.warn("DOCTYPE system cannot contain single and double quotes", DataLossWarning) + sysid = sysid.replace("'", 'U00027') + if sysid.find("'") >= 0: + docStr += '"%s"' % sysid + else: + docStr += "'%s'" % sysid + else: + docStr += "''" + docStr += ">" + if self.doctype.name != token["name"]: + warnings.warn("lxml cannot represent doctype with a different name to the root element", DataLossWarning) + docStr += "<THIS_SHOULD_NEVER_APPEAR_PUBLICLY/>" + root = etree.fromstring(docStr) + + # Append the initial comments: + for comment_token in self.initial_comments: + comment = self.commentClass(comment_token["data"]) + root.addprevious(comment._element) + + # Create the root document and add the ElementTree to it + self.document = self.documentClass() + self.document._elementTree = root.getroottree() + + # Give the root element the right name + name = token["name"] + namespace = token.get("namespace", self.defaultNamespace) + if namespace is None: + etree_tag = name + else: + etree_tag = "{%s}%s" % (namespace, name) + root.tag = etree_tag + + # Add the root element to the internal child/open data structures + root_element = self.elementClass(name, namespace) + root_element._element = root + self.document._childNodes.append(root_element) + self.openElements.append(root_element) + + # Reset to the default insert comment function + self.insertComment = self.insertCommentMain diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py new file mode 100644 index 0000000..9bec207 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__init__.py @@ -0,0 +1,154 @@ +"""A collection of modules for iterating through different kinds of +tree, generating tokens identical to those produced by the tokenizer +module. + +To create a tree walker for a new type of tree, you need to do +implement a tree walker object (called TreeWalker by convention) that +implements a 'serialize' method taking a tree as sole argument and +returning an iterator generating tokens. +""" + +from __future__ import absolute_import, division, unicode_literals + +from .. import constants +from .._utils import default_etree + +__all__ = ["getTreeWalker", "pprint"] + +treeWalkerCache = {} + + +def getTreeWalker(treeType, implementation=None, **kwargs): + """Get a TreeWalker class for various types of tree with built-in support + + :arg str treeType: the name of the tree type required (case-insensitive). + Supported values are: + + * "dom": The xml.dom.minidom DOM implementation + * "etree": A generic walker for tree implementations exposing an + elementtree-like interface (known to work with ElementTree, + cElementTree and lxml.etree). + * "lxml": Optimized walker for lxml.etree + * "genshi": a Genshi stream + + :arg implementation: A module implementing the tree type e.g. + xml.etree.ElementTree or cElementTree (Currently applies to the "etree" + tree type only). + + :arg kwargs: keyword arguments passed to the etree walker--for other + walkers, this has no effect + + :returns: a TreeWalker class + + """ + + treeType = treeType.lower() + if treeType not in treeWalkerCache: + if treeType == "dom": + from . import dom + treeWalkerCache[treeType] = dom.TreeWalker + elif treeType == "genshi": + from . import genshi + treeWalkerCache[treeType] = genshi.TreeWalker + elif treeType == "lxml": + from . import etree_lxml + treeWalkerCache[treeType] = etree_lxml.TreeWalker + elif treeType == "etree": + from . import etree + if implementation is None: + implementation = default_etree + # XXX: NEVER cache here, caching is done in the etree submodule + return etree.getETreeModule(implementation, **kwargs).TreeWalker + return treeWalkerCache.get(treeType) + + +def concatenateCharacterTokens(tokens): + pendingCharacters = [] + for token in tokens: + type = token["type"] + if type in ("Characters", "SpaceCharacters"): + pendingCharacters.append(token["data"]) + else: + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + pendingCharacters = [] + yield token + if pendingCharacters: + yield {"type": "Characters", "data": "".join(pendingCharacters)} + + +def pprint(walker): + """Pretty printer for tree walkers + + Takes a TreeWalker instance and pretty prints the output of walking the tree. + + :arg walker: a TreeWalker instance + + """ + output = [] + indent = 0 + for token in concatenateCharacterTokens(walker): + type = token["type"] + if type in ("StartTag", "EmptyTag"): + # tag name + if token["namespace"] and token["namespace"] != constants.namespaces["html"]: + if token["namespace"] in constants.prefixes: + ns = constants.prefixes[token["namespace"]] + else: + ns = token["namespace"] + name = "%s %s" % (ns, token["name"]) + else: + name = token["name"] + output.append("%s<%s>" % (" " * indent, name)) + indent += 2 + # attributes (sorted for consistent ordering) + attrs = token["data"] + for (namespace, localname), value in sorted(attrs.items()): + if namespace: + if namespace in constants.prefixes: + ns = constants.prefixes[namespace] + else: + ns = namespace + name = "%s %s" % (ns, localname) + else: + name = localname + output.append("%s%s=\"%s\"" % (" " * indent, name, value)) + # self-closing + if type == "EmptyTag": + indent -= 2 + + elif type == "EndTag": + indent -= 2 + + elif type == "Comment": + output.append("%s<!-- %s -->" % (" " * indent, token["data"])) + + elif type == "Doctype": + if token["name"]: + if token["publicId"]: + output.append("""%s<!DOCTYPE %s "%s" "%s">""" % + (" " * indent, + token["name"], + token["publicId"], + token["systemId"] if token["systemId"] else "")) + elif token["systemId"]: + output.append("""%s<!DOCTYPE %s "" "%s">""" % + (" " * indent, + token["name"], + token["systemId"])) + else: + output.append("%s<!DOCTYPE %s>" % (" " * indent, + token["name"])) + else: + output.append("%s<!DOCTYPE >" % (" " * indent,)) + + elif type == "Characters": + output.append("%s\"%s\"" % (" " * indent, token["data"])) + + elif type == "SpaceCharacters": + assert False, "concatenateCharacterTokens should have got rid of all Space tokens" + + else: + raise ValueError("Unknown token type, %s" % type) + + return "\n".join(output) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..43291d3b96873933c71e1017c091a583adbe42ab GIT binary patch literal 3954 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/base.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..10b3a2dbad231e3bb5405f3611932b7a3ece2fa1 GIT binary patch literal 6950 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/dom.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..caa33abf1b057b7a41e3e17a62270ec7589506c4 GIT binary patch literal 1679 zcma)6QEwYX5Z=8z`_8W2rm0Djrbs*>kP(evK;ogQn%Zs^pyw)a2&{n9*}G28**iPC z>olp-rxyMO$s@1)41U7C!b{(I;)$7aZMPAsy3)+e&dkkxJ3F%vs?{=q#eVzb$6pGB z{Dqs@@<6x`q#pp|gi}dU%4q5^Cv}-iQRhf6EwBQ}F85?H^_fq}Bf<;3_>%CV@Q1+* zmzB7`L+ZgRh(qeGy%zWMNKTB1l5{*$#s)k&PINNL?9wDl`XeqPnHZsBsq55wAt+u^ z{1-O8Sc^Uenk@%}`#}10V1h8p33E8*&P&2vgau!33WycB&jZ*Oc?kfOZMmz2*o)<% zP<@Pp3y)m{Y69thfSu7HF?8r0I_e|i4n5cxfQmr=z}uPG1Mn#goWr8J2VP~cUKu!Z zYX$!PBO%Y7ldnw`Y*){(U62>FMSl9~xqC*>m(JV^3X(g#u6_l+eCD7GbYtM$B}YF` zb)3MrFxBi4$Wwz@*MU9&e|o-hK?a3+&YO_)Pw-j2gk=qo-pY~w4c7Gm-N8t=!HXbb zPM|h4tbfRY3@YC}9Sa4$LD+Ju)7*XB4!cqJhbQeQ?6lg-M}rRrR9P>JQ(=Sgq$iX9 z7Po;u)kdUSoRzxm@4NXgY`NLm>~2Oo?PhnY6Hav=npp|+eHY7#V3qc_?K~A`v7St{ zvE|qpmGq!-wDk_fsb)+2!feiz*e0xk2=qAai{0%lTR6^xmE@=&%MdKge;wE6XUkR9 zgIG5Y63H=uW|d~=@glSTddI5s!y_WLGT%Pj-h4FoXTeNw{oU}Ju(KD|J?m*92T&Y{ zZwq(`z>lBbiMk2(`?uXN>9{dY#&?oTn^?*_{iplc&>Ve%%ABHOk@1mg9GFyoDU)8q zK<7TqJ6AXODBT#J+N)3vJVQ&EIFY&pq4meW2(8eXvrH>ag?h9`%d`ml8fZ~d0ZZUM zTU(66#@lh`lYtY0W0+3{jtF+lv{xuA4-%zKUdOtlZh%$Qkl_KRY!xJ1h1d`0o`_E8 zgGZmOz71gE^nUrTWa7l^B+z)-{<{F=MOwIi`UZl_C0Ka9AB6HaRwB!<;9Ur?1W)Fk zpS=O#QVAALVcoYu6k%^iku672I^q+FawUq6Cb67a)EWd+w~(zPyNzsd0l9>?paNh> zIu~fL9=L&<YeRe$qi8TO69w@VUXF5+;k#)4lT>a%yX6mpCDZX=2}jws=uebRj>X~@ Y^LYQ4-UfH4`0rsiY3!t$1Fh)(2euZXy8r+H literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7699f4bdd0a363476c16ed13535afd5de328c000 GIT binary patch literal 3486 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/etree_lxml.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4b4af34a43d4a155368020073d9af26e1719091f GIT binary patch literal 6595 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 S^%Q@_$X6~@%9VWO#s32@%Ug{A literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/__pycache__/genshi.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4259de7bd86ab001e836ec1cbd075ff6051dfb9 GIT binary patch literal 1853 zcmZ`(UvJb#5Z_(<Y@g3}xg3{3T3V_;Ae{t+2U_(3A<`u3A2kOhCqh?L?&a1A&iT(} zy%z#nSC!xy@eN9(zVsdSBlJV;YoB=O2dJv5Gd7{9YHjW8?9A-UZ+B+)({|e@@bMon z-fuJs`3)DRpAF1S7{xOnf(V+BlyaIf&Qgn86lE;2(*|!;yal|&oz&%S>Txe^@@DFD zztY*DYw=bZ@E~pTcG}^cbb&9VUET$KLpaG|+T%UoUEw8X(mwB}OMHov&xmLW|0xlE z)H_&yV)13s+9reG6<{I*%Pfp{i#(aDD2&rtE|u{_d=wXPo|*1Eizm5=!X#Fa94Ezq zn#R||aT*O8rm;O*yE8J@=5WKb?`?e*4%fCew{NelZyI;w*81q1+ndH7ZQdIV9OG5C z;c(kHV2*REmaK2Ajn+&Pg*D4=e_`D9TU%S3!_g~>2&u7m$3^st;ewgqD38Tv5~We5 z3gc%0rkIT<Q8B^uoPKD06Gm|!NJKalgfl?}drG(^EMdcJiw4|-WBiefqMdOvjpPI) z;)j`Qz(A*k03t|9k3ZJrfNYR&FO^J#$7xeuJAOx#7gSTtP8ewX($dylLdoI99imxD z4+EHM+wV?o1^JilogMHGSm+QAXe)qY9F<R_tQgqFE}~@5crzIt#reE2jpzuDZW@)r z&qTfl=>GV8Ri(4lSv<QOXN4Lk$>qtz{p>&;UPECuLf9s9x%xn*$wx`NyNYohR>v+@ z_aWAU_{!{&@xl<39foZ@dJhO;HVvppd(@|%h4bSx|6JLXQ~Qa9w(xaecrdEF`vGoL z)B9Fwm3G<CmLgLof7SMVRyw7toda5WKv~(0N$DSdqFuPftDtR_fwFW<*-w}p=|KCs zb--ZIJ$9WOUPXx@x>c{>j+?3>=n8s&sXgUP9r^P3OUR9@o7#ijEFiNNnhCZ-lsC01 z-dZ8rnOY}ymASTVSDE{1hh$yY*{pY-RQb$)0qh=l|4Z8yW*afTiE0(US5aO0C+zfb z=Lth^+4r!oHD%AKTn0^`?Gswb_dwpR<Ts8vXga6?96|XS$8&mk36R_XyM@Z`E>vGv z+s{a~|02j2)q?7&Gpeta)bgG?bs)+t3&7i1ZPjtAy0VAH#<WW;Z@CC$a85cfnP!qt z#tAl&X})PC<3syn8D*15Vi(9IBz+*<i_)2TG#c+qw_1XgRIoG-R2Pc7AU5tKPq9HI zzKu}P(Xo>7ID$gt6ZL2oNh}cALJ}asVv|@nash~O=h-yNA7+D&TtVTxD6}(hW9(_1 z31f?~8XFoKOO5xrJ61}@y9JoQN#uuM%@-$mb`(h!iSSfQr-mL$d=aXqsmc4eJO>10 z6gPnotaJDs_-)#ORgZO9A9|n%f53XI*7a$Z`LqM0TT$dXlv$4#-|CLKjfe1FLSrGi zFf@J`rn#6W$OmC~IIlAhhVlYLufV(o5c^wJD3^i5+bZyN0)!ojlHuSidfc0<xde|A zpFWAbDAA0!Ubprnm#>qFiLbI(Cjs+P<>`OZQRkFMd<;wz?iEWz6;(mhrGYs93$pR9 W*C)M!l~*A6J`3o1`T+}A*ZLdVFulb9 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py new file mode 100644 index 0000000..80c474c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/base.py @@ -0,0 +1,252 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node +from ..constants import namespaces, voidElements, spaceCharacters + +__all__ = ["DOCUMENT", "DOCTYPE", "TEXT", "ELEMENT", "COMMENT", "ENTITY", "UNKNOWN", + "TreeWalker", "NonRecursiveTreeWalker"] + +DOCUMENT = Node.DOCUMENT_NODE +DOCTYPE = Node.DOCUMENT_TYPE_NODE +TEXT = Node.TEXT_NODE +ELEMENT = Node.ELEMENT_NODE +COMMENT = Node.COMMENT_NODE +ENTITY = Node.ENTITY_NODE +UNKNOWN = "<#UNKNOWN#>" + +spaceCharacters = "".join(spaceCharacters) + + +class TreeWalker(object): + """Walks a tree yielding tokens + + Tokens are dicts that all have a ``type`` field specifying the type of the + token. + + """ + def __init__(self, tree): + """Creates a TreeWalker + + :arg tree: the tree to walk + + """ + self.tree = tree + + def __iter__(self): + raise NotImplementedError + + def error(self, msg): + """Generates an error token with the given message + + :arg msg: the error message + + :returns: SerializeError token + + """ + return {"type": "SerializeError", "data": msg} + + def emptyTag(self, namespace, name, attrs, hasChildren=False): + """Generates an EmptyTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :arg hasChildren: whether or not to yield a SerializationError because + this tag shouldn't have children + + :returns: EmptyTag token + + """ + yield {"type": "EmptyTag", "name": name, + "namespace": namespace, + "data": attrs} + if hasChildren: + yield self.error("Void element has children") + + def startTag(self, namespace, name, attrs): + """Generates a StartTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :arg attrs: the attributes of the element as a dict + + :returns: StartTag token + + """ + return {"type": "StartTag", + "name": name, + "namespace": namespace, + "data": attrs} + + def endTag(self, namespace, name): + """Generates an EndTag token + + :arg namespace: the namespace of the token--can be ``None`` + + :arg name: the name of the element + + :returns: EndTag token + + """ + return {"type": "EndTag", + "name": name, + "namespace": namespace} + + def text(self, data): + """Generates SpaceCharacters and Characters tokens + + Depending on what's in the data, this generates one or more + ``SpaceCharacters`` and ``Characters`` tokens. + + For example: + + >>> from html5lib.treewalkers.base import TreeWalker + >>> # Give it an empty tree just so it instantiates + >>> walker = TreeWalker([]) + >>> list(walker.text('')) + [] + >>> list(walker.text(' ')) + [{u'data': ' ', u'type': u'SpaceCharacters'}] + >>> list(walker.text(' abc ')) # doctest: +NORMALIZE_WHITESPACE + [{u'data': ' ', u'type': u'SpaceCharacters'}, + {u'data': u'abc', u'type': u'Characters'}, + {u'data': u' ', u'type': u'SpaceCharacters'}] + + :arg data: the text data + + :returns: one or more ``SpaceCharacters`` and ``Characters`` tokens + + """ + data = data + middle = data.lstrip(spaceCharacters) + left = data[:len(data) - len(middle)] + if left: + yield {"type": "SpaceCharacters", "data": left} + data = middle + middle = data.rstrip(spaceCharacters) + right = data[len(middle):] + if middle: + yield {"type": "Characters", "data": middle} + if right: + yield {"type": "SpaceCharacters", "data": right} + + def comment(self, data): + """Generates a Comment token + + :arg data: the comment + + :returns: Comment token + + """ + return {"type": "Comment", "data": data} + + def doctype(self, name, publicId=None, systemId=None): + """Generates a Doctype token + + :arg name: + + :arg publicId: + + :arg systemId: + + :returns: the Doctype token + + """ + return {"type": "Doctype", + "name": name, + "publicId": publicId, + "systemId": systemId} + + def entity(self, name): + """Generates an Entity token + + :arg name: the entity name + + :returns: an Entity token + + """ + return {"type": "Entity", "name": name} + + def unknown(self, nodeType): + """Handles unknown node types""" + return self.error("Unknown node type: " + nodeType) + + +class NonRecursiveTreeWalker(TreeWalker): + def getNodeDetails(self, node): + raise NotImplementedError + + def getFirstChild(self, node): + raise NotImplementedError + + def getNextSibling(self, node): + raise NotImplementedError + + def getParentNode(self, node): + raise NotImplementedError + + def __iter__(self): + currentNode = self.tree + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + hasChildren = False + + if type == DOCTYPE: + yield self.doctype(*details) + + elif type == TEXT: + for token in self.text(*details): + yield token + + elif type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (not namespace or namespace == namespaces["html"]) and name in voidElements: + for token in self.emptyTag(namespace, name, attributes, + hasChildren): + yield token + hasChildren = False + else: + yield self.startTag(namespace, name, attributes) + + elif type == COMMENT: + yield self.comment(details[0]) + + elif type == ENTITY: + yield self.entity(details[0]) + + elif type == DOCUMENT: + hasChildren = True + + else: + yield self.unknown(details[0]) + + if hasChildren: + firstChild = self.getFirstChild(currentNode) + else: + firstChild = None + + if firstChild is not None: + currentNode = firstChild + else: + while currentNode is not None: + details = self.getNodeDetails(currentNode) + type, details = details[0], details[1:] + if type == ELEMENT: + namespace, name, attributes, hasChildren = details + if (namespace and namespace != namespaces["html"]) or name not in voidElements: + yield self.endTag(namespace, name) + if self.tree is currentNode: + currentNode = None + break + nextSibling = self.getNextSibling(currentNode) + if nextSibling is not None: + currentNode = nextSibling + break + else: + currentNode = self.getParentNode(currentNode) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py new file mode 100644 index 0000000..b0c89b0 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/dom.py @@ -0,0 +1,43 @@ +from __future__ import absolute_import, division, unicode_literals + +from xml.dom import Node + +from . import base + + +class TreeWalker(base.NonRecursiveTreeWalker): + def getNodeDetails(self, node): + if node.nodeType == Node.DOCUMENT_TYPE_NODE: + return base.DOCTYPE, node.name, node.publicId, node.systemId + + elif node.nodeType in (Node.TEXT_NODE, Node.CDATA_SECTION_NODE): + return base.TEXT, node.nodeValue + + elif node.nodeType == Node.ELEMENT_NODE: + attrs = {} + for attr in list(node.attributes.keys()): + attr = node.getAttributeNode(attr) + if attr.namespaceURI: + attrs[(attr.namespaceURI, attr.localName)] = attr.value + else: + attrs[(None, attr.name)] = attr.value + return (base.ELEMENT, node.namespaceURI, node.nodeName, + attrs, node.hasChildNodes()) + + elif node.nodeType == Node.COMMENT_NODE: + return base.COMMENT, node.nodeValue + + elif node.nodeType in (Node.DOCUMENT_NODE, Node.DOCUMENT_FRAGMENT_NODE): + return (base.DOCUMENT,) + + else: + return base.UNKNOWN, node.nodeType + + def getFirstChild(self, node): + return node.firstChild + + def getNextSibling(self, node): + return node.nextSibling + + def getParentNode(self, node): + return node.parentNode diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py new file mode 100644 index 0000000..95fc0c1 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree.py @@ -0,0 +1,130 @@ +from __future__ import absolute_import, division, unicode_literals + +from collections import OrderedDict +import re + +from pip._vendor.six import string_types + +from . import base +from .._utils import moduleFactoryFactory + +tag_regexp = re.compile("{([^}]*)}(.*)") + + +def getETreeBuilder(ElementTreeImplementation): + ElementTree = ElementTreeImplementation + ElementTreeCommentType = ElementTree.Comment("asd").tag + + class TreeWalker(base.NonRecursiveTreeWalker): # pylint:disable=unused-variable + """Given the particular ElementTree representation, this implementation, + to avoid using recursion, returns "nodes" as tuples with the following + content: + + 1. The current element + + 2. The index of the element relative to its parent + + 3. A stack of ancestor elements + + 4. A flag "text", "tail" or None to indicate if the current node is a + text node; either the text or tail of the current element (1) + """ + def getNodeDetails(self, node): + if isinstance(node, tuple): # It might be the root Element + elt, _, _, flag = node + if flag in ("text", "tail"): + return base.TEXT, getattr(elt, flag) + else: + node = elt + + if not(hasattr(node, "tag")): + node = node.getroot() + + if node.tag in ("DOCUMENT_ROOT", "DOCUMENT_FRAGMENT"): + return (base.DOCUMENT,) + + elif node.tag == "<!DOCTYPE>": + return (base.DOCTYPE, node.text, + node.get("publicId"), node.get("systemId")) + + elif node.tag == ElementTreeCommentType: + return base.COMMENT, node.text + + else: + assert isinstance(node.tag, string_types), type(node.tag) + # This is assumed to be an ordinary element + match = tag_regexp.match(node.tag) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = node.tag + attrs = OrderedDict() + for name, value in list(node.attrib.items()): + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, tag, + attrs, len(node) or node.text) + + def getFirstChild(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + element, key, parents, flag = node, None, [], None + + if flag in ("text", "tail"): + return None + else: + if element.text: + return element, key, parents, "text" + elif len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + + def getNextSibling(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if len(element): + parents.append(element) + return element[0], 0, parents, None + else: + return None + else: + if element.tail and flag != "tail": + return element, key, parents, "tail" + elif key < len(parents[-1]) - 1: + return parents[-1][key + 1], key + 1, parents, None + else: + return None + + def getParentNode(self, node): + if isinstance(node, tuple): + element, key, parents, flag = node + else: + return None + + if flag == "text": + if not parents: + return element + else: + return element, key, parents, None + else: + parent = parents.pop() + if not parents: + return parent + else: + assert list(parents[-1]).count(parent) == 1 + return parent, list(parents[-1]).index(parent), parents, None + + return locals() + +getETreeModule = moduleFactoryFactory(getETreeBuilder) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py new file mode 100644 index 0000000..e81ddf3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/etree_lxml.py @@ -0,0 +1,213 @@ +from __future__ import absolute_import, division, unicode_literals +from pip._vendor.six import text_type + +from lxml import etree +from ..treebuilders.etree import tag_regexp + +from . import base + +from .. import _ihatexml + + +def ensure_str(s): + if s is None: + return None + elif isinstance(s, text_type): + return s + else: + return s.decode("ascii", "strict") + + +class Root(object): + def __init__(self, et): + self.elementtree = et + self.children = [] + + try: + if et.docinfo.internalDTD: + self.children.append(Doctype(self, + ensure_str(et.docinfo.root_name), + ensure_str(et.docinfo.public_id), + ensure_str(et.docinfo.system_url))) + except AttributeError: + pass + + try: + node = et.getroot() + except AttributeError: + node = et + + while node.getprevious() is not None: + node = node.getprevious() + while node is not None: + self.children.append(node) + node = node.getnext() + + self.text = None + self.tail = None + + def __getitem__(self, key): + return self.children[key] + + def getnext(self): + return None + + def __len__(self): + return 1 + + +class Doctype(object): + def __init__(self, root_node, name, public_id, system_id): + self.root_node = root_node + self.name = name + self.public_id = public_id + self.system_id = system_id + + self.text = None + self.tail = None + + def getnext(self): + return self.root_node.children[1] + + +class FragmentRoot(Root): + def __init__(self, children): + self.children = [FragmentWrapper(self, child) for child in children] + self.text = self.tail = None + + def getnext(self): + return None + + +class FragmentWrapper(object): + def __init__(self, fragment_root, obj): + self.root_node = fragment_root + self.obj = obj + if hasattr(self.obj, 'text'): + self.text = ensure_str(self.obj.text) + else: + self.text = None + if hasattr(self.obj, 'tail'): + self.tail = ensure_str(self.obj.tail) + else: + self.tail = None + + def __getattr__(self, name): + return getattr(self.obj, name) + + def getnext(self): + siblings = self.root_node.children + idx = siblings.index(self) + if idx < len(siblings) - 1: + return siblings[idx + 1] + else: + return None + + def __getitem__(self, key): + return self.obj[key] + + def __bool__(self): + return bool(self.obj) + + def getparent(self): + return None + + def __str__(self): + return str(self.obj) + + def __unicode__(self): + return str(self.obj) + + def __len__(self): + return len(self.obj) + + +class TreeWalker(base.NonRecursiveTreeWalker): + def __init__(self, tree): + # pylint:disable=redefined-variable-type + if isinstance(tree, list): + self.fragmentChildren = set(tree) + tree = FragmentRoot(tree) + else: + self.fragmentChildren = set() + tree = Root(tree) + base.NonRecursiveTreeWalker.__init__(self, tree) + self.filter = _ihatexml.InfosetFilter() + + def getNodeDetails(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + return base.TEXT, ensure_str(getattr(node, key)) + + elif isinstance(node, Root): + return (base.DOCUMENT,) + + elif isinstance(node, Doctype): + return base.DOCTYPE, node.name, node.public_id, node.system_id + + elif isinstance(node, FragmentWrapper) and not hasattr(node, "tag"): + return base.TEXT, ensure_str(node.obj) + + elif node.tag == etree.Comment: + return base.COMMENT, ensure_str(node.text) + + elif node.tag == etree.Entity: + return base.ENTITY, ensure_str(node.text)[1:-1] # strip &; + + else: + # This is assumed to be an ordinary element + match = tag_regexp.match(ensure_str(node.tag)) + if match: + namespace, tag = match.groups() + else: + namespace = None + tag = ensure_str(node.tag) + attrs = {} + for name, value in list(node.attrib.items()): + name = ensure_str(name) + value = ensure_str(value) + match = tag_regexp.match(name) + if match: + attrs[(match.group(1), match.group(2))] = value + else: + attrs[(None, name)] = value + return (base.ELEMENT, namespace, self.filter.fromXmlName(tag), + attrs, len(node) > 0 or node.text) + + def getFirstChild(self, node): + assert not isinstance(node, tuple), "Text nodes have no children" + + assert len(node) or node.text, "Node has no children" + if node.text: + return (node, "text") + else: + return node[0] + + def getNextSibling(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + # XXX: we cannot use a "bool(node) and node[0] or None" construct here + # because node[0] might evaluate to False if it has no child element + if len(node): + return node[0] + else: + return None + else: # tail + return node.getnext() + + return (node, "tail") if node.tail else node.getnext() + + def getParentNode(self, node): + if isinstance(node, tuple): # Text node + node, key = node + assert key in ("text", "tail"), "Text nodes are text or tail, found %s" % key + if key == "text": + return node + # else: fallback to "normal" processing + elif node in self.fragmentChildren: + return None + + return node.getparent() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py new file mode 100644 index 0000000..7483be2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/html5lib/treewalkers/genshi.py @@ -0,0 +1,69 @@ +from __future__ import absolute_import, division, unicode_literals + +from genshi.core import QName +from genshi.core import START, END, XML_NAMESPACE, DOCTYPE, TEXT +from genshi.core import START_NS, END_NS, START_CDATA, END_CDATA, PI, COMMENT + +from . import base + +from ..constants import voidElements, namespaces + + +class TreeWalker(base.TreeWalker): + def __iter__(self): + # Buffer the events so we can pass in the following one + previous = None + for event in self.tree: + if previous is not None: + for token in self.tokens(previous, event): + yield token + previous = event + + # Don't forget the final event! + if previous is not None: + for token in self.tokens(previous, None): + yield token + + def tokens(self, event, next): + kind, data, _ = event + if kind == START: + tag, attribs = data + name = tag.localname + namespace = tag.namespace + converted_attribs = {} + for k, v in attribs: + if isinstance(k, QName): + converted_attribs[(k.namespace, k.localname)] = v + else: + converted_attribs[(None, k)] = v + + if namespace == namespaces["html"] and name in voidElements: + for token in self.emptyTag(namespace, name, converted_attribs, + not next or next[0] != END or + next[1] != tag): + yield token + else: + yield self.startTag(namespace, name, converted_attribs) + + elif kind == END: + name = data.localname + namespace = data.namespace + if namespace != namespaces["html"] or name not in voidElements: + yield self.endTag(namespace, name) + + elif kind == COMMENT: + yield self.comment(data) + + elif kind == TEXT: + for token in self.text(data): + yield token + + elif kind == DOCTYPE: + yield self.doctype(*data) + + elif kind in (XML_NAMESPACE, DOCTYPE, START_NS, END_NS, + START_CDATA, END_CDATA, PI): + pass + + else: + yield self.unknown(kind) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py new file mode 100644 index 0000000..847bf93 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/idna/__init__.py @@ -0,0 +1,2 @@ +from .package_data import __version__ +from .core import * diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4d072e4175e37e0f9b561d7a64134a7dbaf04527 GIT binary patch literal 214 zcmZ?b<>g`kf~fgwF;+nOF^B^LOhASM5En}Ti4=wu#vF!R#wbQc5SuB7DTE<~Iha9{ z<s~CfT9fe>cYJ(VYEf}!eqMY$kjtp$r^$SarywyoJ25>qJ|(dvu?S@1Etcf`qSTcP zMQlJ0nD}L-Uy@s(Uyxa#o0(T!l9-dDn_QlrmsL_|0ulscpwW3L`9=DfDS3(d@$s2? dnI-Y@dIgoYIBatBQ%ZAE?Le+523f$v2mlbFHUa<u literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/codec.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..efe10c4736bec1238a52f00747bc0882bfd33202 GIT binary patch literal 3021 zcmc(h&yN&E6vw;z_w>%rE+c{<>HvvxNZ3Us!GqumOAMDeNR*_NbegW-wb$;Rp}I$8 z?IDKYsQwGi9`)=||B;F}PMo-V(eJC?+1XzR>cN`S>#A2Z_2bp&y{fD8^PYy}|M=$T zkDHqIm@3m`p|FBnOdz<%S*m5sXPNHnnc*9m>6@A5TTJ6RH&WZT)z|Tz*qON8++u#? zBaK_!exz|bwl}=7;d{_H+=a%4W)7MrG!5=S<3TeIO$(Yi-h`$ZlWt*b`U}v_^A>b1 zrCWq<kuUJYN1A_x8#lG?ktYnx>{`-}^Qg~bY4f=LhG}>wPNhApzl|HKy$`Po(HBqf z2dy{6zO~Pm9)J7r>90RL{cY=ZMCxfWP*_1OIuNnuGp_kMwty`^V!pw#QEs7RavO_i zNb4Hrj-*|bB8kd~{!WR$Ch|4pVhN(sIs4KO$4Xdl!YX}>joCw1vEp^wO{rI?mj=l- z9Rr&^(ZIhpJD=pma4_hLGUlC_HqrSa%z2vR>zy;-To|3{>QWO9x^_)r<0I|0zR1E- z=u|P%IPV(LEaG%cnmjB+n2Sa!e$vDudi-%|xy%O3gJf_%$%`^f)AP~2^?akedy$kX z2VccG?~CPx=ixG$I9eLqSL4$X3k8(!vX*W#Q{QYVgDlmD@_*Pv(1LcGM9h(bPDIer zcMUO5<rawr5@d*49HA2Rd<pp(JF7A4b(uP$>Bo|85aeMN2Z8j0AnWsCO66t{+#QB# z-J*<EuVgl-DyfNGOiD*t5IL^yd4e<%@=l^tT|q96LhRtlxDLNClwX*#eIt)VoW(hg z^Sbg45z&a0=)}m+6_>xD@H{RjU~-F%Om2>>$`qeg!2g6+ta6*`+`6pg?aC;W{<20r zsAXLn+1wd9U%ykCtJ>{zBe$|AW@%OK7^5+*a>T<5ap96Saw?~^Nl)dw{1#%z#Hs8p zR$0d}ifXm$)(SP{9gP?Fju{QA^yE(@$(9r!LPZc)`Hg}^E(XIqA;bgTFN;9L(kcdN zQc61<4B!QV?5HS`=0-osyN!J;Noy_1Lj)fcdkWbsMVOGc(ty$yaWPCw_+zq(p;e!K z^vPCmXSlW&i=g(P*D+yn0YYO_7xNe#4K<Z@n`-2G%wsL3TQpj%$u>_P#9(Rf*geFI zHf@M#7etgeL*g(tUq-`g$ORGTGC}qKMCPiB*3TgGcZ~i#GAqQ(u`Vu_=ESNQ%};?O zM9`6nq}&|qAdO8dZYhElvEl)!bwF^+Ek&@iO|a4{f*(+eBG}zWuv5Cb2>uxaH?|3G z>=67N2(~8P9)cUyeuBM!L$I{MB1#f*9M-A1K1L-988ymtyHNI$LPhjEilwtnwRnZP zo`8@BE-Z19suT_s(&AN=4iGI)Q9B*IAQr_NBswHclbEqWA#6r(9VI`2u6Pe(hhD>D zO~VDNo?`ZIDAo^9yp7Bb#nVW9fa13>;jWd<BJ5c-TtS{vO!Yk!Q$$#y4s=t@;wx@s zT{dr)A`Y`#A}M3h!!@$ccV?!TP1waS>onfB+fe<VPWW*g@)w@)946S<H6hjaOh`At zHR{lTD76j7S*ee;4MR!9=+Z91IoH2;uxq0yO}h8Hjx^~Go84ftoy@M8I#!82y83j4 zY=ShH?Vd8*v<40Kg!hxJ9u$RasAt2C9IqF;^k(y@NF&aYj*KU0Lx-KMoLi4E(K@a@ zaX&++f=)q0MAVs$pRRu5UFf=PX-0jqYcq9RSDrwRDDgIg)DixjsGkjzG_E~|Rwhqg zRq;9I2ji<+>!BUC(cQlfTFs%Gao?|B5LXDuf<QZkh>tgc-agho-R>SWjv9XfFrR~^ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..868d8f7b9970976c1966088b8dfd6d8383827c78 GIT binary patch literal 574 zcma)3%}N6?5Ki`|O~sykfjtS8)-B?p2NAV;*vnp8FGY}b6J#Zu#B8c4o~-ZT*;m@D z7kvd!&TLr_L2zK^n<SGjUuI7F{S5-Pc-_AE0DQ+qYaS#=;MEWUC!9($Un2$dxc@>H z9uIg3=<^Qm0tTGT$e{O0;mUy4bSK9Q4G|fq;1z@5$P-ynsHQ1Yc7)0`7m$TAyAtw^ z*bs`oCb26`Yzi|fROK=$NBRA=x^cJrxY_vSolsocxZo;_b6uLu?V5+WJJ-jvX_5r^ zAihkf?Lz#wA}-d7EHX4|)}aH-x;NM7s=xx|Z25bC@^8Y4gC4HvGvx$+?WK>y<TO2w z_QvB$#I>j*rCqdig)Ax&sjL*n3KJQtozAs{&TOUHC8d#~6v_#HX05i^<m$IL*51b9 ww%SlZItc3^*H+XaO3#~ySX6EC_y-R*-!?yG2c_mqDGqUh&Eyzm9`l+14YMqEEdT%j literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a6cf1fcd914087cadffef925c84ebaeff8fc2ce5 GIT binary patch literal 9106 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 a4)T2Q8Kecz^~Q^3&-cc>1I4l8BmWQOzevyk literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/idnadata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6d0f886cde4e18e22840933c57fe64acc946cdc8 GIT binary patch literal 20538 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 VJ@9{b4-E4~-spV&$NI=Y{}aa|DINd- literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/intranges.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0abbad97deb90a22224dbafe32033bf4bf717ec GIT binary patch literal 1754 zcmZuxNpIXX6ecNYtc-0SOIzD$krFNtSb#HjoSa%`K^ml&zy*>31&kE3EON%GHIz(J zUIGnrnD*BH(B#-3)C;dY`7iY1zDIdUgHqu3_%?lSc{)GeCos1Exbx<(9wC3@<zg^6 zJb`J}VG(4T2r5`fx2Xt3_$%3FA`(5=12H3F*h6tm^kI(#dqtAj>>4Gc|3h&o70-BC z7|W|6FO-!dsm&@MXF~F(M&im|Rm)*hmM00YnsHW^Ts7lesqwX})QIawnLb?dN*S3q z7Sw*EE3d|NV<iY{S!-#evY9O^h2nNk@?oXN{goACGi~p!a;e0<WR-XK4S(NA_+T(d z2K@CN`m4+l7)Q~AMjEeb`6x5|n4hcf7s@|Zx)>EIEBy~XUIw4IEyj}nxKdW5m2bS? zNiyi40)}KO2T1$?tjP?_?_rwXVX>qoQ#zp|GGT&Ff@5u|Wi6e;_l*3!I|<uRum#f5 z_KAMc(l%ToxFUUt2)0P}nSOC_8)yO2x|iSB5}8CTdmq@ajYI%4k)X)GK&I>irNB1{ z4sQQMEO1RJ#4gOf1V>+9K>0u6<A4Q3N&-46mk6`Y)JU3d`y9qO(&@T~HeJ8OI_<zu z5q*Svm76Bt10XZ|A2hv|i&Wv6mRufZxh+qCt1=S8a3$x1nihQXA&@sQws3)fb5lVa zib3Bid+FWlRH?iYQs6I`LXFC+L^{t1zPZWoZ}1j%fs3lL$ZMOrlxE<you0us#b9b& zlAi0CN?R#h<Z*C8DV6JGbqy-qd<r0e$+UZmye5!|uqaYD+li)lbG;5n*Do`8JJN-f zjuvh{Z?uN2?o|9q^mQ=%&v$EfT(8wdeYa2mLs{O<k4EYjd+-2>ex^`<qS9-HP}v$F z+NmGZC+^neEgkA=?9F2{Fkiqz;+Tf;-K5v)B4zY5`W20tz6mcm_5~cc<McT^2Zt6q z#3RVarv!3{ZJlzUc}ElGA|ECffH$7hEjN%OhUIIR#w(`&epx68ZvfL9!JkGWk8x#B z$PgP%u%&MSy+p3FcW3W{bDPvr{fQ}vgpgN}SO$p;qYH4p{4=b~5T-Z!77kdQf==0l zS^6HTvSlCGB!DWT`=Q>lL055$P=!<ahD}1Kx3C2j0okYec^g5!ZmEzG6^h^$X|WQa zu7P^k$zIC!P!6j25cxz1zZboI_)J=<$AyAK9r7IrTe`!C5N(4Uu;LXwocFmdy4Zwv zy5r8kC#XhnUO!JF53cL&7SKeko9*_rltZf#0gZhrnQ<W+(HK+L^VyoZpstJykrQ&f z80}d{(@){Oag|cgr)^fKJD{RVDAuQQK@5qsNJBOUX@v=<Ioj*FnKTtuo~C*c?mo-B kqn%I4^N}S?0*#5|;>~d-no>SOuMOsI$YK_M9tUywFC{|96aWAK literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/package_data.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..869bd76e86c1bd2e5790ee818af1e5cc804fc3f4 GIT binary patch literal 168 zcmZ?b<>g`kf~fgwF`_{FF^B^Lj6jA15EpX*i4=w?h7`tN22G|aW+OdwKTXD4-0|^c zsYS(^`FZj2D;bKIfU3a6FFXB`+yecA%mUrayyB9?oE+Wc^7Oo{l0p-ZAQ%I6=B4Bp p>1U?oCF&O>CTAz6r^crwmL%#GRNmsS$<0qG%}KQbxu6(`832o8Dy9Gc literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/idna/__pycache__/uts46data.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..73163271fef549bcb8aefc3300cafa8a2e70e2d8 GIT binary patch literal 175610 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/codec.py b/env/lib/python3.7/site-packages/pip/_vendor/idna/codec.py new file mode 100644 index 0000000..98c65ea --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/idna/codec.py @@ -0,0 +1,118 @@ +from .core import encode, decode, alabel, ulabel, IDNAError +import codecs +import re + +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +class Codec(codecs.Codec): + + def encode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return "", 0 + + return encode(data), len(data) + + def decode(self, data, errors='strict'): + + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return u"", 0 + + return decode(data), len(data) + +class IncrementalEncoder(codecs.BufferedIncrementalEncoder): + def _buffer_encode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return ("", 0) + + labels = _unicode_dots_re.split(data) + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = '.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = '.' + + result = [] + size = 0 + for label in labels: + result.append(alabel(label)) + if size: + size += 1 + size += len(label) + + # Join with U+002E + result = ".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + def _buffer_decode(self, data, errors, final): + if errors != 'strict': + raise IDNAError("Unsupported error handling \"{0}\"".format(errors)) + + if not data: + return (u"", 0) + + # IDNA allows decoding to operate on Unicode strings, too. + if isinstance(data, unicode): + labels = _unicode_dots_re.split(data) + else: + # Must be ASCII string + data = str(data) + unicode(data, "ascii") + labels = data.split(".") + + trailing_dot = u'' + if labels: + if not labels[-1]: + trailing_dot = u'.' + del labels[-1] + elif not final: + # Keep potentially unfinished label until the next call + del labels[-1] + if labels: + trailing_dot = u'.' + + result = [] + size = 0 + for label in labels: + result.append(ulabel(label)) + if size: + size += 1 + size += len(label) + + result = u".".join(result) + trailing_dot + size += len(trailing_dot) + return (result, size) + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +def getregentry(): + return codecs.CodecInfo( + name='idna', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/compat.py b/env/lib/python3.7/site-packages/pip/_vendor/idna/compat.py new file mode 100644 index 0000000..4d47f33 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/idna/compat.py @@ -0,0 +1,12 @@ +from .core import * +from .codec import * + +def ToASCII(label): + return encode(label) + +def ToUnicode(label): + return decode(label) + +def nameprep(s): + raise NotImplementedError("IDNA 2008 does not utilise nameprep protocol") + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/core.py b/env/lib/python3.7/site-packages/pip/_vendor/idna/core.py new file mode 100644 index 0000000..090c2c1 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/idna/core.py @@ -0,0 +1,399 @@ +from . import idnadata +import bisect +import unicodedata +import re +import sys +from .intranges import intranges_contain + +_virama_combining_class = 9 +_alabel_prefix = b'xn--' +_unicode_dots_re = re.compile(u'[\u002e\u3002\uff0e\uff61]') + +if sys.version_info[0] == 3: + unicode = str + unichr = chr + +class IDNAError(UnicodeError): + """ Base exception for all IDNA-encoding related problems """ + pass + + +class IDNABidiError(IDNAError): + """ Exception when bidirectional requirements are not satisfied """ + pass + + +class InvalidCodepoint(IDNAError): + """ Exception when a disallowed or unallocated codepoint is used """ + pass + + +class InvalidCodepointContext(IDNAError): + """ Exception when the codepoint is not valid in the context it is used """ + pass + + +def _combining_class(cp): + v = unicodedata.combining(unichr(cp)) + if v == 0: + if not unicodedata.name(unichr(cp)): + raise ValueError("Unknown character in unicodedata") + return v + +def _is_script(cp, script): + return intranges_contain(ord(cp), idnadata.scripts[script]) + +def _punycode(s): + return s.encode('punycode') + +def _unot(s): + return 'U+{0:04X}'.format(s) + + +def valid_label_length(label): + + if len(label) > 63: + return False + return True + + +def valid_string_length(label, trailing_dot): + + if len(label) > (254 if trailing_dot else 253): + return False + return True + + +def check_bidi(label, check_ltr=False): + + # Bidi rules should only be applied if string contains RTL characters + bidi_label = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + if direction == '': + # String likely comes from a newer version of Unicode + raise IDNABidiError('Unknown directionality in label {0} at position {1}'.format(repr(label), idx)) + if direction in ['R', 'AL', 'AN']: + bidi_label = True + if not bidi_label and not check_ltr: + return True + + # Bidi rule 1 + direction = unicodedata.bidirectional(label[0]) + if direction in ['R', 'AL']: + rtl = True + elif direction == 'L': + rtl = False + else: + raise IDNABidiError('First codepoint in label {0} must be directionality L, R or AL'.format(repr(label))) + + valid_ending = False + number_type = False + for (idx, cp) in enumerate(label, 1): + direction = unicodedata.bidirectional(cp) + + if rtl: + # Bidi rule 2 + if not direction in ['R', 'AL', 'AN', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a right-to-left label'.format(idx)) + # Bidi rule 3 + if direction in ['R', 'AL', 'EN', 'AN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + # Bidi rule 4 + if direction in ['AN', 'EN']: + if not number_type: + number_type = direction + else: + if number_type != direction: + raise IDNABidiError('Can not mix numeral types in a right-to-left label') + else: + # Bidi rule 5 + if not direction in ['L', 'EN', 'ES', 'CS', 'ET', 'ON', 'BN', 'NSM']: + raise IDNABidiError('Invalid direction for codepoint at position {0} in a left-to-right label'.format(idx)) + # Bidi rule 6 + if direction in ['L', 'EN']: + valid_ending = True + elif direction != 'NSM': + valid_ending = False + + if not valid_ending: + raise IDNABidiError('Label ends with illegal codepoint directionality') + + return True + + +def check_initial_combiner(label): + + if unicodedata.category(label[0])[0] == 'M': + raise IDNAError('Label begins with an illegal combining character') + return True + + +def check_hyphen_ok(label): + + if label[2:4] == '--': + raise IDNAError('Label has disallowed hyphens in 3rd and 4th position') + if label[0] == '-' or label[-1] == '-': + raise IDNAError('Label must not start or end with a hyphen') + return True + + +def check_nfc(label): + + if unicodedata.normalize('NFC', label) != label: + raise IDNAError('Label must be in Normalization Form C') + + +def valid_contextj(label, pos): + + cp_value = ord(label[pos]) + + if cp_value == 0x200c: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + + ok = False + for i in range(pos-1, -1, -1): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('L'), ord('D')]: + ok = True + break + + if not ok: + return False + + ok = False + for i in range(pos+1, len(label)): + joining_type = idnadata.joining_types.get(ord(label[i])) + if joining_type == ord('T'): + continue + if joining_type in [ord('R'), ord('D')]: + ok = True + break + return ok + + if cp_value == 0x200d: + + if pos > 0: + if _combining_class(ord(label[pos - 1])) == _virama_combining_class: + return True + return False + + else: + + return False + + +def valid_contexto(label, pos, exception=False): + + cp_value = ord(label[pos]) + + if cp_value == 0x00b7: + if 0 < pos < len(label)-1: + if ord(label[pos - 1]) == 0x006c and ord(label[pos + 1]) == 0x006c: + return True + return False + + elif cp_value == 0x0375: + if pos < len(label)-1 and len(label) > 1: + return _is_script(label[pos + 1], 'Greek') + return False + + elif cp_value == 0x05f3 or cp_value == 0x05f4: + if pos > 0: + return _is_script(label[pos - 1], 'Hebrew') + return False + + elif cp_value == 0x30fb: + for cp in label: + if cp == u'\u30fb': + continue + if _is_script(cp, 'Hiragana') or _is_script(cp, 'Katakana') or _is_script(cp, 'Han'): + return True + return False + + elif 0x660 <= cp_value <= 0x669: + for cp in label: + if 0x6f0 <= ord(cp) <= 0x06f9: + return False + return True + + elif 0x6f0 <= cp_value <= 0x6f9: + for cp in label: + if 0x660 <= ord(cp) <= 0x0669: + return False + return True + + +def check_label(label): + + if isinstance(label, (bytes, bytearray)): + label = label.decode('utf-8') + if len(label) == 0: + raise IDNAError('Empty Label') + + check_nfc(label) + check_hyphen_ok(label) + check_initial_combiner(label) + + for (pos, cp) in enumerate(label): + cp_value = ord(cp) + if intranges_contain(cp_value, idnadata.codepoint_classes['PVALID']): + continue + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTJ']): + try: + if not valid_contextj(label, pos): + raise InvalidCodepointContext('Joiner {0} not allowed at position {1} in {2}'.format( + _unot(cp_value), pos+1, repr(label))) + except ValueError: + raise IDNAError('Unknown codepoint adjacent to joiner {0} at position {1} in {2}'.format( + _unot(cp_value), pos+1, repr(label))) + elif intranges_contain(cp_value, idnadata.codepoint_classes['CONTEXTO']): + if not valid_contexto(label, pos): + raise InvalidCodepointContext('Codepoint {0} not allowed at position {1} in {2}'.format(_unot(cp_value), pos+1, repr(label))) + else: + raise InvalidCodepoint('Codepoint {0} at position {1} of {2} not allowed'.format(_unot(cp_value), pos+1, repr(label))) + + check_bidi(label) + + +def alabel(label): + + try: + label = label.encode('ascii') + try: + ulabel(label) + except IDNAError: + raise IDNAError('The label {0} is not a valid A-label'.format(label)) + if not valid_label_length(label): + raise IDNAError('Label too long') + return label + except UnicodeEncodeError: + pass + + if not label: + raise IDNAError('No Input') + + label = unicode(label) + check_label(label) + label = _punycode(label) + label = _alabel_prefix + label + + if not valid_label_length(label): + raise IDNAError('Label too long') + + return label + + +def ulabel(label): + + if not isinstance(label, (bytes, bytearray)): + try: + label = label.encode('ascii') + except UnicodeEncodeError: + check_label(label) + return label + + label = label.lower() + if label.startswith(_alabel_prefix): + label = label[len(_alabel_prefix):] + else: + check_label(label) + return label.decode('ascii') + + label = label.decode('punycode') + check_label(label) + return label + + +def uts46_remap(domain, std3_rules=True, transitional=False): + """Re-map the characters in the string according to UTS46 processing.""" + from .uts46data import uts46data + output = u"" + try: + for pos, char in enumerate(domain): + code_point = ord(char) + uts46row = uts46data[code_point if code_point < 256 else + bisect.bisect_left(uts46data, (code_point, "Z")) - 1] + status = uts46row[1] + replacement = uts46row[2] if len(uts46row) == 3 else None + if (status == "V" or + (status == "D" and not transitional) or + (status == "3" and not std3_rules and replacement is None)): + output += char + elif replacement is not None and (status == "M" or + (status == "3" and not std3_rules) or + (status == "D" and transitional)): + output += replacement + elif status != "I": + raise IndexError() + return unicodedata.normalize("NFC", output) + except IndexError: + raise InvalidCodepoint( + "Codepoint {0} not allowed at position {1} in {2}".format( + _unot(code_point), pos + 1, repr(domain))) + + +def encode(s, strict=False, uts46=False, std3_rules=False, transitional=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, transitional) + trailing_dot = False + result = [] + if strict: + labels = s.split('.') + else: + labels = _unicode_dots_re.split(s) + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if labels[-1] == '': + del labels[-1] + trailing_dot = True + for label in labels: + s = alabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(b'') + s = b'.'.join(result) + if not valid_string_length(s, trailing_dot): + raise IDNAError('Domain too long') + return s + + +def decode(s, strict=False, uts46=False, std3_rules=False): + + if isinstance(s, (bytes, bytearray)): + s = s.decode("ascii") + if uts46: + s = uts46_remap(s, std3_rules, False) + trailing_dot = False + result = [] + if not strict: + labels = _unicode_dots_re.split(s) + else: + labels = s.split(u'.') + if not labels or labels == ['']: + raise IDNAError('Empty domain') + if not labels[-1]: + del labels[-1] + trailing_dot = True + for label in labels: + s = ulabel(label) + if s: + result.append(s) + else: + raise IDNAError('Empty label') + if trailing_dot: + result.append(u'') + return u'.'.join(result) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py b/env/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py new file mode 100644 index 0000000..17974e2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/idna/idnadata.py @@ -0,0 +1,1893 @@ +# This file is automatically generated by tools/idna-data + +__version__ = "10.0.0" +scripts = { + 'Greek': ( + 0x37000000374, + 0x37500000378, + 0x37a0000037e, + 0x37f00000380, + 0x38400000385, + 0x38600000387, + 0x3880000038b, + 0x38c0000038d, + 0x38e000003a2, + 0x3a3000003e2, + 0x3f000000400, + 0x1d2600001d2b, + 0x1d5d00001d62, + 0x1d6600001d6b, + 0x1dbf00001dc0, + 0x1f0000001f16, + 0x1f1800001f1e, + 0x1f2000001f46, + 0x1f4800001f4e, + 0x1f5000001f58, + 0x1f5900001f5a, + 0x1f5b00001f5c, + 0x1f5d00001f5e, + 0x1f5f00001f7e, + 0x1f8000001fb5, + 0x1fb600001fc5, + 0x1fc600001fd4, + 0x1fd600001fdc, + 0x1fdd00001ff0, + 0x1ff200001ff5, + 0x1ff600001fff, + 0x212600002127, + 0xab650000ab66, + 0x101400001018f, + 0x101a0000101a1, + 0x1d2000001d246, + ), + 'Han': ( + 0x2e8000002e9a, + 0x2e9b00002ef4, + 0x2f0000002fd6, + 0x300500003006, + 0x300700003008, + 0x30210000302a, + 0x30380000303c, + 0x340000004db6, + 0x4e0000009feb, + 0xf9000000fa6e, + 0xfa700000fada, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + 0x2f8000002fa1e, + ), + 'Hebrew': ( + 0x591000005c8, + 0x5d0000005eb, + 0x5f0000005f5, + 0xfb1d0000fb37, + 0xfb380000fb3d, + 0xfb3e0000fb3f, + 0xfb400000fb42, + 0xfb430000fb45, + 0xfb460000fb50, + ), + 'Hiragana': ( + 0x304100003097, + 0x309d000030a0, + 0x1b0010001b11f, + 0x1f2000001f201, + ), + 'Katakana': ( + 0x30a1000030fb, + 0x30fd00003100, + 0x31f000003200, + 0x32d0000032ff, + 0x330000003358, + 0xff660000ff70, + 0xff710000ff9e, + 0x1b0000001b001, + ), +} +joining_types = { + 0x600: 85, + 0x601: 85, + 0x602: 85, + 0x603: 85, + 0x604: 85, + 0x605: 85, + 0x608: 85, + 0x60b: 85, + 0x620: 68, + 0x621: 85, + 0x622: 82, + 0x623: 82, + 0x624: 82, + 0x625: 82, + 0x626: 68, + 0x627: 82, + 0x628: 68, + 0x629: 82, + 0x62a: 68, + 0x62b: 68, + 0x62c: 68, + 0x62d: 68, + 0x62e: 68, + 0x62f: 82, + 0x630: 82, + 0x631: 82, + 0x632: 82, + 0x633: 68, + 0x634: 68, + 0x635: 68, + 0x636: 68, + 0x637: 68, + 0x638: 68, + 0x639: 68, + 0x63a: 68, + 0x63b: 68, + 0x63c: 68, + 0x63d: 68, + 0x63e: 68, + 0x63f: 68, + 0x640: 67, + 0x641: 68, + 0x642: 68, + 0x643: 68, + 0x644: 68, + 0x645: 68, + 0x646: 68, + 0x647: 68, + 0x648: 82, + 0x649: 68, + 0x64a: 68, + 0x66e: 68, + 0x66f: 68, + 0x671: 82, + 0x672: 82, + 0x673: 82, + 0x674: 85, + 0x675: 82, + 0x676: 82, + 0x677: 82, + 0x678: 68, + 0x679: 68, + 0x67a: 68, + 0x67b: 68, + 0x67c: 68, + 0x67d: 68, + 0x67e: 68, + 0x67f: 68, + 0x680: 68, + 0x681: 68, + 0x682: 68, + 0x683: 68, + 0x684: 68, + 0x685: 68, + 0x686: 68, + 0x687: 68, + 0x688: 82, + 0x689: 82, + 0x68a: 82, + 0x68b: 82, + 0x68c: 82, + 0x68d: 82, + 0x68e: 82, + 0x68f: 82, + 0x690: 82, + 0x691: 82, + 0x692: 82, + 0x693: 82, + 0x694: 82, + 0x695: 82, + 0x696: 82, + 0x697: 82, + 0x698: 82, + 0x699: 82, + 0x69a: 68, + 0x69b: 68, + 0x69c: 68, + 0x69d: 68, + 0x69e: 68, + 0x69f: 68, + 0x6a0: 68, + 0x6a1: 68, + 0x6a2: 68, + 0x6a3: 68, + 0x6a4: 68, + 0x6a5: 68, + 0x6a6: 68, + 0x6a7: 68, + 0x6a8: 68, + 0x6a9: 68, + 0x6aa: 68, + 0x6ab: 68, + 0x6ac: 68, + 0x6ad: 68, + 0x6ae: 68, + 0x6af: 68, + 0x6b0: 68, + 0x6b1: 68, + 0x6b2: 68, + 0x6b3: 68, + 0x6b4: 68, + 0x6b5: 68, + 0x6b6: 68, + 0x6b7: 68, + 0x6b8: 68, + 0x6b9: 68, + 0x6ba: 68, + 0x6bb: 68, + 0x6bc: 68, + 0x6bd: 68, + 0x6be: 68, + 0x6bf: 68, + 0x6c0: 82, + 0x6c1: 68, + 0x6c2: 68, + 0x6c3: 82, + 0x6c4: 82, + 0x6c5: 82, + 0x6c6: 82, + 0x6c7: 82, + 0x6c8: 82, + 0x6c9: 82, + 0x6ca: 82, + 0x6cb: 82, + 0x6cc: 68, + 0x6cd: 82, + 0x6ce: 68, + 0x6cf: 82, + 0x6d0: 68, + 0x6d1: 68, + 0x6d2: 82, + 0x6d3: 82, + 0x6d5: 82, + 0x6dd: 85, + 0x6ee: 82, + 0x6ef: 82, + 0x6fa: 68, + 0x6fb: 68, + 0x6fc: 68, + 0x6ff: 68, + 0x710: 82, + 0x712: 68, + 0x713: 68, + 0x714: 68, + 0x715: 82, + 0x716: 82, + 0x717: 82, + 0x718: 82, + 0x719: 82, + 0x71a: 68, + 0x71b: 68, + 0x71c: 68, + 0x71d: 68, + 0x71e: 82, + 0x71f: 68, + 0x720: 68, + 0x721: 68, + 0x722: 68, + 0x723: 68, + 0x724: 68, + 0x725: 68, + 0x726: 68, + 0x727: 68, + 0x728: 82, + 0x729: 68, + 0x72a: 82, + 0x72b: 68, + 0x72c: 82, + 0x72d: 68, + 0x72e: 68, + 0x72f: 82, + 0x74d: 82, + 0x74e: 68, + 0x74f: 68, + 0x750: 68, + 0x751: 68, + 0x752: 68, + 0x753: 68, + 0x754: 68, + 0x755: 68, + 0x756: 68, + 0x757: 68, + 0x758: 68, + 0x759: 82, + 0x75a: 82, + 0x75b: 82, + 0x75c: 68, + 0x75d: 68, + 0x75e: 68, + 0x75f: 68, + 0x760: 68, + 0x761: 68, + 0x762: 68, + 0x763: 68, + 0x764: 68, + 0x765: 68, + 0x766: 68, + 0x767: 68, + 0x768: 68, + 0x769: 68, + 0x76a: 68, + 0x76b: 82, + 0x76c: 82, + 0x76d: 68, + 0x76e: 68, + 0x76f: 68, + 0x770: 68, + 0x771: 82, + 0x772: 68, + 0x773: 82, + 0x774: 82, + 0x775: 68, + 0x776: 68, + 0x777: 68, + 0x778: 82, + 0x779: 82, + 0x77a: 68, + 0x77b: 68, + 0x77c: 68, + 0x77d: 68, + 0x77e: 68, + 0x77f: 68, + 0x7ca: 68, + 0x7cb: 68, + 0x7cc: 68, + 0x7cd: 68, + 0x7ce: 68, + 0x7cf: 68, + 0x7d0: 68, + 0x7d1: 68, + 0x7d2: 68, + 0x7d3: 68, + 0x7d4: 68, + 0x7d5: 68, + 0x7d6: 68, + 0x7d7: 68, + 0x7d8: 68, + 0x7d9: 68, + 0x7da: 68, + 0x7db: 68, + 0x7dc: 68, + 0x7dd: 68, + 0x7de: 68, + 0x7df: 68, + 0x7e0: 68, + 0x7e1: 68, + 0x7e2: 68, + 0x7e3: 68, + 0x7e4: 68, + 0x7e5: 68, + 0x7e6: 68, + 0x7e7: 68, + 0x7e8: 68, + 0x7e9: 68, + 0x7ea: 68, + 0x7fa: 67, + 0x840: 82, + 0x841: 68, + 0x842: 68, + 0x843: 68, + 0x844: 68, + 0x845: 68, + 0x846: 82, + 0x847: 82, + 0x848: 68, + 0x849: 82, + 0x84a: 68, + 0x84b: 68, + 0x84c: 68, + 0x84d: 68, + 0x84e: 68, + 0x84f: 68, + 0x850: 68, + 0x851: 68, + 0x852: 68, + 0x853: 68, + 0x854: 82, + 0x855: 68, + 0x856: 85, + 0x857: 85, + 0x858: 85, + 0x860: 68, + 0x861: 85, + 0x862: 68, + 0x863: 68, + 0x864: 68, + 0x865: 68, + 0x866: 85, + 0x867: 82, + 0x868: 68, + 0x869: 82, + 0x86a: 82, + 0x8a0: 68, + 0x8a1: 68, + 0x8a2: 68, + 0x8a3: 68, + 0x8a4: 68, + 0x8a5: 68, + 0x8a6: 68, + 0x8a7: 68, + 0x8a8: 68, + 0x8a9: 68, + 0x8aa: 82, + 0x8ab: 82, + 0x8ac: 82, + 0x8ad: 85, + 0x8ae: 82, + 0x8af: 68, + 0x8b0: 68, + 0x8b1: 82, + 0x8b2: 82, + 0x8b3: 68, + 0x8b4: 68, + 0x8b6: 68, + 0x8b7: 68, + 0x8b8: 68, + 0x8b9: 82, + 0x8ba: 68, + 0x8bb: 68, + 0x8bc: 68, + 0x8bd: 68, + 0x8e2: 85, + 0x1806: 85, + 0x1807: 68, + 0x180a: 67, + 0x180e: 85, + 0x1820: 68, + 0x1821: 68, + 0x1822: 68, + 0x1823: 68, + 0x1824: 68, + 0x1825: 68, + 0x1826: 68, + 0x1827: 68, + 0x1828: 68, + 0x1829: 68, + 0x182a: 68, + 0x182b: 68, + 0x182c: 68, + 0x182d: 68, + 0x182e: 68, + 0x182f: 68, + 0x1830: 68, + 0x1831: 68, + 0x1832: 68, + 0x1833: 68, + 0x1834: 68, + 0x1835: 68, + 0x1836: 68, + 0x1837: 68, + 0x1838: 68, + 0x1839: 68, + 0x183a: 68, + 0x183b: 68, + 0x183c: 68, + 0x183d: 68, + 0x183e: 68, + 0x183f: 68, + 0x1840: 68, + 0x1841: 68, + 0x1842: 68, + 0x1843: 68, + 0x1844: 68, + 0x1845: 68, + 0x1846: 68, + 0x1847: 68, + 0x1848: 68, + 0x1849: 68, + 0x184a: 68, + 0x184b: 68, + 0x184c: 68, + 0x184d: 68, + 0x184e: 68, + 0x184f: 68, + 0x1850: 68, + 0x1851: 68, + 0x1852: 68, + 0x1853: 68, + 0x1854: 68, + 0x1855: 68, + 0x1856: 68, + 0x1857: 68, + 0x1858: 68, + 0x1859: 68, + 0x185a: 68, + 0x185b: 68, + 0x185c: 68, + 0x185d: 68, + 0x185e: 68, + 0x185f: 68, + 0x1860: 68, + 0x1861: 68, + 0x1862: 68, + 0x1863: 68, + 0x1864: 68, + 0x1865: 68, + 0x1866: 68, + 0x1867: 68, + 0x1868: 68, + 0x1869: 68, + 0x186a: 68, + 0x186b: 68, + 0x186c: 68, + 0x186d: 68, + 0x186e: 68, + 0x186f: 68, + 0x1870: 68, + 0x1871: 68, + 0x1872: 68, + 0x1873: 68, + 0x1874: 68, + 0x1875: 68, + 0x1876: 68, + 0x1877: 68, + 0x1880: 85, + 0x1881: 85, + 0x1882: 85, + 0x1883: 85, + 0x1884: 85, + 0x1885: 84, + 0x1886: 84, + 0x1887: 68, + 0x1888: 68, + 0x1889: 68, + 0x188a: 68, + 0x188b: 68, + 0x188c: 68, + 0x188d: 68, + 0x188e: 68, + 0x188f: 68, + 0x1890: 68, + 0x1891: 68, + 0x1892: 68, + 0x1893: 68, + 0x1894: 68, + 0x1895: 68, + 0x1896: 68, + 0x1897: 68, + 0x1898: 68, + 0x1899: 68, + 0x189a: 68, + 0x189b: 68, + 0x189c: 68, + 0x189d: 68, + 0x189e: 68, + 0x189f: 68, + 0x18a0: 68, + 0x18a1: 68, + 0x18a2: 68, + 0x18a3: 68, + 0x18a4: 68, + 0x18a5: 68, + 0x18a6: 68, + 0x18a7: 68, + 0x18a8: 68, + 0x18aa: 68, + 0x200c: 85, + 0x200d: 67, + 0x202f: 85, + 0x2066: 85, + 0x2067: 85, + 0x2068: 85, + 0x2069: 85, + 0xa840: 68, + 0xa841: 68, + 0xa842: 68, + 0xa843: 68, + 0xa844: 68, + 0xa845: 68, + 0xa846: 68, + 0xa847: 68, + 0xa848: 68, + 0xa849: 68, + 0xa84a: 68, + 0xa84b: 68, + 0xa84c: 68, + 0xa84d: 68, + 0xa84e: 68, + 0xa84f: 68, + 0xa850: 68, + 0xa851: 68, + 0xa852: 68, + 0xa853: 68, + 0xa854: 68, + 0xa855: 68, + 0xa856: 68, + 0xa857: 68, + 0xa858: 68, + 0xa859: 68, + 0xa85a: 68, + 0xa85b: 68, + 0xa85c: 68, + 0xa85d: 68, + 0xa85e: 68, + 0xa85f: 68, + 0xa860: 68, + 0xa861: 68, + 0xa862: 68, + 0xa863: 68, + 0xa864: 68, + 0xa865: 68, + 0xa866: 68, + 0xa867: 68, + 0xa868: 68, + 0xa869: 68, + 0xa86a: 68, + 0xa86b: 68, + 0xa86c: 68, + 0xa86d: 68, + 0xa86e: 68, + 0xa86f: 68, + 0xa870: 68, + 0xa871: 68, + 0xa872: 76, + 0xa873: 85, + 0x10ac0: 68, + 0x10ac1: 68, + 0x10ac2: 68, + 0x10ac3: 68, + 0x10ac4: 68, + 0x10ac5: 82, + 0x10ac6: 85, + 0x10ac7: 82, + 0x10ac8: 85, + 0x10ac9: 82, + 0x10aca: 82, + 0x10acb: 85, + 0x10acc: 85, + 0x10acd: 76, + 0x10ace: 82, + 0x10acf: 82, + 0x10ad0: 82, + 0x10ad1: 82, + 0x10ad2: 82, + 0x10ad3: 68, + 0x10ad4: 68, + 0x10ad5: 68, + 0x10ad6: 68, + 0x10ad7: 76, + 0x10ad8: 68, + 0x10ad9: 68, + 0x10ada: 68, + 0x10adb: 68, + 0x10adc: 68, + 0x10add: 82, + 0x10ade: 68, + 0x10adf: 68, + 0x10ae0: 68, + 0x10ae1: 82, + 0x10ae2: 85, + 0x10ae3: 85, + 0x10ae4: 82, + 0x10aeb: 68, + 0x10aec: 68, + 0x10aed: 68, + 0x10aee: 68, + 0x10aef: 82, + 0x10b80: 68, + 0x10b81: 82, + 0x10b82: 68, + 0x10b83: 82, + 0x10b84: 82, + 0x10b85: 82, + 0x10b86: 68, + 0x10b87: 68, + 0x10b88: 68, + 0x10b89: 82, + 0x10b8a: 68, + 0x10b8b: 68, + 0x10b8c: 82, + 0x10b8d: 68, + 0x10b8e: 82, + 0x10b8f: 82, + 0x10b90: 68, + 0x10b91: 82, + 0x10ba9: 82, + 0x10baa: 82, + 0x10bab: 82, + 0x10bac: 82, + 0x10bad: 68, + 0x10bae: 68, + 0x10baf: 85, + 0x1e900: 68, + 0x1e901: 68, + 0x1e902: 68, + 0x1e903: 68, + 0x1e904: 68, + 0x1e905: 68, + 0x1e906: 68, + 0x1e907: 68, + 0x1e908: 68, + 0x1e909: 68, + 0x1e90a: 68, + 0x1e90b: 68, + 0x1e90c: 68, + 0x1e90d: 68, + 0x1e90e: 68, + 0x1e90f: 68, + 0x1e910: 68, + 0x1e911: 68, + 0x1e912: 68, + 0x1e913: 68, + 0x1e914: 68, + 0x1e915: 68, + 0x1e916: 68, + 0x1e917: 68, + 0x1e918: 68, + 0x1e919: 68, + 0x1e91a: 68, + 0x1e91b: 68, + 0x1e91c: 68, + 0x1e91d: 68, + 0x1e91e: 68, + 0x1e91f: 68, + 0x1e920: 68, + 0x1e921: 68, + 0x1e922: 68, + 0x1e923: 68, + 0x1e924: 68, + 0x1e925: 68, + 0x1e926: 68, + 0x1e927: 68, + 0x1e928: 68, + 0x1e929: 68, + 0x1e92a: 68, + 0x1e92b: 68, + 0x1e92c: 68, + 0x1e92d: 68, + 0x1e92e: 68, + 0x1e92f: 68, + 0x1e930: 68, + 0x1e931: 68, + 0x1e932: 68, + 0x1e933: 68, + 0x1e934: 68, + 0x1e935: 68, + 0x1e936: 68, + 0x1e937: 68, + 0x1e938: 68, + 0x1e939: 68, + 0x1e93a: 68, + 0x1e93b: 68, + 0x1e93c: 68, + 0x1e93d: 68, + 0x1e93e: 68, + 0x1e93f: 68, + 0x1e940: 68, + 0x1e941: 68, + 0x1e942: 68, + 0x1e943: 68, +} +codepoint_classes = { + 'PVALID': ( + 0x2d0000002e, + 0x300000003a, + 0x610000007b, + 0xdf000000f7, + 0xf800000100, + 0x10100000102, + 0x10300000104, + 0x10500000106, + 0x10700000108, + 0x1090000010a, + 0x10b0000010c, + 0x10d0000010e, + 0x10f00000110, + 0x11100000112, + 0x11300000114, + 0x11500000116, + 0x11700000118, + 0x1190000011a, + 0x11b0000011c, + 0x11d0000011e, + 0x11f00000120, + 0x12100000122, + 0x12300000124, + 0x12500000126, + 0x12700000128, + 0x1290000012a, + 0x12b0000012c, + 0x12d0000012e, + 0x12f00000130, + 0x13100000132, + 0x13500000136, + 0x13700000139, + 0x13a0000013b, + 0x13c0000013d, + 0x13e0000013f, + 0x14200000143, + 0x14400000145, + 0x14600000147, + 0x14800000149, + 0x14b0000014c, + 0x14d0000014e, + 0x14f00000150, + 0x15100000152, + 0x15300000154, + 0x15500000156, + 0x15700000158, + 0x1590000015a, + 0x15b0000015c, + 0x15d0000015e, + 0x15f00000160, + 0x16100000162, + 0x16300000164, + 0x16500000166, + 0x16700000168, + 0x1690000016a, + 0x16b0000016c, + 0x16d0000016e, + 0x16f00000170, + 0x17100000172, + 0x17300000174, + 0x17500000176, + 0x17700000178, + 0x17a0000017b, + 0x17c0000017d, + 0x17e0000017f, + 0x18000000181, + 0x18300000184, + 0x18500000186, + 0x18800000189, + 0x18c0000018e, + 0x19200000193, + 0x19500000196, + 0x1990000019c, + 0x19e0000019f, + 0x1a1000001a2, + 0x1a3000001a4, + 0x1a5000001a6, + 0x1a8000001a9, + 0x1aa000001ac, + 0x1ad000001ae, + 0x1b0000001b1, + 0x1b4000001b5, + 0x1b6000001b7, + 0x1b9000001bc, + 0x1bd000001c4, + 0x1ce000001cf, + 0x1d0000001d1, + 0x1d2000001d3, + 0x1d4000001d5, + 0x1d6000001d7, + 0x1d8000001d9, + 0x1da000001db, + 0x1dc000001de, + 0x1df000001e0, + 0x1e1000001e2, + 0x1e3000001e4, + 0x1e5000001e6, + 0x1e7000001e8, + 0x1e9000001ea, + 0x1eb000001ec, + 0x1ed000001ee, + 0x1ef000001f1, + 0x1f5000001f6, + 0x1f9000001fa, + 0x1fb000001fc, + 0x1fd000001fe, + 0x1ff00000200, + 0x20100000202, + 0x20300000204, + 0x20500000206, + 0x20700000208, + 0x2090000020a, + 0x20b0000020c, + 0x20d0000020e, + 0x20f00000210, + 0x21100000212, + 0x21300000214, + 0x21500000216, + 0x21700000218, + 0x2190000021a, + 0x21b0000021c, + 0x21d0000021e, + 0x21f00000220, + 0x22100000222, + 0x22300000224, + 0x22500000226, + 0x22700000228, + 0x2290000022a, + 0x22b0000022c, + 0x22d0000022e, + 0x22f00000230, + 0x23100000232, + 0x2330000023a, + 0x23c0000023d, + 0x23f00000241, + 0x24200000243, + 0x24700000248, + 0x2490000024a, + 0x24b0000024c, + 0x24d0000024e, + 0x24f000002b0, + 0x2b9000002c2, + 0x2c6000002d2, + 0x2ec000002ed, + 0x2ee000002ef, + 0x30000000340, + 0x34200000343, + 0x3460000034f, + 0x35000000370, + 0x37100000372, + 0x37300000374, + 0x37700000378, + 0x37b0000037e, + 0x39000000391, + 0x3ac000003cf, + 0x3d7000003d8, + 0x3d9000003da, + 0x3db000003dc, + 0x3dd000003de, + 0x3df000003e0, + 0x3e1000003e2, + 0x3e3000003e4, + 0x3e5000003e6, + 0x3e7000003e8, + 0x3e9000003ea, + 0x3eb000003ec, + 0x3ed000003ee, + 0x3ef000003f0, + 0x3f3000003f4, + 0x3f8000003f9, + 0x3fb000003fd, + 0x43000000460, + 0x46100000462, + 0x46300000464, + 0x46500000466, + 0x46700000468, + 0x4690000046a, + 0x46b0000046c, + 0x46d0000046e, + 0x46f00000470, + 0x47100000472, + 0x47300000474, + 0x47500000476, + 0x47700000478, + 0x4790000047a, + 0x47b0000047c, + 0x47d0000047e, + 0x47f00000480, + 0x48100000482, + 0x48300000488, + 0x48b0000048c, + 0x48d0000048e, + 0x48f00000490, + 0x49100000492, + 0x49300000494, + 0x49500000496, + 0x49700000498, + 0x4990000049a, + 0x49b0000049c, + 0x49d0000049e, + 0x49f000004a0, + 0x4a1000004a2, + 0x4a3000004a4, + 0x4a5000004a6, + 0x4a7000004a8, + 0x4a9000004aa, + 0x4ab000004ac, + 0x4ad000004ae, + 0x4af000004b0, + 0x4b1000004b2, + 0x4b3000004b4, + 0x4b5000004b6, + 0x4b7000004b8, + 0x4b9000004ba, + 0x4bb000004bc, + 0x4bd000004be, + 0x4bf000004c0, + 0x4c2000004c3, + 0x4c4000004c5, + 0x4c6000004c7, + 0x4c8000004c9, + 0x4ca000004cb, + 0x4cc000004cd, + 0x4ce000004d0, + 0x4d1000004d2, + 0x4d3000004d4, + 0x4d5000004d6, + 0x4d7000004d8, + 0x4d9000004da, + 0x4db000004dc, + 0x4dd000004de, + 0x4df000004e0, + 0x4e1000004e2, + 0x4e3000004e4, + 0x4e5000004e6, + 0x4e7000004e8, + 0x4e9000004ea, + 0x4eb000004ec, + 0x4ed000004ee, + 0x4ef000004f0, + 0x4f1000004f2, + 0x4f3000004f4, + 0x4f5000004f6, + 0x4f7000004f8, + 0x4f9000004fa, + 0x4fb000004fc, + 0x4fd000004fe, + 0x4ff00000500, + 0x50100000502, + 0x50300000504, + 0x50500000506, + 0x50700000508, + 0x5090000050a, + 0x50b0000050c, + 0x50d0000050e, + 0x50f00000510, + 0x51100000512, + 0x51300000514, + 0x51500000516, + 0x51700000518, + 0x5190000051a, + 0x51b0000051c, + 0x51d0000051e, + 0x51f00000520, + 0x52100000522, + 0x52300000524, + 0x52500000526, + 0x52700000528, + 0x5290000052a, + 0x52b0000052c, + 0x52d0000052e, + 0x52f00000530, + 0x5590000055a, + 0x56100000587, + 0x591000005be, + 0x5bf000005c0, + 0x5c1000005c3, + 0x5c4000005c6, + 0x5c7000005c8, + 0x5d0000005eb, + 0x5f0000005f3, + 0x6100000061b, + 0x62000000640, + 0x64100000660, + 0x66e00000675, + 0x679000006d4, + 0x6d5000006dd, + 0x6df000006e9, + 0x6ea000006f0, + 0x6fa00000700, + 0x7100000074b, + 0x74d000007b2, + 0x7c0000007f6, + 0x8000000082e, + 0x8400000085c, + 0x8600000086b, + 0x8a0000008b5, + 0x8b6000008be, + 0x8d4000008e2, + 0x8e300000958, + 0x96000000964, + 0x96600000970, + 0x97100000984, + 0x9850000098d, + 0x98f00000991, + 0x993000009a9, + 0x9aa000009b1, + 0x9b2000009b3, + 0x9b6000009ba, + 0x9bc000009c5, + 0x9c7000009c9, + 0x9cb000009cf, + 0x9d7000009d8, + 0x9e0000009e4, + 0x9e6000009f2, + 0x9fc000009fd, + 0xa0100000a04, + 0xa0500000a0b, + 0xa0f00000a11, + 0xa1300000a29, + 0xa2a00000a31, + 0xa3200000a33, + 0xa3500000a36, + 0xa3800000a3a, + 0xa3c00000a3d, + 0xa3e00000a43, + 0xa4700000a49, + 0xa4b00000a4e, + 0xa5100000a52, + 0xa5c00000a5d, + 0xa6600000a76, + 0xa8100000a84, + 0xa8500000a8e, + 0xa8f00000a92, + 0xa9300000aa9, + 0xaaa00000ab1, + 0xab200000ab4, + 0xab500000aba, + 0xabc00000ac6, + 0xac700000aca, + 0xacb00000ace, + 0xad000000ad1, + 0xae000000ae4, + 0xae600000af0, + 0xaf900000b00, + 0xb0100000b04, + 0xb0500000b0d, + 0xb0f00000b11, + 0xb1300000b29, + 0xb2a00000b31, + 0xb3200000b34, + 0xb3500000b3a, + 0xb3c00000b45, + 0xb4700000b49, + 0xb4b00000b4e, + 0xb5600000b58, + 0xb5f00000b64, + 0xb6600000b70, + 0xb7100000b72, + 0xb8200000b84, + 0xb8500000b8b, + 0xb8e00000b91, + 0xb9200000b96, + 0xb9900000b9b, + 0xb9c00000b9d, + 0xb9e00000ba0, + 0xba300000ba5, + 0xba800000bab, + 0xbae00000bba, + 0xbbe00000bc3, + 0xbc600000bc9, + 0xbca00000bce, + 0xbd000000bd1, + 0xbd700000bd8, + 0xbe600000bf0, + 0xc0000000c04, + 0xc0500000c0d, + 0xc0e00000c11, + 0xc1200000c29, + 0xc2a00000c3a, + 0xc3d00000c45, + 0xc4600000c49, + 0xc4a00000c4e, + 0xc5500000c57, + 0xc5800000c5b, + 0xc6000000c64, + 0xc6600000c70, + 0xc8000000c84, + 0xc8500000c8d, + 0xc8e00000c91, + 0xc9200000ca9, + 0xcaa00000cb4, + 0xcb500000cba, + 0xcbc00000cc5, + 0xcc600000cc9, + 0xcca00000cce, + 0xcd500000cd7, + 0xcde00000cdf, + 0xce000000ce4, + 0xce600000cf0, + 0xcf100000cf3, + 0xd0000000d04, + 0xd0500000d0d, + 0xd0e00000d11, + 0xd1200000d45, + 0xd4600000d49, + 0xd4a00000d4f, + 0xd5400000d58, + 0xd5f00000d64, + 0xd6600000d70, + 0xd7a00000d80, + 0xd8200000d84, + 0xd8500000d97, + 0xd9a00000db2, + 0xdb300000dbc, + 0xdbd00000dbe, + 0xdc000000dc7, + 0xdca00000dcb, + 0xdcf00000dd5, + 0xdd600000dd7, + 0xdd800000de0, + 0xde600000df0, + 0xdf200000df4, + 0xe0100000e33, + 0xe3400000e3b, + 0xe4000000e4f, + 0xe5000000e5a, + 0xe8100000e83, + 0xe8400000e85, + 0xe8700000e89, + 0xe8a00000e8b, + 0xe8d00000e8e, + 0xe9400000e98, + 0xe9900000ea0, + 0xea100000ea4, + 0xea500000ea6, + 0xea700000ea8, + 0xeaa00000eac, + 0xead00000eb3, + 0xeb400000eba, + 0xebb00000ebe, + 0xec000000ec5, + 0xec600000ec7, + 0xec800000ece, + 0xed000000eda, + 0xede00000ee0, + 0xf0000000f01, + 0xf0b00000f0c, + 0xf1800000f1a, + 0xf2000000f2a, + 0xf3500000f36, + 0xf3700000f38, + 0xf3900000f3a, + 0xf3e00000f43, + 0xf4400000f48, + 0xf4900000f4d, + 0xf4e00000f52, + 0xf5300000f57, + 0xf5800000f5c, + 0xf5d00000f69, + 0xf6a00000f6d, + 0xf7100000f73, + 0xf7400000f75, + 0xf7a00000f81, + 0xf8200000f85, + 0xf8600000f93, + 0xf9400000f98, + 0xf9900000f9d, + 0xf9e00000fa2, + 0xfa300000fa7, + 0xfa800000fac, + 0xfad00000fb9, + 0xfba00000fbd, + 0xfc600000fc7, + 0x10000000104a, + 0x10500000109e, + 0x10d0000010fb, + 0x10fd00001100, + 0x120000001249, + 0x124a0000124e, + 0x125000001257, + 0x125800001259, + 0x125a0000125e, + 0x126000001289, + 0x128a0000128e, + 0x1290000012b1, + 0x12b2000012b6, + 0x12b8000012bf, + 0x12c0000012c1, + 0x12c2000012c6, + 0x12c8000012d7, + 0x12d800001311, + 0x131200001316, + 0x13180000135b, + 0x135d00001360, + 0x138000001390, + 0x13a0000013f6, + 0x14010000166d, + 0x166f00001680, + 0x16810000169b, + 0x16a0000016eb, + 0x16f1000016f9, + 0x17000000170d, + 0x170e00001715, + 0x172000001735, + 0x174000001754, + 0x17600000176d, + 0x176e00001771, + 0x177200001774, + 0x1780000017b4, + 0x17b6000017d4, + 0x17d7000017d8, + 0x17dc000017de, + 0x17e0000017ea, + 0x18100000181a, + 0x182000001878, + 0x1880000018ab, + 0x18b0000018f6, + 0x19000000191f, + 0x19200000192c, + 0x19300000193c, + 0x19460000196e, + 0x197000001975, + 0x1980000019ac, + 0x19b0000019ca, + 0x19d0000019da, + 0x1a0000001a1c, + 0x1a2000001a5f, + 0x1a6000001a7d, + 0x1a7f00001a8a, + 0x1a9000001a9a, + 0x1aa700001aa8, + 0x1ab000001abe, + 0x1b0000001b4c, + 0x1b5000001b5a, + 0x1b6b00001b74, + 0x1b8000001bf4, + 0x1c0000001c38, + 0x1c4000001c4a, + 0x1c4d00001c7e, + 0x1cd000001cd3, + 0x1cd400001cfa, + 0x1d0000001d2c, + 0x1d2f00001d30, + 0x1d3b00001d3c, + 0x1d4e00001d4f, + 0x1d6b00001d78, + 0x1d7900001d9b, + 0x1dc000001dfa, + 0x1dfb00001e00, + 0x1e0100001e02, + 0x1e0300001e04, + 0x1e0500001e06, + 0x1e0700001e08, + 0x1e0900001e0a, + 0x1e0b00001e0c, + 0x1e0d00001e0e, + 0x1e0f00001e10, + 0x1e1100001e12, + 0x1e1300001e14, + 0x1e1500001e16, + 0x1e1700001e18, + 0x1e1900001e1a, + 0x1e1b00001e1c, + 0x1e1d00001e1e, + 0x1e1f00001e20, + 0x1e2100001e22, + 0x1e2300001e24, + 0x1e2500001e26, + 0x1e2700001e28, + 0x1e2900001e2a, + 0x1e2b00001e2c, + 0x1e2d00001e2e, + 0x1e2f00001e30, + 0x1e3100001e32, + 0x1e3300001e34, + 0x1e3500001e36, + 0x1e3700001e38, + 0x1e3900001e3a, + 0x1e3b00001e3c, + 0x1e3d00001e3e, + 0x1e3f00001e40, + 0x1e4100001e42, + 0x1e4300001e44, + 0x1e4500001e46, + 0x1e4700001e48, + 0x1e4900001e4a, + 0x1e4b00001e4c, + 0x1e4d00001e4e, + 0x1e4f00001e50, + 0x1e5100001e52, + 0x1e5300001e54, + 0x1e5500001e56, + 0x1e5700001e58, + 0x1e5900001e5a, + 0x1e5b00001e5c, + 0x1e5d00001e5e, + 0x1e5f00001e60, + 0x1e6100001e62, + 0x1e6300001e64, + 0x1e6500001e66, + 0x1e6700001e68, + 0x1e6900001e6a, + 0x1e6b00001e6c, + 0x1e6d00001e6e, + 0x1e6f00001e70, + 0x1e7100001e72, + 0x1e7300001e74, + 0x1e7500001e76, + 0x1e7700001e78, + 0x1e7900001e7a, + 0x1e7b00001e7c, + 0x1e7d00001e7e, + 0x1e7f00001e80, + 0x1e8100001e82, + 0x1e8300001e84, + 0x1e8500001e86, + 0x1e8700001e88, + 0x1e8900001e8a, + 0x1e8b00001e8c, + 0x1e8d00001e8e, + 0x1e8f00001e90, + 0x1e9100001e92, + 0x1e9300001e94, + 0x1e9500001e9a, + 0x1e9c00001e9e, + 0x1e9f00001ea0, + 0x1ea100001ea2, + 0x1ea300001ea4, + 0x1ea500001ea6, + 0x1ea700001ea8, + 0x1ea900001eaa, + 0x1eab00001eac, + 0x1ead00001eae, + 0x1eaf00001eb0, + 0x1eb100001eb2, + 0x1eb300001eb4, + 0x1eb500001eb6, + 0x1eb700001eb8, + 0x1eb900001eba, + 0x1ebb00001ebc, + 0x1ebd00001ebe, + 0x1ebf00001ec0, + 0x1ec100001ec2, + 0x1ec300001ec4, + 0x1ec500001ec6, + 0x1ec700001ec8, + 0x1ec900001eca, + 0x1ecb00001ecc, + 0x1ecd00001ece, + 0x1ecf00001ed0, + 0x1ed100001ed2, + 0x1ed300001ed4, + 0x1ed500001ed6, + 0x1ed700001ed8, + 0x1ed900001eda, + 0x1edb00001edc, + 0x1edd00001ede, + 0x1edf00001ee0, + 0x1ee100001ee2, + 0x1ee300001ee4, + 0x1ee500001ee6, + 0x1ee700001ee8, + 0x1ee900001eea, + 0x1eeb00001eec, + 0x1eed00001eee, + 0x1eef00001ef0, + 0x1ef100001ef2, + 0x1ef300001ef4, + 0x1ef500001ef6, + 0x1ef700001ef8, + 0x1ef900001efa, + 0x1efb00001efc, + 0x1efd00001efe, + 0x1eff00001f08, + 0x1f1000001f16, + 0x1f2000001f28, + 0x1f3000001f38, + 0x1f4000001f46, + 0x1f5000001f58, + 0x1f6000001f68, + 0x1f7000001f71, + 0x1f7200001f73, + 0x1f7400001f75, + 0x1f7600001f77, + 0x1f7800001f79, + 0x1f7a00001f7b, + 0x1f7c00001f7d, + 0x1fb000001fb2, + 0x1fb600001fb7, + 0x1fc600001fc7, + 0x1fd000001fd3, + 0x1fd600001fd8, + 0x1fe000001fe3, + 0x1fe400001fe8, + 0x1ff600001ff7, + 0x214e0000214f, + 0x218400002185, + 0x2c3000002c5f, + 0x2c6100002c62, + 0x2c6500002c67, + 0x2c6800002c69, + 0x2c6a00002c6b, + 0x2c6c00002c6d, + 0x2c7100002c72, + 0x2c7300002c75, + 0x2c7600002c7c, + 0x2c8100002c82, + 0x2c8300002c84, + 0x2c8500002c86, + 0x2c8700002c88, + 0x2c8900002c8a, + 0x2c8b00002c8c, + 0x2c8d00002c8e, + 0x2c8f00002c90, + 0x2c9100002c92, + 0x2c9300002c94, + 0x2c9500002c96, + 0x2c9700002c98, + 0x2c9900002c9a, + 0x2c9b00002c9c, + 0x2c9d00002c9e, + 0x2c9f00002ca0, + 0x2ca100002ca2, + 0x2ca300002ca4, + 0x2ca500002ca6, + 0x2ca700002ca8, + 0x2ca900002caa, + 0x2cab00002cac, + 0x2cad00002cae, + 0x2caf00002cb0, + 0x2cb100002cb2, + 0x2cb300002cb4, + 0x2cb500002cb6, + 0x2cb700002cb8, + 0x2cb900002cba, + 0x2cbb00002cbc, + 0x2cbd00002cbe, + 0x2cbf00002cc0, + 0x2cc100002cc2, + 0x2cc300002cc4, + 0x2cc500002cc6, + 0x2cc700002cc8, + 0x2cc900002cca, + 0x2ccb00002ccc, + 0x2ccd00002cce, + 0x2ccf00002cd0, + 0x2cd100002cd2, + 0x2cd300002cd4, + 0x2cd500002cd6, + 0x2cd700002cd8, + 0x2cd900002cda, + 0x2cdb00002cdc, + 0x2cdd00002cde, + 0x2cdf00002ce0, + 0x2ce100002ce2, + 0x2ce300002ce5, + 0x2cec00002ced, + 0x2cee00002cf2, + 0x2cf300002cf4, + 0x2d0000002d26, + 0x2d2700002d28, + 0x2d2d00002d2e, + 0x2d3000002d68, + 0x2d7f00002d97, + 0x2da000002da7, + 0x2da800002daf, + 0x2db000002db7, + 0x2db800002dbf, + 0x2dc000002dc7, + 0x2dc800002dcf, + 0x2dd000002dd7, + 0x2dd800002ddf, + 0x2de000002e00, + 0x2e2f00002e30, + 0x300500003008, + 0x302a0000302e, + 0x303c0000303d, + 0x304100003097, + 0x30990000309b, + 0x309d0000309f, + 0x30a1000030fb, + 0x30fc000030ff, + 0x31050000312f, + 0x31a0000031bb, + 0x31f000003200, + 0x340000004db6, + 0x4e0000009feb, + 0xa0000000a48d, + 0xa4d00000a4fe, + 0xa5000000a60d, + 0xa6100000a62c, + 0xa6410000a642, + 0xa6430000a644, + 0xa6450000a646, + 0xa6470000a648, + 0xa6490000a64a, + 0xa64b0000a64c, + 0xa64d0000a64e, + 0xa64f0000a650, + 0xa6510000a652, + 0xa6530000a654, + 0xa6550000a656, + 0xa6570000a658, + 0xa6590000a65a, + 0xa65b0000a65c, + 0xa65d0000a65e, + 0xa65f0000a660, + 0xa6610000a662, + 0xa6630000a664, + 0xa6650000a666, + 0xa6670000a668, + 0xa6690000a66a, + 0xa66b0000a66c, + 0xa66d0000a670, + 0xa6740000a67e, + 0xa67f0000a680, + 0xa6810000a682, + 0xa6830000a684, + 0xa6850000a686, + 0xa6870000a688, + 0xa6890000a68a, + 0xa68b0000a68c, + 0xa68d0000a68e, + 0xa68f0000a690, + 0xa6910000a692, + 0xa6930000a694, + 0xa6950000a696, + 0xa6970000a698, + 0xa6990000a69a, + 0xa69b0000a69c, + 0xa69e0000a6e6, + 0xa6f00000a6f2, + 0xa7170000a720, + 0xa7230000a724, + 0xa7250000a726, + 0xa7270000a728, + 0xa7290000a72a, + 0xa72b0000a72c, + 0xa72d0000a72e, + 0xa72f0000a732, + 0xa7330000a734, + 0xa7350000a736, + 0xa7370000a738, + 0xa7390000a73a, + 0xa73b0000a73c, + 0xa73d0000a73e, + 0xa73f0000a740, + 0xa7410000a742, + 0xa7430000a744, + 0xa7450000a746, + 0xa7470000a748, + 0xa7490000a74a, + 0xa74b0000a74c, + 0xa74d0000a74e, + 0xa74f0000a750, + 0xa7510000a752, + 0xa7530000a754, + 0xa7550000a756, + 0xa7570000a758, + 0xa7590000a75a, + 0xa75b0000a75c, + 0xa75d0000a75e, + 0xa75f0000a760, + 0xa7610000a762, + 0xa7630000a764, + 0xa7650000a766, + 0xa7670000a768, + 0xa7690000a76a, + 0xa76b0000a76c, + 0xa76d0000a76e, + 0xa76f0000a770, + 0xa7710000a779, + 0xa77a0000a77b, + 0xa77c0000a77d, + 0xa77f0000a780, + 0xa7810000a782, + 0xa7830000a784, + 0xa7850000a786, + 0xa7870000a789, + 0xa78c0000a78d, + 0xa78e0000a790, + 0xa7910000a792, + 0xa7930000a796, + 0xa7970000a798, + 0xa7990000a79a, + 0xa79b0000a79c, + 0xa79d0000a79e, + 0xa79f0000a7a0, + 0xa7a10000a7a2, + 0xa7a30000a7a4, + 0xa7a50000a7a6, + 0xa7a70000a7a8, + 0xa7a90000a7aa, + 0xa7b50000a7b6, + 0xa7b70000a7b8, + 0xa7f70000a7f8, + 0xa7fa0000a828, + 0xa8400000a874, + 0xa8800000a8c6, + 0xa8d00000a8da, + 0xa8e00000a8f8, + 0xa8fb0000a8fc, + 0xa8fd0000a8fe, + 0xa9000000a92e, + 0xa9300000a954, + 0xa9800000a9c1, + 0xa9cf0000a9da, + 0xa9e00000a9ff, + 0xaa000000aa37, + 0xaa400000aa4e, + 0xaa500000aa5a, + 0xaa600000aa77, + 0xaa7a0000aac3, + 0xaadb0000aade, + 0xaae00000aaf0, + 0xaaf20000aaf7, + 0xab010000ab07, + 0xab090000ab0f, + 0xab110000ab17, + 0xab200000ab27, + 0xab280000ab2f, + 0xab300000ab5b, + 0xab600000ab66, + 0xabc00000abeb, + 0xabec0000abee, + 0xabf00000abfa, + 0xac000000d7a4, + 0xfa0e0000fa10, + 0xfa110000fa12, + 0xfa130000fa15, + 0xfa1f0000fa20, + 0xfa210000fa22, + 0xfa230000fa25, + 0xfa270000fa2a, + 0xfb1e0000fb1f, + 0xfe200000fe30, + 0xfe730000fe74, + 0x100000001000c, + 0x1000d00010027, + 0x100280001003b, + 0x1003c0001003e, + 0x1003f0001004e, + 0x100500001005e, + 0x10080000100fb, + 0x101fd000101fe, + 0x102800001029d, + 0x102a0000102d1, + 0x102e0000102e1, + 0x1030000010320, + 0x1032d00010341, + 0x103420001034a, + 0x103500001037b, + 0x103800001039e, + 0x103a0000103c4, + 0x103c8000103d0, + 0x104280001049e, + 0x104a0000104aa, + 0x104d8000104fc, + 0x1050000010528, + 0x1053000010564, + 0x1060000010737, + 0x1074000010756, + 0x1076000010768, + 0x1080000010806, + 0x1080800010809, + 0x1080a00010836, + 0x1083700010839, + 0x1083c0001083d, + 0x1083f00010856, + 0x1086000010877, + 0x108800001089f, + 0x108e0000108f3, + 0x108f4000108f6, + 0x1090000010916, + 0x109200001093a, + 0x10980000109b8, + 0x109be000109c0, + 0x10a0000010a04, + 0x10a0500010a07, + 0x10a0c00010a14, + 0x10a1500010a18, + 0x10a1900010a34, + 0x10a3800010a3b, + 0x10a3f00010a40, + 0x10a6000010a7d, + 0x10a8000010a9d, + 0x10ac000010ac8, + 0x10ac900010ae7, + 0x10b0000010b36, + 0x10b4000010b56, + 0x10b6000010b73, + 0x10b8000010b92, + 0x10c0000010c49, + 0x10cc000010cf3, + 0x1100000011047, + 0x1106600011070, + 0x1107f000110bb, + 0x110d0000110e9, + 0x110f0000110fa, + 0x1110000011135, + 0x1113600011140, + 0x1115000011174, + 0x1117600011177, + 0x11180000111c5, + 0x111ca000111cd, + 0x111d0000111db, + 0x111dc000111dd, + 0x1120000011212, + 0x1121300011238, + 0x1123e0001123f, + 0x1128000011287, + 0x1128800011289, + 0x1128a0001128e, + 0x1128f0001129e, + 0x1129f000112a9, + 0x112b0000112eb, + 0x112f0000112fa, + 0x1130000011304, + 0x113050001130d, + 0x1130f00011311, + 0x1131300011329, + 0x1132a00011331, + 0x1133200011334, + 0x113350001133a, + 0x1133c00011345, + 0x1134700011349, + 0x1134b0001134e, + 0x1135000011351, + 0x1135700011358, + 0x1135d00011364, + 0x113660001136d, + 0x1137000011375, + 0x114000001144b, + 0x114500001145a, + 0x11480000114c6, + 0x114c7000114c8, + 0x114d0000114da, + 0x11580000115b6, + 0x115b8000115c1, + 0x115d8000115de, + 0x1160000011641, + 0x1164400011645, + 0x116500001165a, + 0x11680000116b8, + 0x116c0000116ca, + 0x117000001171a, + 0x1171d0001172c, + 0x117300001173a, + 0x118c0000118ea, + 0x118ff00011900, + 0x11a0000011a3f, + 0x11a4700011a48, + 0x11a5000011a84, + 0x11a8600011a9a, + 0x11ac000011af9, + 0x11c0000011c09, + 0x11c0a00011c37, + 0x11c3800011c41, + 0x11c5000011c5a, + 0x11c7200011c90, + 0x11c9200011ca8, + 0x11ca900011cb7, + 0x11d0000011d07, + 0x11d0800011d0a, + 0x11d0b00011d37, + 0x11d3a00011d3b, + 0x11d3c00011d3e, + 0x11d3f00011d48, + 0x11d5000011d5a, + 0x120000001239a, + 0x1248000012544, + 0x130000001342f, + 0x1440000014647, + 0x1680000016a39, + 0x16a4000016a5f, + 0x16a6000016a6a, + 0x16ad000016aee, + 0x16af000016af5, + 0x16b0000016b37, + 0x16b4000016b44, + 0x16b5000016b5a, + 0x16b6300016b78, + 0x16b7d00016b90, + 0x16f0000016f45, + 0x16f5000016f7f, + 0x16f8f00016fa0, + 0x16fe000016fe2, + 0x17000000187ed, + 0x1880000018af3, + 0x1b0000001b11f, + 0x1b1700001b2fc, + 0x1bc000001bc6b, + 0x1bc700001bc7d, + 0x1bc800001bc89, + 0x1bc900001bc9a, + 0x1bc9d0001bc9f, + 0x1da000001da37, + 0x1da3b0001da6d, + 0x1da750001da76, + 0x1da840001da85, + 0x1da9b0001daa0, + 0x1daa10001dab0, + 0x1e0000001e007, + 0x1e0080001e019, + 0x1e01b0001e022, + 0x1e0230001e025, + 0x1e0260001e02b, + 0x1e8000001e8c5, + 0x1e8d00001e8d7, + 0x1e9220001e94b, + 0x1e9500001e95a, + 0x200000002a6d7, + 0x2a7000002b735, + 0x2b7400002b81e, + 0x2b8200002cea2, + 0x2ceb00002ebe1, + ), + 'CONTEXTJ': ( + 0x200c0000200e, + ), + 'CONTEXTO': ( + 0xb7000000b8, + 0x37500000376, + 0x5f3000005f5, + 0x6600000066a, + 0x6f0000006fa, + 0x30fb000030fc, + ), +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py b/env/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py new file mode 100644 index 0000000..fa8a735 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/idna/intranges.py @@ -0,0 +1,53 @@ +""" +Given a list of integers, made up of (hopefully) a small number of long runs +of consecutive integers, compute a representation of the form +((start1, end1), (start2, end2) ...). Then answer the question "was x present +in the original list?" in time O(log(# runs)). +""" + +import bisect + +def intranges_from_list(list_): + """Represent a list of integers as a sequence of ranges: + ((start_0, end_0), (start_1, end_1), ...), such that the original + integers are exactly those x such that start_i <= x < end_i for some i. + + Ranges are encoded as single integers (start << 32 | end), not as tuples. + """ + + sorted_list = sorted(list_) + ranges = [] + last_write = -1 + for i in range(len(sorted_list)): + if i+1 < len(sorted_list): + if sorted_list[i] == sorted_list[i+1]-1: + continue + current_range = sorted_list[last_write+1:i+1] + ranges.append(_encode_range(current_range[0], current_range[-1] + 1)) + last_write = i + + return tuple(ranges) + +def _encode_range(start, end): + return (start << 32) | end + +def _decode_range(r): + return (r >> 32), (r & ((1 << 32) - 1)) + + +def intranges_contain(int_, ranges): + """Determine if `int_` falls into one of the ranges in `ranges`.""" + tuple_ = _encode_range(int_, 0) + pos = bisect.bisect_left(ranges, tuple_) + # we could be immediately ahead of a tuple (start, end) + # with start < int_ <= end + if pos > 0: + left, right = _decode_range(ranges[pos-1]) + if left <= int_ < right: + return True + # or we could be immediately behind a tuple (int_, end) + if pos < len(ranges): + left, _ = _decode_range(ranges[pos]) + if left == int_: + return True + return False diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py b/env/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py new file mode 100644 index 0000000..39c192b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/idna/package_data.py @@ -0,0 +1,2 @@ +__version__ = '2.7' + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py b/env/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py new file mode 100644 index 0000000..79731cb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/idna/uts46data.py @@ -0,0 +1,8179 @@ +# This file is automatically generated by tools/idna-data +# vim: set fileencoding=utf-8 : + +"""IDNA Mapping Table from UTS46.""" + + +__version__ = "10.0.0" +def _seg_0(): + return [ + (0x0, '3'), + (0x1, '3'), + (0x2, '3'), + (0x3, '3'), + (0x4, '3'), + (0x5, '3'), + (0x6, '3'), + (0x7, '3'), + (0x8, '3'), + (0x9, '3'), + (0xA, '3'), + (0xB, '3'), + (0xC, '3'), + (0xD, '3'), + (0xE, '3'), + (0xF, '3'), + (0x10, '3'), + (0x11, '3'), + (0x12, '3'), + (0x13, '3'), + (0x14, '3'), + (0x15, '3'), + (0x16, '3'), + (0x17, '3'), + (0x18, '3'), + (0x19, '3'), + (0x1A, '3'), + (0x1B, '3'), + (0x1C, '3'), + (0x1D, '3'), + (0x1E, '3'), + (0x1F, '3'), + (0x20, '3'), + (0x21, '3'), + (0x22, '3'), + (0x23, '3'), + (0x24, '3'), + (0x25, '3'), + (0x26, '3'), + (0x27, '3'), + (0x28, '3'), + (0x29, '3'), + (0x2A, '3'), + (0x2B, '3'), + (0x2C, '3'), + (0x2D, 'V'), + (0x2E, 'V'), + (0x2F, '3'), + (0x30, 'V'), + (0x31, 'V'), + (0x32, 'V'), + (0x33, 'V'), + (0x34, 'V'), + (0x35, 'V'), + (0x36, 'V'), + (0x37, 'V'), + (0x38, 'V'), + (0x39, 'V'), + (0x3A, '3'), + (0x3B, '3'), + (0x3C, '3'), + (0x3D, '3'), + (0x3E, '3'), + (0x3F, '3'), + (0x40, '3'), + (0x41, 'M', u'a'), + (0x42, 'M', u'b'), + (0x43, 'M', u'c'), + (0x44, 'M', u'd'), + (0x45, 'M', u'e'), + (0x46, 'M', u'f'), + (0x47, 'M', u'g'), + (0x48, 'M', u'h'), + (0x49, 'M', u'i'), + (0x4A, 'M', u'j'), + (0x4B, 'M', u'k'), + (0x4C, 'M', u'l'), + (0x4D, 'M', u'm'), + (0x4E, 'M', u'n'), + (0x4F, 'M', u'o'), + (0x50, 'M', u'p'), + (0x51, 'M', u'q'), + (0x52, 'M', u'r'), + (0x53, 'M', u's'), + (0x54, 'M', u't'), + (0x55, 'M', u'u'), + (0x56, 'M', u'v'), + (0x57, 'M', u'w'), + (0x58, 'M', u'x'), + (0x59, 'M', u'y'), + (0x5A, 'M', u'z'), + (0x5B, '3'), + (0x5C, '3'), + (0x5D, '3'), + (0x5E, '3'), + (0x5F, '3'), + (0x60, '3'), + (0x61, 'V'), + (0x62, 'V'), + (0x63, 'V'), + ] + +def _seg_1(): + return [ + (0x64, 'V'), + (0x65, 'V'), + (0x66, 'V'), + (0x67, 'V'), + (0x68, 'V'), + (0x69, 'V'), + (0x6A, 'V'), + (0x6B, 'V'), + (0x6C, 'V'), + (0x6D, 'V'), + (0x6E, 'V'), + (0x6F, 'V'), + (0x70, 'V'), + (0x71, 'V'), + (0x72, 'V'), + (0x73, 'V'), + (0x74, 'V'), + (0x75, 'V'), + (0x76, 'V'), + (0x77, 'V'), + (0x78, 'V'), + (0x79, 'V'), + (0x7A, 'V'), + (0x7B, '3'), + (0x7C, '3'), + (0x7D, '3'), + (0x7E, '3'), + (0x7F, '3'), + (0x80, 'X'), + (0x81, 'X'), + (0x82, 'X'), + (0x83, 'X'), + (0x84, 'X'), + (0x85, 'X'), + (0x86, 'X'), + (0x87, 'X'), + (0x88, 'X'), + (0x89, 'X'), + (0x8A, 'X'), + (0x8B, 'X'), + (0x8C, 'X'), + (0x8D, 'X'), + (0x8E, 'X'), + (0x8F, 'X'), + (0x90, 'X'), + (0x91, 'X'), + (0x92, 'X'), + (0x93, 'X'), + (0x94, 'X'), + (0x95, 'X'), + (0x96, 'X'), + (0x97, 'X'), + (0x98, 'X'), + (0x99, 'X'), + (0x9A, 'X'), + (0x9B, 'X'), + (0x9C, 'X'), + (0x9D, 'X'), + (0x9E, 'X'), + (0x9F, 'X'), + (0xA0, '3', u' '), + (0xA1, 'V'), + (0xA2, 'V'), + (0xA3, 'V'), + (0xA4, 'V'), + (0xA5, 'V'), + (0xA6, 'V'), + (0xA7, 'V'), + (0xA8, '3', u' ̈'), + (0xA9, 'V'), + (0xAA, 'M', u'a'), + (0xAB, 'V'), + (0xAC, 'V'), + (0xAD, 'I'), + (0xAE, 'V'), + (0xAF, '3', u' ̄'), + (0xB0, 'V'), + (0xB1, 'V'), + (0xB2, 'M', u'2'), + (0xB3, 'M', u'3'), + (0xB4, '3', u' ́'), + (0xB5, 'M', u'μ'), + (0xB6, 'V'), + (0xB7, 'V'), + (0xB8, '3', u' ̧'), + (0xB9, 'M', u'1'), + (0xBA, 'M', u'o'), + (0xBB, 'V'), + (0xBC, 'M', u'1⁄4'), + (0xBD, 'M', u'1⁄2'), + (0xBE, 'M', u'3⁄4'), + (0xBF, 'V'), + (0xC0, 'M', u'à'), + (0xC1, 'M', u'á'), + (0xC2, 'M', u'â'), + (0xC3, 'M', u'ã'), + (0xC4, 'M', u'ä'), + (0xC5, 'M', u'å'), + (0xC6, 'M', u'æ'), + (0xC7, 'M', u'ç'), + ] + +def _seg_2(): + return [ + (0xC8, 'M', u'è'), + (0xC9, 'M', u'é'), + (0xCA, 'M', u'ê'), + (0xCB, 'M', u'ë'), + (0xCC, 'M', u'ì'), + (0xCD, 'M', u'í'), + (0xCE, 'M', u'î'), + (0xCF, 'M', u'ï'), + (0xD0, 'M', u'ð'), + (0xD1, 'M', u'ñ'), + (0xD2, 'M', u'ò'), + (0xD3, 'M', u'ó'), + (0xD4, 'M', u'ô'), + (0xD5, 'M', u'õ'), + (0xD6, 'M', u'ö'), + (0xD7, 'V'), + (0xD8, 'M', u'ø'), + (0xD9, 'M', u'ù'), + (0xDA, 'M', u'ú'), + (0xDB, 'M', u'û'), + (0xDC, 'M', u'ü'), + (0xDD, 'M', u'ý'), + (0xDE, 'M', u'þ'), + (0xDF, 'D', u'ss'), + (0xE0, 'V'), + (0xE1, 'V'), + (0xE2, 'V'), + (0xE3, 'V'), + (0xE4, 'V'), + (0xE5, 'V'), + (0xE6, 'V'), + (0xE7, 'V'), + (0xE8, 'V'), + (0xE9, 'V'), + (0xEA, 'V'), + (0xEB, 'V'), + (0xEC, 'V'), + (0xED, 'V'), + (0xEE, 'V'), + (0xEF, 'V'), + (0xF0, 'V'), + (0xF1, 'V'), + (0xF2, 'V'), + (0xF3, 'V'), + (0xF4, 'V'), + (0xF5, 'V'), + (0xF6, 'V'), + (0xF7, 'V'), + (0xF8, 'V'), + (0xF9, 'V'), + (0xFA, 'V'), + (0xFB, 'V'), + (0xFC, 'V'), + (0xFD, 'V'), + (0xFE, 'V'), + (0xFF, 'V'), + (0x100, 'M', u'ā'), + (0x101, 'V'), + (0x102, 'M', u'ă'), + (0x103, 'V'), + (0x104, 'M', u'ą'), + (0x105, 'V'), + (0x106, 'M', u'ć'), + (0x107, 'V'), + (0x108, 'M', u'ĉ'), + (0x109, 'V'), + (0x10A, 'M', u'ċ'), + (0x10B, 'V'), + (0x10C, 'M', u'č'), + (0x10D, 'V'), + (0x10E, 'M', u'ď'), + (0x10F, 'V'), + (0x110, 'M', u'đ'), + (0x111, 'V'), + (0x112, 'M', u'ē'), + (0x113, 'V'), + (0x114, 'M', u'ĕ'), + (0x115, 'V'), + (0x116, 'M', u'ė'), + (0x117, 'V'), + (0x118, 'M', u'ę'), + (0x119, 'V'), + (0x11A, 'M', u'ě'), + (0x11B, 'V'), + (0x11C, 'M', u'ĝ'), + (0x11D, 'V'), + (0x11E, 'M', u'ğ'), + (0x11F, 'V'), + (0x120, 'M', u'ġ'), + (0x121, 'V'), + (0x122, 'M', u'ģ'), + (0x123, 'V'), + (0x124, 'M', u'ĥ'), + (0x125, 'V'), + (0x126, 'M', u'ħ'), + (0x127, 'V'), + (0x128, 'M', u'ĩ'), + (0x129, 'V'), + (0x12A, 'M', u'ī'), + (0x12B, 'V'), + ] + +def _seg_3(): + return [ + (0x12C, 'M', u'ĭ'), + (0x12D, 'V'), + (0x12E, 'M', u'į'), + (0x12F, 'V'), + (0x130, 'M', u'i̇'), + (0x131, 'V'), + (0x132, 'M', u'ij'), + (0x134, 'M', u'ĵ'), + (0x135, 'V'), + (0x136, 'M', u'ķ'), + (0x137, 'V'), + (0x139, 'M', u'ĺ'), + (0x13A, 'V'), + (0x13B, 'M', u'ļ'), + (0x13C, 'V'), + (0x13D, 'M', u'ľ'), + (0x13E, 'V'), + (0x13F, 'M', u'l·'), + (0x141, 'M', u'ł'), + (0x142, 'V'), + (0x143, 'M', u'ń'), + (0x144, 'V'), + (0x145, 'M', u'ņ'), + (0x146, 'V'), + (0x147, 'M', u'ň'), + (0x148, 'V'), + (0x149, 'M', u'ʼn'), + (0x14A, 'M', u'ŋ'), + (0x14B, 'V'), + (0x14C, 'M', u'ō'), + (0x14D, 'V'), + (0x14E, 'M', u'ŏ'), + (0x14F, 'V'), + (0x150, 'M', u'ő'), + (0x151, 'V'), + (0x152, 'M', u'œ'), + (0x153, 'V'), + (0x154, 'M', u'ŕ'), + (0x155, 'V'), + (0x156, 'M', u'ŗ'), + (0x157, 'V'), + (0x158, 'M', u'ř'), + (0x159, 'V'), + (0x15A, 'M', u'ś'), + (0x15B, 'V'), + (0x15C, 'M', u'ŝ'), + (0x15D, 'V'), + (0x15E, 'M', u'ş'), + (0x15F, 'V'), + (0x160, 'M', u'š'), + (0x161, 'V'), + (0x162, 'M', u'ţ'), + (0x163, 'V'), + (0x164, 'M', u'ť'), + (0x165, 'V'), + (0x166, 'M', u'ŧ'), + (0x167, 'V'), + (0x168, 'M', u'ũ'), + (0x169, 'V'), + (0x16A, 'M', u'ū'), + (0x16B, 'V'), + (0x16C, 'M', u'ŭ'), + (0x16D, 'V'), + (0x16E, 'M', u'ů'), + (0x16F, 'V'), + (0x170, 'M', u'ű'), + (0x171, 'V'), + (0x172, 'M', u'ų'), + (0x173, 'V'), + (0x174, 'M', u'ŵ'), + (0x175, 'V'), + (0x176, 'M', u'ŷ'), + (0x177, 'V'), + (0x178, 'M', u'ÿ'), + (0x179, 'M', u'ź'), + (0x17A, 'V'), + (0x17B, 'M', u'ż'), + (0x17C, 'V'), + (0x17D, 'M', u'ž'), + (0x17E, 'V'), + (0x17F, 'M', u's'), + (0x180, 'V'), + (0x181, 'M', u'ɓ'), + (0x182, 'M', u'ƃ'), + (0x183, 'V'), + (0x184, 'M', u'ƅ'), + (0x185, 'V'), + (0x186, 'M', u'ɔ'), + (0x187, 'M', u'ƈ'), + (0x188, 'V'), + (0x189, 'M', u'ɖ'), + (0x18A, 'M', u'ɗ'), + (0x18B, 'M', u'ƌ'), + (0x18C, 'V'), + (0x18E, 'M', u'ǝ'), + (0x18F, 'M', u'ə'), + (0x190, 'M', u'ɛ'), + (0x191, 'M', u'ƒ'), + (0x192, 'V'), + (0x193, 'M', u'ɠ'), + ] + +def _seg_4(): + return [ + (0x194, 'M', u'ɣ'), + (0x195, 'V'), + (0x196, 'M', u'ɩ'), + (0x197, 'M', u'ɨ'), + (0x198, 'M', u'ƙ'), + (0x199, 'V'), + (0x19C, 'M', u'ɯ'), + (0x19D, 'M', u'ɲ'), + (0x19E, 'V'), + (0x19F, 'M', u'ɵ'), + (0x1A0, 'M', u'ơ'), + (0x1A1, 'V'), + (0x1A2, 'M', u'ƣ'), + (0x1A3, 'V'), + (0x1A4, 'M', u'ƥ'), + (0x1A5, 'V'), + (0x1A6, 'M', u'ʀ'), + (0x1A7, 'M', u'ƨ'), + (0x1A8, 'V'), + (0x1A9, 'M', u'ʃ'), + (0x1AA, 'V'), + (0x1AC, 'M', u'ƭ'), + (0x1AD, 'V'), + (0x1AE, 'M', u'ʈ'), + (0x1AF, 'M', u'ư'), + (0x1B0, 'V'), + (0x1B1, 'M', u'ʊ'), + (0x1B2, 'M', u'ʋ'), + (0x1B3, 'M', u'ƴ'), + (0x1B4, 'V'), + (0x1B5, 'M', u'ƶ'), + (0x1B6, 'V'), + (0x1B7, 'M', u'ʒ'), + (0x1B8, 'M', u'ƹ'), + (0x1B9, 'V'), + (0x1BC, 'M', u'ƽ'), + (0x1BD, 'V'), + (0x1C4, 'M', u'dž'), + (0x1C7, 'M', u'lj'), + (0x1CA, 'M', u'nj'), + (0x1CD, 'M', u'ǎ'), + (0x1CE, 'V'), + (0x1CF, 'M', u'ǐ'), + (0x1D0, 'V'), + (0x1D1, 'M', u'ǒ'), + (0x1D2, 'V'), + (0x1D3, 'M', u'ǔ'), + (0x1D4, 'V'), + (0x1D5, 'M', u'ǖ'), + (0x1D6, 'V'), + (0x1D7, 'M', u'ǘ'), + (0x1D8, 'V'), + (0x1D9, 'M', u'ǚ'), + (0x1DA, 'V'), + (0x1DB, 'M', u'ǜ'), + (0x1DC, 'V'), + (0x1DE, 'M', u'ǟ'), + (0x1DF, 'V'), + (0x1E0, 'M', u'ǡ'), + (0x1E1, 'V'), + (0x1E2, 'M', u'ǣ'), + (0x1E3, 'V'), + (0x1E4, 'M', u'ǥ'), + (0x1E5, 'V'), + (0x1E6, 'M', u'ǧ'), + (0x1E7, 'V'), + (0x1E8, 'M', u'ǩ'), + (0x1E9, 'V'), + (0x1EA, 'M', u'ǫ'), + (0x1EB, 'V'), + (0x1EC, 'M', u'ǭ'), + (0x1ED, 'V'), + (0x1EE, 'M', u'ǯ'), + (0x1EF, 'V'), + (0x1F1, 'M', u'dz'), + (0x1F4, 'M', u'ǵ'), + (0x1F5, 'V'), + (0x1F6, 'M', u'ƕ'), + (0x1F7, 'M', u'ƿ'), + (0x1F8, 'M', u'ǹ'), + (0x1F9, 'V'), + (0x1FA, 'M', u'ǻ'), + (0x1FB, 'V'), + (0x1FC, 'M', u'ǽ'), + (0x1FD, 'V'), + (0x1FE, 'M', u'ǿ'), + (0x1FF, 'V'), + (0x200, 'M', u'ȁ'), + (0x201, 'V'), + (0x202, 'M', u'ȃ'), + (0x203, 'V'), + (0x204, 'M', u'ȅ'), + (0x205, 'V'), + (0x206, 'M', u'ȇ'), + (0x207, 'V'), + (0x208, 'M', u'ȉ'), + (0x209, 'V'), + (0x20A, 'M', u'ȋ'), + (0x20B, 'V'), + (0x20C, 'M', u'ȍ'), + ] + +def _seg_5(): + return [ + (0x20D, 'V'), + (0x20E, 'M', u'ȏ'), + (0x20F, 'V'), + (0x210, 'M', u'ȑ'), + (0x211, 'V'), + (0x212, 'M', u'ȓ'), + (0x213, 'V'), + (0x214, 'M', u'ȕ'), + (0x215, 'V'), + (0x216, 'M', u'ȗ'), + (0x217, 'V'), + (0x218, 'M', u'ș'), + (0x219, 'V'), + (0x21A, 'M', u'ț'), + (0x21B, 'V'), + (0x21C, 'M', u'ȝ'), + (0x21D, 'V'), + (0x21E, 'M', u'ȟ'), + (0x21F, 'V'), + (0x220, 'M', u'ƞ'), + (0x221, 'V'), + (0x222, 'M', u'ȣ'), + (0x223, 'V'), + (0x224, 'M', u'ȥ'), + (0x225, 'V'), + (0x226, 'M', u'ȧ'), + (0x227, 'V'), + (0x228, 'M', u'ȩ'), + (0x229, 'V'), + (0x22A, 'M', u'ȫ'), + (0x22B, 'V'), + (0x22C, 'M', u'ȭ'), + (0x22D, 'V'), + (0x22E, 'M', u'ȯ'), + (0x22F, 'V'), + (0x230, 'M', u'ȱ'), + (0x231, 'V'), + (0x232, 'M', u'ȳ'), + (0x233, 'V'), + (0x23A, 'M', u'ⱥ'), + (0x23B, 'M', u'ȼ'), + (0x23C, 'V'), + (0x23D, 'M', u'ƚ'), + (0x23E, 'M', u'ⱦ'), + (0x23F, 'V'), + (0x241, 'M', u'ɂ'), + (0x242, 'V'), + (0x243, 'M', u'ƀ'), + (0x244, 'M', u'ʉ'), + (0x245, 'M', u'ʌ'), + (0x246, 'M', u'ɇ'), + (0x247, 'V'), + (0x248, 'M', u'ɉ'), + (0x249, 'V'), + (0x24A, 'M', u'ɋ'), + (0x24B, 'V'), + (0x24C, 'M', u'ɍ'), + (0x24D, 'V'), + (0x24E, 'M', u'ɏ'), + (0x24F, 'V'), + (0x2B0, 'M', u'h'), + (0x2B1, 'M', u'ɦ'), + (0x2B2, 'M', u'j'), + (0x2B3, 'M', u'r'), + (0x2B4, 'M', u'ɹ'), + (0x2B5, 'M', u'ɻ'), + (0x2B6, 'M', u'ʁ'), + (0x2B7, 'M', u'w'), + (0x2B8, 'M', u'y'), + (0x2B9, 'V'), + (0x2D8, '3', u' ̆'), + (0x2D9, '3', u' ̇'), + (0x2DA, '3', u' ̊'), + (0x2DB, '3', u' ̨'), + (0x2DC, '3', u' ̃'), + (0x2DD, '3', u' ̋'), + (0x2DE, 'V'), + (0x2E0, 'M', u'ɣ'), + (0x2E1, 'M', u'l'), + (0x2E2, 'M', u's'), + (0x2E3, 'M', u'x'), + (0x2E4, 'M', u'ʕ'), + (0x2E5, 'V'), + (0x340, 'M', u'̀'), + (0x341, 'M', u'́'), + (0x342, 'V'), + (0x343, 'M', u'̓'), + (0x344, 'M', u'̈́'), + (0x345, 'M', u'ι'), + (0x346, 'V'), + (0x34F, 'I'), + (0x350, 'V'), + (0x370, 'M', u'ͱ'), + (0x371, 'V'), + (0x372, 'M', u'ͳ'), + (0x373, 'V'), + (0x374, 'M', u'ʹ'), + (0x375, 'V'), + (0x376, 'M', u'ͷ'), + (0x377, 'V'), + ] + +def _seg_6(): + return [ + (0x378, 'X'), + (0x37A, '3', u' ι'), + (0x37B, 'V'), + (0x37E, '3', u';'), + (0x37F, 'M', u'ϳ'), + (0x380, 'X'), + (0x384, '3', u' ́'), + (0x385, '3', u' ̈́'), + (0x386, 'M', u'ά'), + (0x387, 'M', u'·'), + (0x388, 'M', u'έ'), + (0x389, 'M', u'ή'), + (0x38A, 'M', u'ί'), + (0x38B, 'X'), + (0x38C, 'M', u'ό'), + (0x38D, 'X'), + (0x38E, 'M', u'ύ'), + (0x38F, 'M', u'ώ'), + (0x390, 'V'), + (0x391, 'M', u'α'), + (0x392, 'M', u'β'), + (0x393, 'M', u'γ'), + (0x394, 'M', u'δ'), + (0x395, 'M', u'ε'), + (0x396, 'M', u'ζ'), + (0x397, 'M', u'η'), + (0x398, 'M', u'θ'), + (0x399, 'M', u'ι'), + (0x39A, 'M', u'κ'), + (0x39B, 'M', u'λ'), + (0x39C, 'M', u'μ'), + (0x39D, 'M', u'ν'), + (0x39E, 'M', u'ξ'), + (0x39F, 'M', u'ο'), + (0x3A0, 'M', u'π'), + (0x3A1, 'M', u'ρ'), + (0x3A2, 'X'), + (0x3A3, 'M', u'σ'), + (0x3A4, 'M', u'τ'), + (0x3A5, 'M', u'υ'), + (0x3A6, 'M', u'φ'), + (0x3A7, 'M', u'χ'), + (0x3A8, 'M', u'ψ'), + (0x3A9, 'M', u'ω'), + (0x3AA, 'M', u'ϊ'), + (0x3AB, 'M', u'ϋ'), + (0x3AC, 'V'), + (0x3C2, 'D', u'σ'), + (0x3C3, 'V'), + (0x3CF, 'M', u'ϗ'), + (0x3D0, 'M', u'β'), + (0x3D1, 'M', u'θ'), + (0x3D2, 'M', u'υ'), + (0x3D3, 'M', u'ύ'), + (0x3D4, 'M', u'ϋ'), + (0x3D5, 'M', u'φ'), + (0x3D6, 'M', u'π'), + (0x3D7, 'V'), + (0x3D8, 'M', u'ϙ'), + (0x3D9, 'V'), + (0x3DA, 'M', u'ϛ'), + (0x3DB, 'V'), + (0x3DC, 'M', u'ϝ'), + (0x3DD, 'V'), + (0x3DE, 'M', u'ϟ'), + (0x3DF, 'V'), + (0x3E0, 'M', u'ϡ'), + (0x3E1, 'V'), + (0x3E2, 'M', u'ϣ'), + (0x3E3, 'V'), + (0x3E4, 'M', u'ϥ'), + (0x3E5, 'V'), + (0x3E6, 'M', u'ϧ'), + (0x3E7, 'V'), + (0x3E8, 'M', u'ϩ'), + (0x3E9, 'V'), + (0x3EA, 'M', u'ϫ'), + (0x3EB, 'V'), + (0x3EC, 'M', u'ϭ'), + (0x3ED, 'V'), + (0x3EE, 'M', u'ϯ'), + (0x3EF, 'V'), + (0x3F0, 'M', u'κ'), + (0x3F1, 'M', u'ρ'), + (0x3F2, 'M', u'σ'), + (0x3F3, 'V'), + (0x3F4, 'M', u'θ'), + (0x3F5, 'M', u'ε'), + (0x3F6, 'V'), + (0x3F7, 'M', u'ϸ'), + (0x3F8, 'V'), + (0x3F9, 'M', u'σ'), + (0x3FA, 'M', u'ϻ'), + (0x3FB, 'V'), + (0x3FD, 'M', u'ͻ'), + (0x3FE, 'M', u'ͼ'), + (0x3FF, 'M', u'ͽ'), + (0x400, 'M', u'ѐ'), + (0x401, 'M', u'ё'), + (0x402, 'M', u'ђ'), + ] + +def _seg_7(): + return [ + (0x403, 'M', u'ѓ'), + (0x404, 'M', u'є'), + (0x405, 'M', u'ѕ'), + (0x406, 'M', u'і'), + (0x407, 'M', u'ї'), + (0x408, 'M', u'ј'), + (0x409, 'M', u'љ'), + (0x40A, 'M', u'њ'), + (0x40B, 'M', u'ћ'), + (0x40C, 'M', u'ќ'), + (0x40D, 'M', u'ѝ'), + (0x40E, 'M', u'ў'), + (0x40F, 'M', u'џ'), + (0x410, 'M', u'а'), + (0x411, 'M', u'б'), + (0x412, 'M', u'в'), + (0x413, 'M', u'г'), + (0x414, 'M', u'д'), + (0x415, 'M', u'е'), + (0x416, 'M', u'ж'), + (0x417, 'M', u'з'), + (0x418, 'M', u'и'), + (0x419, 'M', u'й'), + (0x41A, 'M', u'к'), + (0x41B, 'M', u'л'), + (0x41C, 'M', u'м'), + (0x41D, 'M', u'н'), + (0x41E, 'M', u'о'), + (0x41F, 'M', u'п'), + (0x420, 'M', u'р'), + (0x421, 'M', u'с'), + (0x422, 'M', u'т'), + (0x423, 'M', u'у'), + (0x424, 'M', u'ф'), + (0x425, 'M', u'х'), + (0x426, 'M', u'ц'), + (0x427, 'M', u'ч'), + (0x428, 'M', u'ш'), + (0x429, 'M', u'щ'), + (0x42A, 'M', u'ъ'), + (0x42B, 'M', u'ы'), + (0x42C, 'M', u'ь'), + (0x42D, 'M', u'э'), + (0x42E, 'M', u'ю'), + (0x42F, 'M', u'я'), + (0x430, 'V'), + (0x460, 'M', u'ѡ'), + (0x461, 'V'), + (0x462, 'M', u'ѣ'), + (0x463, 'V'), + (0x464, 'M', u'ѥ'), + (0x465, 'V'), + (0x466, 'M', u'ѧ'), + (0x467, 'V'), + (0x468, 'M', u'ѩ'), + (0x469, 'V'), + (0x46A, 'M', u'ѫ'), + (0x46B, 'V'), + (0x46C, 'M', u'ѭ'), + (0x46D, 'V'), + (0x46E, 'M', u'ѯ'), + (0x46F, 'V'), + (0x470, 'M', u'ѱ'), + (0x471, 'V'), + (0x472, 'M', u'ѳ'), + (0x473, 'V'), + (0x474, 'M', u'ѵ'), + (0x475, 'V'), + (0x476, 'M', u'ѷ'), + (0x477, 'V'), + (0x478, 'M', u'ѹ'), + (0x479, 'V'), + (0x47A, 'M', u'ѻ'), + (0x47B, 'V'), + (0x47C, 'M', u'ѽ'), + (0x47D, 'V'), + (0x47E, 'M', u'ѿ'), + (0x47F, 'V'), + (0x480, 'M', u'ҁ'), + (0x481, 'V'), + (0x48A, 'M', u'ҋ'), + (0x48B, 'V'), + (0x48C, 'M', u'ҍ'), + (0x48D, 'V'), + (0x48E, 'M', u'ҏ'), + (0x48F, 'V'), + (0x490, 'M', u'ґ'), + (0x491, 'V'), + (0x492, 'M', u'ғ'), + (0x493, 'V'), + (0x494, 'M', u'ҕ'), + (0x495, 'V'), + (0x496, 'M', u'җ'), + (0x497, 'V'), + (0x498, 'M', u'ҙ'), + (0x499, 'V'), + (0x49A, 'M', u'қ'), + (0x49B, 'V'), + (0x49C, 'M', u'ҝ'), + (0x49D, 'V'), + ] + +def _seg_8(): + return [ + (0x49E, 'M', u'ҟ'), + (0x49F, 'V'), + (0x4A0, 'M', u'ҡ'), + (0x4A1, 'V'), + (0x4A2, 'M', u'ң'), + (0x4A3, 'V'), + (0x4A4, 'M', u'ҥ'), + (0x4A5, 'V'), + (0x4A6, 'M', u'ҧ'), + (0x4A7, 'V'), + (0x4A8, 'M', u'ҩ'), + (0x4A9, 'V'), + (0x4AA, 'M', u'ҫ'), + (0x4AB, 'V'), + (0x4AC, 'M', u'ҭ'), + (0x4AD, 'V'), + (0x4AE, 'M', u'ү'), + (0x4AF, 'V'), + (0x4B0, 'M', u'ұ'), + (0x4B1, 'V'), + (0x4B2, 'M', u'ҳ'), + (0x4B3, 'V'), + (0x4B4, 'M', u'ҵ'), + (0x4B5, 'V'), + (0x4B6, 'M', u'ҷ'), + (0x4B7, 'V'), + (0x4B8, 'M', u'ҹ'), + (0x4B9, 'V'), + (0x4BA, 'M', u'һ'), + (0x4BB, 'V'), + (0x4BC, 'M', u'ҽ'), + (0x4BD, 'V'), + (0x4BE, 'M', u'ҿ'), + (0x4BF, 'V'), + (0x4C0, 'X'), + (0x4C1, 'M', u'ӂ'), + (0x4C2, 'V'), + (0x4C3, 'M', u'ӄ'), + (0x4C4, 'V'), + (0x4C5, 'M', u'ӆ'), + (0x4C6, 'V'), + (0x4C7, 'M', u'ӈ'), + (0x4C8, 'V'), + (0x4C9, 'M', u'ӊ'), + (0x4CA, 'V'), + (0x4CB, 'M', u'ӌ'), + (0x4CC, 'V'), + (0x4CD, 'M', u'ӎ'), + (0x4CE, 'V'), + (0x4D0, 'M', u'ӑ'), + (0x4D1, 'V'), + (0x4D2, 'M', u'ӓ'), + (0x4D3, 'V'), + (0x4D4, 'M', u'ӕ'), + (0x4D5, 'V'), + (0x4D6, 'M', u'ӗ'), + (0x4D7, 'V'), + (0x4D8, 'M', u'ә'), + (0x4D9, 'V'), + (0x4DA, 'M', u'ӛ'), + (0x4DB, 'V'), + (0x4DC, 'M', u'ӝ'), + (0x4DD, 'V'), + (0x4DE, 'M', u'ӟ'), + (0x4DF, 'V'), + (0x4E0, 'M', u'ӡ'), + (0x4E1, 'V'), + (0x4E2, 'M', u'ӣ'), + (0x4E3, 'V'), + (0x4E4, 'M', u'ӥ'), + (0x4E5, 'V'), + (0x4E6, 'M', u'ӧ'), + (0x4E7, 'V'), + (0x4E8, 'M', u'ө'), + (0x4E9, 'V'), + (0x4EA, 'M', u'ӫ'), + (0x4EB, 'V'), + (0x4EC, 'M', u'ӭ'), + (0x4ED, 'V'), + (0x4EE, 'M', u'ӯ'), + (0x4EF, 'V'), + (0x4F0, 'M', u'ӱ'), + (0x4F1, 'V'), + (0x4F2, 'M', u'ӳ'), + (0x4F3, 'V'), + (0x4F4, 'M', u'ӵ'), + (0x4F5, 'V'), + (0x4F6, 'M', u'ӷ'), + (0x4F7, 'V'), + (0x4F8, 'M', u'ӹ'), + (0x4F9, 'V'), + (0x4FA, 'M', u'ӻ'), + (0x4FB, 'V'), + (0x4FC, 'M', u'ӽ'), + (0x4FD, 'V'), + (0x4FE, 'M', u'ӿ'), + (0x4FF, 'V'), + (0x500, 'M', u'ԁ'), + (0x501, 'V'), + (0x502, 'M', u'ԃ'), + ] + +def _seg_9(): + return [ + (0x503, 'V'), + (0x504, 'M', u'ԅ'), + (0x505, 'V'), + (0x506, 'M', u'ԇ'), + (0x507, 'V'), + (0x508, 'M', u'ԉ'), + (0x509, 'V'), + (0x50A, 'M', u'ԋ'), + (0x50B, 'V'), + (0x50C, 'M', u'ԍ'), + (0x50D, 'V'), + (0x50E, 'M', u'ԏ'), + (0x50F, 'V'), + (0x510, 'M', u'ԑ'), + (0x511, 'V'), + (0x512, 'M', u'ԓ'), + (0x513, 'V'), + (0x514, 'M', u'ԕ'), + (0x515, 'V'), + (0x516, 'M', u'ԗ'), + (0x517, 'V'), + (0x518, 'M', u'ԙ'), + (0x519, 'V'), + (0x51A, 'M', u'ԛ'), + (0x51B, 'V'), + (0x51C, 'M', u'ԝ'), + (0x51D, 'V'), + (0x51E, 'M', u'ԟ'), + (0x51F, 'V'), + (0x520, 'M', u'ԡ'), + (0x521, 'V'), + (0x522, 'M', u'ԣ'), + (0x523, 'V'), + (0x524, 'M', u'ԥ'), + (0x525, 'V'), + (0x526, 'M', u'ԧ'), + (0x527, 'V'), + (0x528, 'M', u'ԩ'), + (0x529, 'V'), + (0x52A, 'M', u'ԫ'), + (0x52B, 'V'), + (0x52C, 'M', u'ԭ'), + (0x52D, 'V'), + (0x52E, 'M', u'ԯ'), + (0x52F, 'V'), + (0x530, 'X'), + (0x531, 'M', u'ա'), + (0x532, 'M', u'բ'), + (0x533, 'M', u'գ'), + (0x534, 'M', u'դ'), + (0x535, 'M', u'ե'), + (0x536, 'M', u'զ'), + (0x537, 'M', u'է'), + (0x538, 'M', u'ը'), + (0x539, 'M', u'թ'), + (0x53A, 'M', u'ժ'), + (0x53B, 'M', u'ի'), + (0x53C, 'M', u'լ'), + (0x53D, 'M', u'խ'), + (0x53E, 'M', u'ծ'), + (0x53F, 'M', u'կ'), + (0x540, 'M', u'հ'), + (0x541, 'M', u'ձ'), + (0x542, 'M', u'ղ'), + (0x543, 'M', u'ճ'), + (0x544, 'M', u'մ'), + (0x545, 'M', u'յ'), + (0x546, 'M', u'ն'), + (0x547, 'M', u'շ'), + (0x548, 'M', u'ո'), + (0x549, 'M', u'չ'), + (0x54A, 'M', u'պ'), + (0x54B, 'M', u'ջ'), + (0x54C, 'M', u'ռ'), + (0x54D, 'M', u'ս'), + (0x54E, 'M', u'վ'), + (0x54F, 'M', u'տ'), + (0x550, 'M', u'ր'), + (0x551, 'M', u'ց'), + (0x552, 'M', u'ւ'), + (0x553, 'M', u'փ'), + (0x554, 'M', u'ք'), + (0x555, 'M', u'օ'), + (0x556, 'M', u'ֆ'), + (0x557, 'X'), + (0x559, 'V'), + (0x560, 'X'), + (0x561, 'V'), + (0x587, 'M', u'եւ'), + (0x588, 'X'), + (0x589, 'V'), + (0x58B, 'X'), + (0x58D, 'V'), + (0x590, 'X'), + (0x591, 'V'), + (0x5C8, 'X'), + (0x5D0, 'V'), + (0x5EB, 'X'), + (0x5F0, 'V'), + (0x5F5, 'X'), + ] + +def _seg_10(): + return [ + (0x606, 'V'), + (0x61C, 'X'), + (0x61E, 'V'), + (0x675, 'M', u'اٴ'), + (0x676, 'M', u'وٴ'), + (0x677, 'M', u'ۇٴ'), + (0x678, 'M', u'يٴ'), + (0x679, 'V'), + (0x6DD, 'X'), + (0x6DE, 'V'), + (0x70E, 'X'), + (0x710, 'V'), + (0x74B, 'X'), + (0x74D, 'V'), + (0x7B2, 'X'), + (0x7C0, 'V'), + (0x7FB, 'X'), + (0x800, 'V'), + (0x82E, 'X'), + (0x830, 'V'), + (0x83F, 'X'), + (0x840, 'V'), + (0x85C, 'X'), + (0x85E, 'V'), + (0x85F, 'X'), + (0x860, 'V'), + (0x86B, 'X'), + (0x8A0, 'V'), + (0x8B5, 'X'), + (0x8B6, 'V'), + (0x8BE, 'X'), + (0x8D4, 'V'), + (0x8E2, 'X'), + (0x8E3, 'V'), + (0x958, 'M', u'क़'), + (0x959, 'M', u'ख़'), + (0x95A, 'M', u'ग़'), + (0x95B, 'M', u'ज़'), + (0x95C, 'M', u'ड़'), + (0x95D, 'M', u'ढ़'), + (0x95E, 'M', u'फ़'), + (0x95F, 'M', u'य़'), + (0x960, 'V'), + (0x984, 'X'), + (0x985, 'V'), + (0x98D, 'X'), + (0x98F, 'V'), + (0x991, 'X'), + (0x993, 'V'), + (0x9A9, 'X'), + (0x9AA, 'V'), + (0x9B1, 'X'), + (0x9B2, 'V'), + (0x9B3, 'X'), + (0x9B6, 'V'), + (0x9BA, 'X'), + (0x9BC, 'V'), + (0x9C5, 'X'), + (0x9C7, 'V'), + (0x9C9, 'X'), + (0x9CB, 'V'), + (0x9CF, 'X'), + (0x9D7, 'V'), + (0x9D8, 'X'), + (0x9DC, 'M', u'ড়'), + (0x9DD, 'M', u'ঢ়'), + (0x9DE, 'X'), + (0x9DF, 'M', u'য়'), + (0x9E0, 'V'), + (0x9E4, 'X'), + (0x9E6, 'V'), + (0x9FE, 'X'), + (0xA01, 'V'), + (0xA04, 'X'), + (0xA05, 'V'), + (0xA0B, 'X'), + (0xA0F, 'V'), + (0xA11, 'X'), + (0xA13, 'V'), + (0xA29, 'X'), + (0xA2A, 'V'), + (0xA31, 'X'), + (0xA32, 'V'), + (0xA33, 'M', u'ਲ਼'), + (0xA34, 'X'), + (0xA35, 'V'), + (0xA36, 'M', u'ਸ਼'), + (0xA37, 'X'), + (0xA38, 'V'), + (0xA3A, 'X'), + (0xA3C, 'V'), + (0xA3D, 'X'), + (0xA3E, 'V'), + (0xA43, 'X'), + (0xA47, 'V'), + (0xA49, 'X'), + (0xA4B, 'V'), + (0xA4E, 'X'), + (0xA51, 'V'), + (0xA52, 'X'), + ] + +def _seg_11(): + return [ + (0xA59, 'M', u'ਖ਼'), + (0xA5A, 'M', u'ਗ਼'), + (0xA5B, 'M', u'ਜ਼'), + (0xA5C, 'V'), + (0xA5D, 'X'), + (0xA5E, 'M', u'ਫ਼'), + (0xA5F, 'X'), + (0xA66, 'V'), + (0xA76, 'X'), + (0xA81, 'V'), + (0xA84, 'X'), + (0xA85, 'V'), + (0xA8E, 'X'), + (0xA8F, 'V'), + (0xA92, 'X'), + (0xA93, 'V'), + (0xAA9, 'X'), + (0xAAA, 'V'), + (0xAB1, 'X'), + (0xAB2, 'V'), + (0xAB4, 'X'), + (0xAB5, 'V'), + (0xABA, 'X'), + (0xABC, 'V'), + (0xAC6, 'X'), + (0xAC7, 'V'), + (0xACA, 'X'), + (0xACB, 'V'), + (0xACE, 'X'), + (0xAD0, 'V'), + (0xAD1, 'X'), + (0xAE0, 'V'), + (0xAE4, 'X'), + (0xAE6, 'V'), + (0xAF2, 'X'), + (0xAF9, 'V'), + (0xB00, 'X'), + (0xB01, 'V'), + (0xB04, 'X'), + (0xB05, 'V'), + (0xB0D, 'X'), + (0xB0F, 'V'), + (0xB11, 'X'), + (0xB13, 'V'), + (0xB29, 'X'), + (0xB2A, 'V'), + (0xB31, 'X'), + (0xB32, 'V'), + (0xB34, 'X'), + (0xB35, 'V'), + (0xB3A, 'X'), + (0xB3C, 'V'), + (0xB45, 'X'), + (0xB47, 'V'), + (0xB49, 'X'), + (0xB4B, 'V'), + (0xB4E, 'X'), + (0xB56, 'V'), + (0xB58, 'X'), + (0xB5C, 'M', u'ଡ଼'), + (0xB5D, 'M', u'ଢ଼'), + (0xB5E, 'X'), + (0xB5F, 'V'), + (0xB64, 'X'), + (0xB66, 'V'), + (0xB78, 'X'), + (0xB82, 'V'), + (0xB84, 'X'), + (0xB85, 'V'), + (0xB8B, 'X'), + (0xB8E, 'V'), + (0xB91, 'X'), + (0xB92, 'V'), + (0xB96, 'X'), + (0xB99, 'V'), + (0xB9B, 'X'), + (0xB9C, 'V'), + (0xB9D, 'X'), + (0xB9E, 'V'), + (0xBA0, 'X'), + (0xBA3, 'V'), + (0xBA5, 'X'), + (0xBA8, 'V'), + (0xBAB, 'X'), + (0xBAE, 'V'), + (0xBBA, 'X'), + (0xBBE, 'V'), + (0xBC3, 'X'), + (0xBC6, 'V'), + (0xBC9, 'X'), + (0xBCA, 'V'), + (0xBCE, 'X'), + (0xBD0, 'V'), + (0xBD1, 'X'), + (0xBD7, 'V'), + (0xBD8, 'X'), + (0xBE6, 'V'), + (0xBFB, 'X'), + (0xC00, 'V'), + (0xC04, 'X'), + ] + +def _seg_12(): + return [ + (0xC05, 'V'), + (0xC0D, 'X'), + (0xC0E, 'V'), + (0xC11, 'X'), + (0xC12, 'V'), + (0xC29, 'X'), + (0xC2A, 'V'), + (0xC3A, 'X'), + (0xC3D, 'V'), + (0xC45, 'X'), + (0xC46, 'V'), + (0xC49, 'X'), + (0xC4A, 'V'), + (0xC4E, 'X'), + (0xC55, 'V'), + (0xC57, 'X'), + (0xC58, 'V'), + (0xC5B, 'X'), + (0xC60, 'V'), + (0xC64, 'X'), + (0xC66, 'V'), + (0xC70, 'X'), + (0xC78, 'V'), + (0xC84, 'X'), + (0xC85, 'V'), + (0xC8D, 'X'), + (0xC8E, 'V'), + (0xC91, 'X'), + (0xC92, 'V'), + (0xCA9, 'X'), + (0xCAA, 'V'), + (0xCB4, 'X'), + (0xCB5, 'V'), + (0xCBA, 'X'), + (0xCBC, 'V'), + (0xCC5, 'X'), + (0xCC6, 'V'), + (0xCC9, 'X'), + (0xCCA, 'V'), + (0xCCE, 'X'), + (0xCD5, 'V'), + (0xCD7, 'X'), + (0xCDE, 'V'), + (0xCDF, 'X'), + (0xCE0, 'V'), + (0xCE4, 'X'), + (0xCE6, 'V'), + (0xCF0, 'X'), + (0xCF1, 'V'), + (0xCF3, 'X'), + (0xD00, 'V'), + (0xD04, 'X'), + (0xD05, 'V'), + (0xD0D, 'X'), + (0xD0E, 'V'), + (0xD11, 'X'), + (0xD12, 'V'), + (0xD45, 'X'), + (0xD46, 'V'), + (0xD49, 'X'), + (0xD4A, 'V'), + (0xD50, 'X'), + (0xD54, 'V'), + (0xD64, 'X'), + (0xD66, 'V'), + (0xD80, 'X'), + (0xD82, 'V'), + (0xD84, 'X'), + (0xD85, 'V'), + (0xD97, 'X'), + (0xD9A, 'V'), + (0xDB2, 'X'), + (0xDB3, 'V'), + (0xDBC, 'X'), + (0xDBD, 'V'), + (0xDBE, 'X'), + (0xDC0, 'V'), + (0xDC7, 'X'), + (0xDCA, 'V'), + (0xDCB, 'X'), + (0xDCF, 'V'), + (0xDD5, 'X'), + (0xDD6, 'V'), + (0xDD7, 'X'), + (0xDD8, 'V'), + (0xDE0, 'X'), + (0xDE6, 'V'), + (0xDF0, 'X'), + (0xDF2, 'V'), + (0xDF5, 'X'), + (0xE01, 'V'), + (0xE33, 'M', u'ํา'), + (0xE34, 'V'), + (0xE3B, 'X'), + (0xE3F, 'V'), + (0xE5C, 'X'), + (0xE81, 'V'), + (0xE83, 'X'), + (0xE84, 'V'), + (0xE85, 'X'), + ] + +def _seg_13(): + return [ + (0xE87, 'V'), + (0xE89, 'X'), + (0xE8A, 'V'), + (0xE8B, 'X'), + (0xE8D, 'V'), + (0xE8E, 'X'), + (0xE94, 'V'), + (0xE98, 'X'), + (0xE99, 'V'), + (0xEA0, 'X'), + (0xEA1, 'V'), + (0xEA4, 'X'), + (0xEA5, 'V'), + (0xEA6, 'X'), + (0xEA7, 'V'), + (0xEA8, 'X'), + (0xEAA, 'V'), + (0xEAC, 'X'), + (0xEAD, 'V'), + (0xEB3, 'M', u'ໍາ'), + (0xEB4, 'V'), + (0xEBA, 'X'), + (0xEBB, 'V'), + (0xEBE, 'X'), + (0xEC0, 'V'), + (0xEC5, 'X'), + (0xEC6, 'V'), + (0xEC7, 'X'), + (0xEC8, 'V'), + (0xECE, 'X'), + (0xED0, 'V'), + (0xEDA, 'X'), + (0xEDC, 'M', u'ຫນ'), + (0xEDD, 'M', u'ຫມ'), + (0xEDE, 'V'), + (0xEE0, 'X'), + (0xF00, 'V'), + (0xF0C, 'M', u'་'), + (0xF0D, 'V'), + (0xF43, 'M', u'གྷ'), + (0xF44, 'V'), + (0xF48, 'X'), + (0xF49, 'V'), + (0xF4D, 'M', u'ཌྷ'), + (0xF4E, 'V'), + (0xF52, 'M', u'དྷ'), + (0xF53, 'V'), + (0xF57, 'M', u'བྷ'), + (0xF58, 'V'), + (0xF5C, 'M', u'ཛྷ'), + (0xF5D, 'V'), + (0xF69, 'M', u'ཀྵ'), + (0xF6A, 'V'), + (0xF6D, 'X'), + (0xF71, 'V'), + (0xF73, 'M', u'ཱི'), + (0xF74, 'V'), + (0xF75, 'M', u'ཱུ'), + (0xF76, 'M', u'ྲྀ'), + (0xF77, 'M', u'ྲཱྀ'), + (0xF78, 'M', u'ླྀ'), + (0xF79, 'M', u'ླཱྀ'), + (0xF7A, 'V'), + (0xF81, 'M', u'ཱྀ'), + (0xF82, 'V'), + (0xF93, 'M', u'ྒྷ'), + (0xF94, 'V'), + (0xF98, 'X'), + (0xF99, 'V'), + (0xF9D, 'M', u'ྜྷ'), + (0xF9E, 'V'), + (0xFA2, 'M', u'ྡྷ'), + (0xFA3, 'V'), + (0xFA7, 'M', u'ྦྷ'), + (0xFA8, 'V'), + (0xFAC, 'M', u'ྫྷ'), + (0xFAD, 'V'), + (0xFB9, 'M', u'ྐྵ'), + (0xFBA, 'V'), + (0xFBD, 'X'), + (0xFBE, 'V'), + (0xFCD, 'X'), + (0xFCE, 'V'), + (0xFDB, 'X'), + (0x1000, 'V'), + (0x10A0, 'X'), + (0x10C7, 'M', u'ⴧ'), + (0x10C8, 'X'), + (0x10CD, 'M', u'ⴭ'), + (0x10CE, 'X'), + (0x10D0, 'V'), + (0x10FC, 'M', u'ნ'), + (0x10FD, 'V'), + (0x115F, 'X'), + (0x1161, 'V'), + (0x1249, 'X'), + (0x124A, 'V'), + (0x124E, 'X'), + (0x1250, 'V'), + (0x1257, 'X'), + ] + +def _seg_14(): + return [ + (0x1258, 'V'), + (0x1259, 'X'), + (0x125A, 'V'), + (0x125E, 'X'), + (0x1260, 'V'), + (0x1289, 'X'), + (0x128A, 'V'), + (0x128E, 'X'), + (0x1290, 'V'), + (0x12B1, 'X'), + (0x12B2, 'V'), + (0x12B6, 'X'), + (0x12B8, 'V'), + (0x12BF, 'X'), + (0x12C0, 'V'), + (0x12C1, 'X'), + (0x12C2, 'V'), + (0x12C6, 'X'), + (0x12C8, 'V'), + (0x12D7, 'X'), + (0x12D8, 'V'), + (0x1311, 'X'), + (0x1312, 'V'), + (0x1316, 'X'), + (0x1318, 'V'), + (0x135B, 'X'), + (0x135D, 'V'), + (0x137D, 'X'), + (0x1380, 'V'), + (0x139A, 'X'), + (0x13A0, 'V'), + (0x13F6, 'X'), + (0x13F8, 'M', u'Ᏸ'), + (0x13F9, 'M', u'Ᏹ'), + (0x13FA, 'M', u'Ᏺ'), + (0x13FB, 'M', u'Ᏻ'), + (0x13FC, 'M', u'Ᏼ'), + (0x13FD, 'M', u'Ᏽ'), + (0x13FE, 'X'), + (0x1400, 'V'), + (0x1680, 'X'), + (0x1681, 'V'), + (0x169D, 'X'), + (0x16A0, 'V'), + (0x16F9, 'X'), + (0x1700, 'V'), + (0x170D, 'X'), + (0x170E, 'V'), + (0x1715, 'X'), + (0x1720, 'V'), + (0x1737, 'X'), + (0x1740, 'V'), + (0x1754, 'X'), + (0x1760, 'V'), + (0x176D, 'X'), + (0x176E, 'V'), + (0x1771, 'X'), + (0x1772, 'V'), + (0x1774, 'X'), + (0x1780, 'V'), + (0x17B4, 'X'), + (0x17B6, 'V'), + (0x17DE, 'X'), + (0x17E0, 'V'), + (0x17EA, 'X'), + (0x17F0, 'V'), + (0x17FA, 'X'), + (0x1800, 'V'), + (0x1806, 'X'), + (0x1807, 'V'), + (0x180B, 'I'), + (0x180E, 'X'), + (0x1810, 'V'), + (0x181A, 'X'), + (0x1820, 'V'), + (0x1878, 'X'), + (0x1880, 'V'), + (0x18AB, 'X'), + (0x18B0, 'V'), + (0x18F6, 'X'), + (0x1900, 'V'), + (0x191F, 'X'), + (0x1920, 'V'), + (0x192C, 'X'), + (0x1930, 'V'), + (0x193C, 'X'), + (0x1940, 'V'), + (0x1941, 'X'), + (0x1944, 'V'), + (0x196E, 'X'), + (0x1970, 'V'), + (0x1975, 'X'), + (0x1980, 'V'), + (0x19AC, 'X'), + (0x19B0, 'V'), + (0x19CA, 'X'), + (0x19D0, 'V'), + (0x19DB, 'X'), + (0x19DE, 'V'), + (0x1A1C, 'X'), + ] + +def _seg_15(): + return [ + (0x1A1E, 'V'), + (0x1A5F, 'X'), + (0x1A60, 'V'), + (0x1A7D, 'X'), + (0x1A7F, 'V'), + (0x1A8A, 'X'), + (0x1A90, 'V'), + (0x1A9A, 'X'), + (0x1AA0, 'V'), + (0x1AAE, 'X'), + (0x1AB0, 'V'), + (0x1ABF, 'X'), + (0x1B00, 'V'), + (0x1B4C, 'X'), + (0x1B50, 'V'), + (0x1B7D, 'X'), + (0x1B80, 'V'), + (0x1BF4, 'X'), + (0x1BFC, 'V'), + (0x1C38, 'X'), + (0x1C3B, 'V'), + (0x1C4A, 'X'), + (0x1C4D, 'V'), + (0x1C80, 'M', u'в'), + (0x1C81, 'M', u'д'), + (0x1C82, 'M', u'о'), + (0x1C83, 'M', u'с'), + (0x1C84, 'M', u'т'), + (0x1C86, 'M', u'ъ'), + (0x1C87, 'M', u'ѣ'), + (0x1C88, 'M', u'ꙋ'), + (0x1C89, 'X'), + (0x1CC0, 'V'), + (0x1CC8, 'X'), + (0x1CD0, 'V'), + (0x1CFA, 'X'), + (0x1D00, 'V'), + (0x1D2C, 'M', u'a'), + (0x1D2D, 'M', u'æ'), + (0x1D2E, 'M', u'b'), + (0x1D2F, 'V'), + (0x1D30, 'M', u'd'), + (0x1D31, 'M', u'e'), + (0x1D32, 'M', u'ǝ'), + (0x1D33, 'M', u'g'), + (0x1D34, 'M', u'h'), + (0x1D35, 'M', u'i'), + (0x1D36, 'M', u'j'), + (0x1D37, 'M', u'k'), + (0x1D38, 'M', u'l'), + (0x1D39, 'M', u'm'), + (0x1D3A, 'M', u'n'), + (0x1D3B, 'V'), + (0x1D3C, 'M', u'o'), + (0x1D3D, 'M', u'ȣ'), + (0x1D3E, 'M', u'p'), + (0x1D3F, 'M', u'r'), + (0x1D40, 'M', u't'), + (0x1D41, 'M', u'u'), + (0x1D42, 'M', u'w'), + (0x1D43, 'M', u'a'), + (0x1D44, 'M', u'ɐ'), + (0x1D45, 'M', u'ɑ'), + (0x1D46, 'M', u'ᴂ'), + (0x1D47, 'M', u'b'), + (0x1D48, 'M', u'd'), + (0x1D49, 'M', u'e'), + (0x1D4A, 'M', u'ə'), + (0x1D4B, 'M', u'ɛ'), + (0x1D4C, 'M', u'ɜ'), + (0x1D4D, 'M', u'g'), + (0x1D4E, 'V'), + (0x1D4F, 'M', u'k'), + (0x1D50, 'M', u'm'), + (0x1D51, 'M', u'ŋ'), + (0x1D52, 'M', u'o'), + (0x1D53, 'M', u'ɔ'), + (0x1D54, 'M', u'ᴖ'), + (0x1D55, 'M', u'ᴗ'), + (0x1D56, 'M', u'p'), + (0x1D57, 'M', u't'), + (0x1D58, 'M', u'u'), + (0x1D59, 'M', u'ᴝ'), + (0x1D5A, 'M', u'ɯ'), + (0x1D5B, 'M', u'v'), + (0x1D5C, 'M', u'ᴥ'), + (0x1D5D, 'M', u'β'), + (0x1D5E, 'M', u'γ'), + (0x1D5F, 'M', u'δ'), + (0x1D60, 'M', u'φ'), + (0x1D61, 'M', u'χ'), + (0x1D62, 'M', u'i'), + (0x1D63, 'M', u'r'), + (0x1D64, 'M', u'u'), + (0x1D65, 'M', u'v'), + (0x1D66, 'M', u'β'), + (0x1D67, 'M', u'γ'), + (0x1D68, 'M', u'ρ'), + (0x1D69, 'M', u'φ'), + (0x1D6A, 'M', u'χ'), + ] + +def _seg_16(): + return [ + (0x1D6B, 'V'), + (0x1D78, 'M', u'н'), + (0x1D79, 'V'), + (0x1D9B, 'M', u'ɒ'), + (0x1D9C, 'M', u'c'), + (0x1D9D, 'M', u'ɕ'), + (0x1D9E, 'M', u'ð'), + (0x1D9F, 'M', u'ɜ'), + (0x1DA0, 'M', u'f'), + (0x1DA1, 'M', u'ɟ'), + (0x1DA2, 'M', u'ɡ'), + (0x1DA3, 'M', u'ɥ'), + (0x1DA4, 'M', u'ɨ'), + (0x1DA5, 'M', u'ɩ'), + (0x1DA6, 'M', u'ɪ'), + (0x1DA7, 'M', u'ᵻ'), + (0x1DA8, 'M', u'ʝ'), + (0x1DA9, 'M', u'ɭ'), + (0x1DAA, 'M', u'ᶅ'), + (0x1DAB, 'M', u'ʟ'), + (0x1DAC, 'M', u'ɱ'), + (0x1DAD, 'M', u'ɰ'), + (0x1DAE, 'M', u'ɲ'), + (0x1DAF, 'M', u'ɳ'), + (0x1DB0, 'M', u'ɴ'), + (0x1DB1, 'M', u'ɵ'), + (0x1DB2, 'M', u'ɸ'), + (0x1DB3, 'M', u'ʂ'), + (0x1DB4, 'M', u'ʃ'), + (0x1DB5, 'M', u'ƫ'), + (0x1DB6, 'M', u'ʉ'), + (0x1DB7, 'M', u'ʊ'), + (0x1DB8, 'M', u'ᴜ'), + (0x1DB9, 'M', u'ʋ'), + (0x1DBA, 'M', u'ʌ'), + (0x1DBB, 'M', u'z'), + (0x1DBC, 'M', u'ʐ'), + (0x1DBD, 'M', u'ʑ'), + (0x1DBE, 'M', u'ʒ'), + (0x1DBF, 'M', u'θ'), + (0x1DC0, 'V'), + (0x1DFA, 'X'), + (0x1DFB, 'V'), + (0x1E00, 'M', u'ḁ'), + (0x1E01, 'V'), + (0x1E02, 'M', u'ḃ'), + (0x1E03, 'V'), + (0x1E04, 'M', u'ḅ'), + (0x1E05, 'V'), + (0x1E06, 'M', u'ḇ'), + (0x1E07, 'V'), + (0x1E08, 'M', u'ḉ'), + (0x1E09, 'V'), + (0x1E0A, 'M', u'ḋ'), + (0x1E0B, 'V'), + (0x1E0C, 'M', u'ḍ'), + (0x1E0D, 'V'), + (0x1E0E, 'M', u'ḏ'), + (0x1E0F, 'V'), + (0x1E10, 'M', u'ḑ'), + (0x1E11, 'V'), + (0x1E12, 'M', u'ḓ'), + (0x1E13, 'V'), + (0x1E14, 'M', u'ḕ'), + (0x1E15, 'V'), + (0x1E16, 'M', u'ḗ'), + (0x1E17, 'V'), + (0x1E18, 'M', u'ḙ'), + (0x1E19, 'V'), + (0x1E1A, 'M', u'ḛ'), + (0x1E1B, 'V'), + (0x1E1C, 'M', u'ḝ'), + (0x1E1D, 'V'), + (0x1E1E, 'M', u'ḟ'), + (0x1E1F, 'V'), + (0x1E20, 'M', u'ḡ'), + (0x1E21, 'V'), + (0x1E22, 'M', u'ḣ'), + (0x1E23, 'V'), + (0x1E24, 'M', u'ḥ'), + (0x1E25, 'V'), + (0x1E26, 'M', u'ḧ'), + (0x1E27, 'V'), + (0x1E28, 'M', u'ḩ'), + (0x1E29, 'V'), + (0x1E2A, 'M', u'ḫ'), + (0x1E2B, 'V'), + (0x1E2C, 'M', u'ḭ'), + (0x1E2D, 'V'), + (0x1E2E, 'M', u'ḯ'), + (0x1E2F, 'V'), + (0x1E30, 'M', u'ḱ'), + (0x1E31, 'V'), + (0x1E32, 'M', u'ḳ'), + (0x1E33, 'V'), + (0x1E34, 'M', u'ḵ'), + (0x1E35, 'V'), + (0x1E36, 'M', u'ḷ'), + (0x1E37, 'V'), + (0x1E38, 'M', u'ḹ'), + ] + +def _seg_17(): + return [ + (0x1E39, 'V'), + (0x1E3A, 'M', u'ḻ'), + (0x1E3B, 'V'), + (0x1E3C, 'M', u'ḽ'), + (0x1E3D, 'V'), + (0x1E3E, 'M', u'ḿ'), + (0x1E3F, 'V'), + (0x1E40, 'M', u'ṁ'), + (0x1E41, 'V'), + (0x1E42, 'M', u'ṃ'), + (0x1E43, 'V'), + (0x1E44, 'M', u'ṅ'), + (0x1E45, 'V'), + (0x1E46, 'M', u'ṇ'), + (0x1E47, 'V'), + (0x1E48, 'M', u'ṉ'), + (0x1E49, 'V'), + (0x1E4A, 'M', u'ṋ'), + (0x1E4B, 'V'), + (0x1E4C, 'M', u'ṍ'), + (0x1E4D, 'V'), + (0x1E4E, 'M', u'ṏ'), + (0x1E4F, 'V'), + (0x1E50, 'M', u'ṑ'), + (0x1E51, 'V'), + (0x1E52, 'M', u'ṓ'), + (0x1E53, 'V'), + (0x1E54, 'M', u'ṕ'), + (0x1E55, 'V'), + (0x1E56, 'M', u'ṗ'), + (0x1E57, 'V'), + (0x1E58, 'M', u'ṙ'), + (0x1E59, 'V'), + (0x1E5A, 'M', u'ṛ'), + (0x1E5B, 'V'), + (0x1E5C, 'M', u'ṝ'), + (0x1E5D, 'V'), + (0x1E5E, 'M', u'ṟ'), + (0x1E5F, 'V'), + (0x1E60, 'M', u'ṡ'), + (0x1E61, 'V'), + (0x1E62, 'M', u'ṣ'), + (0x1E63, 'V'), + (0x1E64, 'M', u'ṥ'), + (0x1E65, 'V'), + (0x1E66, 'M', u'ṧ'), + (0x1E67, 'V'), + (0x1E68, 'M', u'ṩ'), + (0x1E69, 'V'), + (0x1E6A, 'M', u'ṫ'), + (0x1E6B, 'V'), + (0x1E6C, 'M', u'ṭ'), + (0x1E6D, 'V'), + (0x1E6E, 'M', u'ṯ'), + (0x1E6F, 'V'), + (0x1E70, 'M', u'ṱ'), + (0x1E71, 'V'), + (0x1E72, 'M', u'ṳ'), + (0x1E73, 'V'), + (0x1E74, 'M', u'ṵ'), + (0x1E75, 'V'), + (0x1E76, 'M', u'ṷ'), + (0x1E77, 'V'), + (0x1E78, 'M', u'ṹ'), + (0x1E79, 'V'), + (0x1E7A, 'M', u'ṻ'), + (0x1E7B, 'V'), + (0x1E7C, 'M', u'ṽ'), + (0x1E7D, 'V'), + (0x1E7E, 'M', u'ṿ'), + (0x1E7F, 'V'), + (0x1E80, 'M', u'ẁ'), + (0x1E81, 'V'), + (0x1E82, 'M', u'ẃ'), + (0x1E83, 'V'), + (0x1E84, 'M', u'ẅ'), + (0x1E85, 'V'), + (0x1E86, 'M', u'ẇ'), + (0x1E87, 'V'), + (0x1E88, 'M', u'ẉ'), + (0x1E89, 'V'), + (0x1E8A, 'M', u'ẋ'), + (0x1E8B, 'V'), + (0x1E8C, 'M', u'ẍ'), + (0x1E8D, 'V'), + (0x1E8E, 'M', u'ẏ'), + (0x1E8F, 'V'), + (0x1E90, 'M', u'ẑ'), + (0x1E91, 'V'), + (0x1E92, 'M', u'ẓ'), + (0x1E93, 'V'), + (0x1E94, 'M', u'ẕ'), + (0x1E95, 'V'), + (0x1E9A, 'M', u'aʾ'), + (0x1E9B, 'M', u'ṡ'), + (0x1E9C, 'V'), + (0x1E9E, 'M', u'ss'), + (0x1E9F, 'V'), + (0x1EA0, 'M', u'ạ'), + (0x1EA1, 'V'), + ] + +def _seg_18(): + return [ + (0x1EA2, 'M', u'ả'), + (0x1EA3, 'V'), + (0x1EA4, 'M', u'ấ'), + (0x1EA5, 'V'), + (0x1EA6, 'M', u'ầ'), + (0x1EA7, 'V'), + (0x1EA8, 'M', u'ẩ'), + (0x1EA9, 'V'), + (0x1EAA, 'M', u'ẫ'), + (0x1EAB, 'V'), + (0x1EAC, 'M', u'ậ'), + (0x1EAD, 'V'), + (0x1EAE, 'M', u'ắ'), + (0x1EAF, 'V'), + (0x1EB0, 'M', u'ằ'), + (0x1EB1, 'V'), + (0x1EB2, 'M', u'ẳ'), + (0x1EB3, 'V'), + (0x1EB4, 'M', u'ẵ'), + (0x1EB5, 'V'), + (0x1EB6, 'M', u'ặ'), + (0x1EB7, 'V'), + (0x1EB8, 'M', u'ẹ'), + (0x1EB9, 'V'), + (0x1EBA, 'M', u'ẻ'), + (0x1EBB, 'V'), + (0x1EBC, 'M', u'ẽ'), + (0x1EBD, 'V'), + (0x1EBE, 'M', u'ế'), + (0x1EBF, 'V'), + (0x1EC0, 'M', u'ề'), + (0x1EC1, 'V'), + (0x1EC2, 'M', u'ể'), + (0x1EC3, 'V'), + (0x1EC4, 'M', u'ễ'), + (0x1EC5, 'V'), + (0x1EC6, 'M', u'ệ'), + (0x1EC7, 'V'), + (0x1EC8, 'M', u'ỉ'), + (0x1EC9, 'V'), + (0x1ECA, 'M', u'ị'), + (0x1ECB, 'V'), + (0x1ECC, 'M', u'ọ'), + (0x1ECD, 'V'), + (0x1ECE, 'M', u'ỏ'), + (0x1ECF, 'V'), + (0x1ED0, 'M', u'ố'), + (0x1ED1, 'V'), + (0x1ED2, 'M', u'ồ'), + (0x1ED3, 'V'), + (0x1ED4, 'M', u'ổ'), + (0x1ED5, 'V'), + (0x1ED6, 'M', u'ỗ'), + (0x1ED7, 'V'), + (0x1ED8, 'M', u'ộ'), + (0x1ED9, 'V'), + (0x1EDA, 'M', u'ớ'), + (0x1EDB, 'V'), + (0x1EDC, 'M', u'ờ'), + (0x1EDD, 'V'), + (0x1EDE, 'M', u'ở'), + (0x1EDF, 'V'), + (0x1EE0, 'M', u'ỡ'), + (0x1EE1, 'V'), + (0x1EE2, 'M', u'ợ'), + (0x1EE3, 'V'), + (0x1EE4, 'M', u'ụ'), + (0x1EE5, 'V'), + (0x1EE6, 'M', u'ủ'), + (0x1EE7, 'V'), + (0x1EE8, 'M', u'ứ'), + (0x1EE9, 'V'), + (0x1EEA, 'M', u'ừ'), + (0x1EEB, 'V'), + (0x1EEC, 'M', u'ử'), + (0x1EED, 'V'), + (0x1EEE, 'M', u'ữ'), + (0x1EEF, 'V'), + (0x1EF0, 'M', u'ự'), + (0x1EF1, 'V'), + (0x1EF2, 'M', u'ỳ'), + (0x1EF3, 'V'), + (0x1EF4, 'M', u'ỵ'), + (0x1EF5, 'V'), + (0x1EF6, 'M', u'ỷ'), + (0x1EF7, 'V'), + (0x1EF8, 'M', u'ỹ'), + (0x1EF9, 'V'), + (0x1EFA, 'M', u'ỻ'), + (0x1EFB, 'V'), + (0x1EFC, 'M', u'ỽ'), + (0x1EFD, 'V'), + (0x1EFE, 'M', u'ỿ'), + (0x1EFF, 'V'), + (0x1F08, 'M', u'ἀ'), + (0x1F09, 'M', u'ἁ'), + (0x1F0A, 'M', u'ἂ'), + (0x1F0B, 'M', u'ἃ'), + (0x1F0C, 'M', u'ἄ'), + (0x1F0D, 'M', u'ἅ'), + ] + +def _seg_19(): + return [ + (0x1F0E, 'M', u'ἆ'), + (0x1F0F, 'M', u'ἇ'), + (0x1F10, 'V'), + (0x1F16, 'X'), + (0x1F18, 'M', u'ἐ'), + (0x1F19, 'M', u'ἑ'), + (0x1F1A, 'M', u'ἒ'), + (0x1F1B, 'M', u'ἓ'), + (0x1F1C, 'M', u'ἔ'), + (0x1F1D, 'M', u'ἕ'), + (0x1F1E, 'X'), + (0x1F20, 'V'), + (0x1F28, 'M', u'ἠ'), + (0x1F29, 'M', u'ἡ'), + (0x1F2A, 'M', u'ἢ'), + (0x1F2B, 'M', u'ἣ'), + (0x1F2C, 'M', u'ἤ'), + (0x1F2D, 'M', u'ἥ'), + (0x1F2E, 'M', u'ἦ'), + (0x1F2F, 'M', u'ἧ'), + (0x1F30, 'V'), + (0x1F38, 'M', u'ἰ'), + (0x1F39, 'M', u'ἱ'), + (0x1F3A, 'M', u'ἲ'), + (0x1F3B, 'M', u'ἳ'), + (0x1F3C, 'M', u'ἴ'), + (0x1F3D, 'M', u'ἵ'), + (0x1F3E, 'M', u'ἶ'), + (0x1F3F, 'M', u'ἷ'), + (0x1F40, 'V'), + (0x1F46, 'X'), + (0x1F48, 'M', u'ὀ'), + (0x1F49, 'M', u'ὁ'), + (0x1F4A, 'M', u'ὂ'), + (0x1F4B, 'M', u'ὃ'), + (0x1F4C, 'M', u'ὄ'), + (0x1F4D, 'M', u'ὅ'), + (0x1F4E, 'X'), + (0x1F50, 'V'), + (0x1F58, 'X'), + (0x1F59, 'M', u'ὑ'), + (0x1F5A, 'X'), + (0x1F5B, 'M', u'ὓ'), + (0x1F5C, 'X'), + (0x1F5D, 'M', u'ὕ'), + (0x1F5E, 'X'), + (0x1F5F, 'M', u'ὗ'), + (0x1F60, 'V'), + (0x1F68, 'M', u'ὠ'), + (0x1F69, 'M', u'ὡ'), + (0x1F6A, 'M', u'ὢ'), + (0x1F6B, 'M', u'ὣ'), + (0x1F6C, 'M', u'ὤ'), + (0x1F6D, 'M', u'ὥ'), + (0x1F6E, 'M', u'ὦ'), + (0x1F6F, 'M', u'ὧ'), + (0x1F70, 'V'), + (0x1F71, 'M', u'ά'), + (0x1F72, 'V'), + (0x1F73, 'M', u'έ'), + (0x1F74, 'V'), + (0x1F75, 'M', u'ή'), + (0x1F76, 'V'), + (0x1F77, 'M', u'ί'), + (0x1F78, 'V'), + (0x1F79, 'M', u'ό'), + (0x1F7A, 'V'), + (0x1F7B, 'M', u'ύ'), + (0x1F7C, 'V'), + (0x1F7D, 'M', u'ώ'), + (0x1F7E, 'X'), + (0x1F80, 'M', u'ἀι'), + (0x1F81, 'M', u'ἁι'), + (0x1F82, 'M', u'ἂι'), + (0x1F83, 'M', u'ἃι'), + (0x1F84, 'M', u'ἄι'), + (0x1F85, 'M', u'ἅι'), + (0x1F86, 'M', u'ἆι'), + (0x1F87, 'M', u'ἇι'), + (0x1F88, 'M', u'ἀι'), + (0x1F89, 'M', u'ἁι'), + (0x1F8A, 'M', u'ἂι'), + (0x1F8B, 'M', u'ἃι'), + (0x1F8C, 'M', u'ἄι'), + (0x1F8D, 'M', u'ἅι'), + (0x1F8E, 'M', u'ἆι'), + (0x1F8F, 'M', u'ἇι'), + (0x1F90, 'M', u'ἠι'), + (0x1F91, 'M', u'ἡι'), + (0x1F92, 'M', u'ἢι'), + (0x1F93, 'M', u'ἣι'), + (0x1F94, 'M', u'ἤι'), + (0x1F95, 'M', u'ἥι'), + (0x1F96, 'M', u'ἦι'), + (0x1F97, 'M', u'ἧι'), + (0x1F98, 'M', u'ἠι'), + (0x1F99, 'M', u'ἡι'), + (0x1F9A, 'M', u'ἢι'), + (0x1F9B, 'M', u'ἣι'), + (0x1F9C, 'M', u'ἤι'), + ] + +def _seg_20(): + return [ + (0x1F9D, 'M', u'ἥι'), + (0x1F9E, 'M', u'ἦι'), + (0x1F9F, 'M', u'ἧι'), + (0x1FA0, 'M', u'ὠι'), + (0x1FA1, 'M', u'ὡι'), + (0x1FA2, 'M', u'ὢι'), + (0x1FA3, 'M', u'ὣι'), + (0x1FA4, 'M', u'ὤι'), + (0x1FA5, 'M', u'ὥι'), + (0x1FA6, 'M', u'ὦι'), + (0x1FA7, 'M', u'ὧι'), + (0x1FA8, 'M', u'ὠι'), + (0x1FA9, 'M', u'ὡι'), + (0x1FAA, 'M', u'ὢι'), + (0x1FAB, 'M', u'ὣι'), + (0x1FAC, 'M', u'ὤι'), + (0x1FAD, 'M', u'ὥι'), + (0x1FAE, 'M', u'ὦι'), + (0x1FAF, 'M', u'ὧι'), + (0x1FB0, 'V'), + (0x1FB2, 'M', u'ὰι'), + (0x1FB3, 'M', u'αι'), + (0x1FB4, 'M', u'άι'), + (0x1FB5, 'X'), + (0x1FB6, 'V'), + (0x1FB7, 'M', u'ᾶι'), + (0x1FB8, 'M', u'ᾰ'), + (0x1FB9, 'M', u'ᾱ'), + (0x1FBA, 'M', u'ὰ'), + (0x1FBB, 'M', u'ά'), + (0x1FBC, 'M', u'αι'), + (0x1FBD, '3', u' ̓'), + (0x1FBE, 'M', u'ι'), + (0x1FBF, '3', u' ̓'), + (0x1FC0, '3', u' ͂'), + (0x1FC1, '3', u' ̈͂'), + (0x1FC2, 'M', u'ὴι'), + (0x1FC3, 'M', u'ηι'), + (0x1FC4, 'M', u'ήι'), + (0x1FC5, 'X'), + (0x1FC6, 'V'), + (0x1FC7, 'M', u'ῆι'), + (0x1FC8, 'M', u'ὲ'), + (0x1FC9, 'M', u'έ'), + (0x1FCA, 'M', u'ὴ'), + (0x1FCB, 'M', u'ή'), + (0x1FCC, 'M', u'ηι'), + (0x1FCD, '3', u' ̓̀'), + (0x1FCE, '3', u' ̓́'), + (0x1FCF, '3', u' ̓͂'), + (0x1FD0, 'V'), + (0x1FD3, 'M', u'ΐ'), + (0x1FD4, 'X'), + (0x1FD6, 'V'), + (0x1FD8, 'M', u'ῐ'), + (0x1FD9, 'M', u'ῑ'), + (0x1FDA, 'M', u'ὶ'), + (0x1FDB, 'M', u'ί'), + (0x1FDC, 'X'), + (0x1FDD, '3', u' ̔̀'), + (0x1FDE, '3', u' ̔́'), + (0x1FDF, '3', u' ̔͂'), + (0x1FE0, 'V'), + (0x1FE3, 'M', u'ΰ'), + (0x1FE4, 'V'), + (0x1FE8, 'M', u'ῠ'), + (0x1FE9, 'M', u'ῡ'), + (0x1FEA, 'M', u'ὺ'), + (0x1FEB, 'M', u'ύ'), + (0x1FEC, 'M', u'ῥ'), + (0x1FED, '3', u' ̈̀'), + (0x1FEE, '3', u' ̈́'), + (0x1FEF, '3', u'`'), + (0x1FF0, 'X'), + (0x1FF2, 'M', u'ὼι'), + (0x1FF3, 'M', u'ωι'), + (0x1FF4, 'M', u'ώι'), + (0x1FF5, 'X'), + (0x1FF6, 'V'), + (0x1FF7, 'M', u'ῶι'), + (0x1FF8, 'M', u'ὸ'), + (0x1FF9, 'M', u'ό'), + (0x1FFA, 'M', u'ὼ'), + (0x1FFB, 'M', u'ώ'), + (0x1FFC, 'M', u'ωι'), + (0x1FFD, '3', u' ́'), + (0x1FFE, '3', u' ̔'), + (0x1FFF, 'X'), + (0x2000, '3', u' '), + (0x200B, 'I'), + (0x200C, 'D', u''), + (0x200E, 'X'), + (0x2010, 'V'), + (0x2011, 'M', u'‐'), + (0x2012, 'V'), + (0x2017, '3', u' ̳'), + (0x2018, 'V'), + (0x2024, 'X'), + (0x2027, 'V'), + (0x2028, 'X'), + ] + +def _seg_21(): + return [ + (0x202F, '3', u' '), + (0x2030, 'V'), + (0x2033, 'M', u'′′'), + (0x2034, 'M', u'′′′'), + (0x2035, 'V'), + (0x2036, 'M', u'‵‵'), + (0x2037, 'M', u'‵‵‵'), + (0x2038, 'V'), + (0x203C, '3', u'!!'), + (0x203D, 'V'), + (0x203E, '3', u' ̅'), + (0x203F, 'V'), + (0x2047, '3', u'??'), + (0x2048, '3', u'?!'), + (0x2049, '3', u'!?'), + (0x204A, 'V'), + (0x2057, 'M', u'′′′′'), + (0x2058, 'V'), + (0x205F, '3', u' '), + (0x2060, 'I'), + (0x2061, 'X'), + (0x2064, 'I'), + (0x2065, 'X'), + (0x2070, 'M', u'0'), + (0x2071, 'M', u'i'), + (0x2072, 'X'), + (0x2074, 'M', u'4'), + (0x2075, 'M', u'5'), + (0x2076, 'M', u'6'), + (0x2077, 'M', u'7'), + (0x2078, 'M', u'8'), + (0x2079, 'M', u'9'), + (0x207A, '3', u'+'), + (0x207B, 'M', u'−'), + (0x207C, '3', u'='), + (0x207D, '3', u'('), + (0x207E, '3', u')'), + (0x207F, 'M', u'n'), + (0x2080, 'M', u'0'), + (0x2081, 'M', u'1'), + (0x2082, 'M', u'2'), + (0x2083, 'M', u'3'), + (0x2084, 'M', u'4'), + (0x2085, 'M', u'5'), + (0x2086, 'M', u'6'), + (0x2087, 'M', u'7'), + (0x2088, 'M', u'8'), + (0x2089, 'M', u'9'), + (0x208A, '3', u'+'), + (0x208B, 'M', u'−'), + (0x208C, '3', u'='), + (0x208D, '3', u'('), + (0x208E, '3', u')'), + (0x208F, 'X'), + (0x2090, 'M', u'a'), + (0x2091, 'M', u'e'), + (0x2092, 'M', u'o'), + (0x2093, 'M', u'x'), + (0x2094, 'M', u'ə'), + (0x2095, 'M', u'h'), + (0x2096, 'M', u'k'), + (0x2097, 'M', u'l'), + (0x2098, 'M', u'm'), + (0x2099, 'M', u'n'), + (0x209A, 'M', u'p'), + (0x209B, 'M', u's'), + (0x209C, 'M', u't'), + (0x209D, 'X'), + (0x20A0, 'V'), + (0x20A8, 'M', u'rs'), + (0x20A9, 'V'), + (0x20C0, 'X'), + (0x20D0, 'V'), + (0x20F1, 'X'), + (0x2100, '3', u'a/c'), + (0x2101, '3', u'a/s'), + (0x2102, 'M', u'c'), + (0x2103, 'M', u'°c'), + (0x2104, 'V'), + (0x2105, '3', u'c/o'), + (0x2106, '3', u'c/u'), + (0x2107, 'M', u'ɛ'), + (0x2108, 'V'), + (0x2109, 'M', u'°f'), + (0x210A, 'M', u'g'), + (0x210B, 'M', u'h'), + (0x210F, 'M', u'ħ'), + (0x2110, 'M', u'i'), + (0x2112, 'M', u'l'), + (0x2114, 'V'), + (0x2115, 'M', u'n'), + (0x2116, 'M', u'no'), + (0x2117, 'V'), + (0x2119, 'M', u'p'), + (0x211A, 'M', u'q'), + (0x211B, 'M', u'r'), + (0x211E, 'V'), + (0x2120, 'M', u'sm'), + (0x2121, 'M', u'tel'), + (0x2122, 'M', u'tm'), + ] + +def _seg_22(): + return [ + (0x2123, 'V'), + (0x2124, 'M', u'z'), + (0x2125, 'V'), + (0x2126, 'M', u'ω'), + (0x2127, 'V'), + (0x2128, 'M', u'z'), + (0x2129, 'V'), + (0x212A, 'M', u'k'), + (0x212B, 'M', u'å'), + (0x212C, 'M', u'b'), + (0x212D, 'M', u'c'), + (0x212E, 'V'), + (0x212F, 'M', u'e'), + (0x2131, 'M', u'f'), + (0x2132, 'X'), + (0x2133, 'M', u'm'), + (0x2134, 'M', u'o'), + (0x2135, 'M', u'א'), + (0x2136, 'M', u'ב'), + (0x2137, 'M', u'ג'), + (0x2138, 'M', u'ד'), + (0x2139, 'M', u'i'), + (0x213A, 'V'), + (0x213B, 'M', u'fax'), + (0x213C, 'M', u'π'), + (0x213D, 'M', u'γ'), + (0x213F, 'M', u'π'), + (0x2140, 'M', u'∑'), + (0x2141, 'V'), + (0x2145, 'M', u'd'), + (0x2147, 'M', u'e'), + (0x2148, 'M', u'i'), + (0x2149, 'M', u'j'), + (0x214A, 'V'), + (0x2150, 'M', u'1⁄7'), + (0x2151, 'M', u'1⁄9'), + (0x2152, 'M', u'1⁄10'), + (0x2153, 'M', u'1⁄3'), + (0x2154, 'M', u'2⁄3'), + (0x2155, 'M', u'1⁄5'), + (0x2156, 'M', u'2⁄5'), + (0x2157, 'M', u'3⁄5'), + (0x2158, 'M', u'4⁄5'), + (0x2159, 'M', u'1⁄6'), + (0x215A, 'M', u'5⁄6'), + (0x215B, 'M', u'1⁄8'), + (0x215C, 'M', u'3⁄8'), + (0x215D, 'M', u'5⁄8'), + (0x215E, 'M', u'7⁄8'), + (0x215F, 'M', u'1⁄'), + (0x2160, 'M', u'i'), + (0x2161, 'M', u'ii'), + (0x2162, 'M', u'iii'), + (0x2163, 'M', u'iv'), + (0x2164, 'M', u'v'), + (0x2165, 'M', u'vi'), + (0x2166, 'M', u'vii'), + (0x2167, 'M', u'viii'), + (0x2168, 'M', u'ix'), + (0x2169, 'M', u'x'), + (0x216A, 'M', u'xi'), + (0x216B, 'M', u'xii'), + (0x216C, 'M', u'l'), + (0x216D, 'M', u'c'), + (0x216E, 'M', u'd'), + (0x216F, 'M', u'm'), + (0x2170, 'M', u'i'), + (0x2171, 'M', u'ii'), + (0x2172, 'M', u'iii'), + (0x2173, 'M', u'iv'), + (0x2174, 'M', u'v'), + (0x2175, 'M', u'vi'), + (0x2176, 'M', u'vii'), + (0x2177, 'M', u'viii'), + (0x2178, 'M', u'ix'), + (0x2179, 'M', u'x'), + (0x217A, 'M', u'xi'), + (0x217B, 'M', u'xii'), + (0x217C, 'M', u'l'), + (0x217D, 'M', u'c'), + (0x217E, 'M', u'd'), + (0x217F, 'M', u'm'), + (0x2180, 'V'), + (0x2183, 'X'), + (0x2184, 'V'), + (0x2189, 'M', u'0⁄3'), + (0x218A, 'V'), + (0x218C, 'X'), + (0x2190, 'V'), + (0x222C, 'M', u'∫∫'), + (0x222D, 'M', u'∫∫∫'), + (0x222E, 'V'), + (0x222F, 'M', u'∮∮'), + (0x2230, 'M', u'∮∮∮'), + (0x2231, 'V'), + (0x2260, '3'), + (0x2261, 'V'), + (0x226E, '3'), + (0x2270, 'V'), + (0x2329, 'M', u'〈'), + ] + +def _seg_23(): + return [ + (0x232A, 'M', u'〉'), + (0x232B, 'V'), + (0x2427, 'X'), + (0x2440, 'V'), + (0x244B, 'X'), + (0x2460, 'M', u'1'), + (0x2461, 'M', u'2'), + (0x2462, 'M', u'3'), + (0x2463, 'M', u'4'), + (0x2464, 'M', u'5'), + (0x2465, 'M', u'6'), + (0x2466, 'M', u'7'), + (0x2467, 'M', u'8'), + (0x2468, 'M', u'9'), + (0x2469, 'M', u'10'), + (0x246A, 'M', u'11'), + (0x246B, 'M', u'12'), + (0x246C, 'M', u'13'), + (0x246D, 'M', u'14'), + (0x246E, 'M', u'15'), + (0x246F, 'M', u'16'), + (0x2470, 'M', u'17'), + (0x2471, 'M', u'18'), + (0x2472, 'M', u'19'), + (0x2473, 'M', u'20'), + (0x2474, '3', u'(1)'), + (0x2475, '3', u'(2)'), + (0x2476, '3', u'(3)'), + (0x2477, '3', u'(4)'), + (0x2478, '3', u'(5)'), + (0x2479, '3', u'(6)'), + (0x247A, '3', u'(7)'), + (0x247B, '3', u'(8)'), + (0x247C, '3', u'(9)'), + (0x247D, '3', u'(10)'), + (0x247E, '3', u'(11)'), + (0x247F, '3', u'(12)'), + (0x2480, '3', u'(13)'), + (0x2481, '3', u'(14)'), + (0x2482, '3', u'(15)'), + (0x2483, '3', u'(16)'), + (0x2484, '3', u'(17)'), + (0x2485, '3', u'(18)'), + (0x2486, '3', u'(19)'), + (0x2487, '3', u'(20)'), + (0x2488, 'X'), + (0x249C, '3', u'(a)'), + (0x249D, '3', u'(b)'), + (0x249E, '3', u'(c)'), + (0x249F, '3', u'(d)'), + (0x24A0, '3', u'(e)'), + (0x24A1, '3', u'(f)'), + (0x24A2, '3', u'(g)'), + (0x24A3, '3', u'(h)'), + (0x24A4, '3', u'(i)'), + (0x24A5, '3', u'(j)'), + (0x24A6, '3', u'(k)'), + (0x24A7, '3', u'(l)'), + (0x24A8, '3', u'(m)'), + (0x24A9, '3', u'(n)'), + (0x24AA, '3', u'(o)'), + (0x24AB, '3', u'(p)'), + (0x24AC, '3', u'(q)'), + (0x24AD, '3', u'(r)'), + (0x24AE, '3', u'(s)'), + (0x24AF, '3', u'(t)'), + (0x24B0, '3', u'(u)'), + (0x24B1, '3', u'(v)'), + (0x24B2, '3', u'(w)'), + (0x24B3, '3', u'(x)'), + (0x24B4, '3', u'(y)'), + (0x24B5, '3', u'(z)'), + (0x24B6, 'M', u'a'), + (0x24B7, 'M', u'b'), + (0x24B8, 'M', u'c'), + (0x24B9, 'M', u'd'), + (0x24BA, 'M', u'e'), + (0x24BB, 'M', u'f'), + (0x24BC, 'M', u'g'), + (0x24BD, 'M', u'h'), + (0x24BE, 'M', u'i'), + (0x24BF, 'M', u'j'), + (0x24C0, 'M', u'k'), + (0x24C1, 'M', u'l'), + (0x24C2, 'M', u'm'), + (0x24C3, 'M', u'n'), + (0x24C4, 'M', u'o'), + (0x24C5, 'M', u'p'), + (0x24C6, 'M', u'q'), + (0x24C7, 'M', u'r'), + (0x24C8, 'M', u's'), + (0x24C9, 'M', u't'), + (0x24CA, 'M', u'u'), + (0x24CB, 'M', u'v'), + (0x24CC, 'M', u'w'), + (0x24CD, 'M', u'x'), + (0x24CE, 'M', u'y'), + (0x24CF, 'M', u'z'), + (0x24D0, 'M', u'a'), + (0x24D1, 'M', u'b'), + ] + +def _seg_24(): + return [ + (0x24D2, 'M', u'c'), + (0x24D3, 'M', u'd'), + (0x24D4, 'M', u'e'), + (0x24D5, 'M', u'f'), + (0x24D6, 'M', u'g'), + (0x24D7, 'M', u'h'), + (0x24D8, 'M', u'i'), + (0x24D9, 'M', u'j'), + (0x24DA, 'M', u'k'), + (0x24DB, 'M', u'l'), + (0x24DC, 'M', u'm'), + (0x24DD, 'M', u'n'), + (0x24DE, 'M', u'o'), + (0x24DF, 'M', u'p'), + (0x24E0, 'M', u'q'), + (0x24E1, 'M', u'r'), + (0x24E2, 'M', u's'), + (0x24E3, 'M', u't'), + (0x24E4, 'M', u'u'), + (0x24E5, 'M', u'v'), + (0x24E6, 'M', u'w'), + (0x24E7, 'M', u'x'), + (0x24E8, 'M', u'y'), + (0x24E9, 'M', u'z'), + (0x24EA, 'M', u'0'), + (0x24EB, 'V'), + (0x2A0C, 'M', u'∫∫∫∫'), + (0x2A0D, 'V'), + (0x2A74, '3', u'::='), + (0x2A75, '3', u'=='), + (0x2A76, '3', u'==='), + (0x2A77, 'V'), + (0x2ADC, 'M', u'⫝̸'), + (0x2ADD, 'V'), + (0x2B74, 'X'), + (0x2B76, 'V'), + (0x2B96, 'X'), + (0x2B98, 'V'), + (0x2BBA, 'X'), + (0x2BBD, 'V'), + (0x2BC9, 'X'), + (0x2BCA, 'V'), + (0x2BD3, 'X'), + (0x2BEC, 'V'), + (0x2BF0, 'X'), + (0x2C00, 'M', u'ⰰ'), + (0x2C01, 'M', u'ⰱ'), + (0x2C02, 'M', u'ⰲ'), + (0x2C03, 'M', u'ⰳ'), + (0x2C04, 'M', u'ⰴ'), + (0x2C05, 'M', u'ⰵ'), + (0x2C06, 'M', u'ⰶ'), + (0x2C07, 'M', u'ⰷ'), + (0x2C08, 'M', u'ⰸ'), + (0x2C09, 'M', u'ⰹ'), + (0x2C0A, 'M', u'ⰺ'), + (0x2C0B, 'M', u'ⰻ'), + (0x2C0C, 'M', u'ⰼ'), + (0x2C0D, 'M', u'ⰽ'), + (0x2C0E, 'M', u'ⰾ'), + (0x2C0F, 'M', u'ⰿ'), + (0x2C10, 'M', u'ⱀ'), + (0x2C11, 'M', u'ⱁ'), + (0x2C12, 'M', u'ⱂ'), + (0x2C13, 'M', u'ⱃ'), + (0x2C14, 'M', u'ⱄ'), + (0x2C15, 'M', u'ⱅ'), + (0x2C16, 'M', u'ⱆ'), + (0x2C17, 'M', u'ⱇ'), + (0x2C18, 'M', u'ⱈ'), + (0x2C19, 'M', u'ⱉ'), + (0x2C1A, 'M', u'ⱊ'), + (0x2C1B, 'M', u'ⱋ'), + (0x2C1C, 'M', u'ⱌ'), + (0x2C1D, 'M', u'ⱍ'), + (0x2C1E, 'M', u'ⱎ'), + (0x2C1F, 'M', u'ⱏ'), + (0x2C20, 'M', u'ⱐ'), + (0x2C21, 'M', u'ⱑ'), + (0x2C22, 'M', u'ⱒ'), + (0x2C23, 'M', u'ⱓ'), + (0x2C24, 'M', u'ⱔ'), + (0x2C25, 'M', u'ⱕ'), + (0x2C26, 'M', u'ⱖ'), + (0x2C27, 'M', u'ⱗ'), + (0x2C28, 'M', u'ⱘ'), + (0x2C29, 'M', u'ⱙ'), + (0x2C2A, 'M', u'ⱚ'), + (0x2C2B, 'M', u'ⱛ'), + (0x2C2C, 'M', u'ⱜ'), + (0x2C2D, 'M', u'ⱝ'), + (0x2C2E, 'M', u'ⱞ'), + (0x2C2F, 'X'), + (0x2C30, 'V'), + (0x2C5F, 'X'), + (0x2C60, 'M', u'ⱡ'), + (0x2C61, 'V'), + (0x2C62, 'M', u'ɫ'), + (0x2C63, 'M', u'ᵽ'), + (0x2C64, 'M', u'ɽ'), + ] + +def _seg_25(): + return [ + (0x2C65, 'V'), + (0x2C67, 'M', u'ⱨ'), + (0x2C68, 'V'), + (0x2C69, 'M', u'ⱪ'), + (0x2C6A, 'V'), + (0x2C6B, 'M', u'ⱬ'), + (0x2C6C, 'V'), + (0x2C6D, 'M', u'ɑ'), + (0x2C6E, 'M', u'ɱ'), + (0x2C6F, 'M', u'ɐ'), + (0x2C70, 'M', u'ɒ'), + (0x2C71, 'V'), + (0x2C72, 'M', u'ⱳ'), + (0x2C73, 'V'), + (0x2C75, 'M', u'ⱶ'), + (0x2C76, 'V'), + (0x2C7C, 'M', u'j'), + (0x2C7D, 'M', u'v'), + (0x2C7E, 'M', u'ȿ'), + (0x2C7F, 'M', u'ɀ'), + (0x2C80, 'M', u'ⲁ'), + (0x2C81, 'V'), + (0x2C82, 'M', u'ⲃ'), + (0x2C83, 'V'), + (0x2C84, 'M', u'ⲅ'), + (0x2C85, 'V'), + (0x2C86, 'M', u'ⲇ'), + (0x2C87, 'V'), + (0x2C88, 'M', u'ⲉ'), + (0x2C89, 'V'), + (0x2C8A, 'M', u'ⲋ'), + (0x2C8B, 'V'), + (0x2C8C, 'M', u'ⲍ'), + (0x2C8D, 'V'), + (0x2C8E, 'M', u'ⲏ'), + (0x2C8F, 'V'), + (0x2C90, 'M', u'ⲑ'), + (0x2C91, 'V'), + (0x2C92, 'M', u'ⲓ'), + (0x2C93, 'V'), + (0x2C94, 'M', u'ⲕ'), + (0x2C95, 'V'), + (0x2C96, 'M', u'ⲗ'), + (0x2C97, 'V'), + (0x2C98, 'M', u'ⲙ'), + (0x2C99, 'V'), + (0x2C9A, 'M', u'ⲛ'), + (0x2C9B, 'V'), + (0x2C9C, 'M', u'ⲝ'), + (0x2C9D, 'V'), + (0x2C9E, 'M', u'ⲟ'), + (0x2C9F, 'V'), + (0x2CA0, 'M', u'ⲡ'), + (0x2CA1, 'V'), + (0x2CA2, 'M', u'ⲣ'), + (0x2CA3, 'V'), + (0x2CA4, 'M', u'ⲥ'), + (0x2CA5, 'V'), + (0x2CA6, 'M', u'ⲧ'), + (0x2CA7, 'V'), + (0x2CA8, 'M', u'ⲩ'), + (0x2CA9, 'V'), + (0x2CAA, 'M', u'ⲫ'), + (0x2CAB, 'V'), + (0x2CAC, 'M', u'ⲭ'), + (0x2CAD, 'V'), + (0x2CAE, 'M', u'ⲯ'), + (0x2CAF, 'V'), + (0x2CB0, 'M', u'ⲱ'), + (0x2CB1, 'V'), + (0x2CB2, 'M', u'ⲳ'), + (0x2CB3, 'V'), + (0x2CB4, 'M', u'ⲵ'), + (0x2CB5, 'V'), + (0x2CB6, 'M', u'ⲷ'), + (0x2CB7, 'V'), + (0x2CB8, 'M', u'ⲹ'), + (0x2CB9, 'V'), + (0x2CBA, 'M', u'ⲻ'), + (0x2CBB, 'V'), + (0x2CBC, 'M', u'ⲽ'), + (0x2CBD, 'V'), + (0x2CBE, 'M', u'ⲿ'), + (0x2CBF, 'V'), + (0x2CC0, 'M', u'ⳁ'), + (0x2CC1, 'V'), + (0x2CC2, 'M', u'ⳃ'), + (0x2CC3, 'V'), + (0x2CC4, 'M', u'ⳅ'), + (0x2CC5, 'V'), + (0x2CC6, 'M', u'ⳇ'), + (0x2CC7, 'V'), + (0x2CC8, 'M', u'ⳉ'), + (0x2CC9, 'V'), + (0x2CCA, 'M', u'ⳋ'), + (0x2CCB, 'V'), + (0x2CCC, 'M', u'ⳍ'), + (0x2CCD, 'V'), + (0x2CCE, 'M', u'ⳏ'), + (0x2CCF, 'V'), + ] + +def _seg_26(): + return [ + (0x2CD0, 'M', u'ⳑ'), + (0x2CD1, 'V'), + (0x2CD2, 'M', u'ⳓ'), + (0x2CD3, 'V'), + (0x2CD4, 'M', u'ⳕ'), + (0x2CD5, 'V'), + (0x2CD6, 'M', u'ⳗ'), + (0x2CD7, 'V'), + (0x2CD8, 'M', u'ⳙ'), + (0x2CD9, 'V'), + (0x2CDA, 'M', u'ⳛ'), + (0x2CDB, 'V'), + (0x2CDC, 'M', u'ⳝ'), + (0x2CDD, 'V'), + (0x2CDE, 'M', u'ⳟ'), + (0x2CDF, 'V'), + (0x2CE0, 'M', u'ⳡ'), + (0x2CE1, 'V'), + (0x2CE2, 'M', u'ⳣ'), + (0x2CE3, 'V'), + (0x2CEB, 'M', u'ⳬ'), + (0x2CEC, 'V'), + (0x2CED, 'M', u'ⳮ'), + (0x2CEE, 'V'), + (0x2CF2, 'M', u'ⳳ'), + (0x2CF3, 'V'), + (0x2CF4, 'X'), + (0x2CF9, 'V'), + (0x2D26, 'X'), + (0x2D27, 'V'), + (0x2D28, 'X'), + (0x2D2D, 'V'), + (0x2D2E, 'X'), + (0x2D30, 'V'), + (0x2D68, 'X'), + (0x2D6F, 'M', u'ⵡ'), + (0x2D70, 'V'), + (0x2D71, 'X'), + (0x2D7F, 'V'), + (0x2D97, 'X'), + (0x2DA0, 'V'), + (0x2DA7, 'X'), + (0x2DA8, 'V'), + (0x2DAF, 'X'), + (0x2DB0, 'V'), + (0x2DB7, 'X'), + (0x2DB8, 'V'), + (0x2DBF, 'X'), + (0x2DC0, 'V'), + (0x2DC7, 'X'), + (0x2DC8, 'V'), + (0x2DCF, 'X'), + (0x2DD0, 'V'), + (0x2DD7, 'X'), + (0x2DD8, 'V'), + (0x2DDF, 'X'), + (0x2DE0, 'V'), + (0x2E4A, 'X'), + (0x2E80, 'V'), + (0x2E9A, 'X'), + (0x2E9B, 'V'), + (0x2E9F, 'M', u'母'), + (0x2EA0, 'V'), + (0x2EF3, 'M', u'龟'), + (0x2EF4, 'X'), + (0x2F00, 'M', u'一'), + (0x2F01, 'M', u'丨'), + (0x2F02, 'M', u'丶'), + (0x2F03, 'M', u'丿'), + (0x2F04, 'M', u'乙'), + (0x2F05, 'M', u'亅'), + (0x2F06, 'M', u'二'), + (0x2F07, 'M', u'亠'), + (0x2F08, 'M', u'人'), + (0x2F09, 'M', u'儿'), + (0x2F0A, 'M', u'入'), + (0x2F0B, 'M', u'八'), + (0x2F0C, 'M', u'冂'), + (0x2F0D, 'M', u'冖'), + (0x2F0E, 'M', u'冫'), + (0x2F0F, 'M', u'几'), + (0x2F10, 'M', u'凵'), + (0x2F11, 'M', u'刀'), + (0x2F12, 'M', u'力'), + (0x2F13, 'M', u'勹'), + (0x2F14, 'M', u'匕'), + (0x2F15, 'M', u'匚'), + (0x2F16, 'M', u'匸'), + (0x2F17, 'M', u'十'), + (0x2F18, 'M', u'卜'), + (0x2F19, 'M', u'卩'), + (0x2F1A, 'M', u'厂'), + (0x2F1B, 'M', u'厶'), + (0x2F1C, 'M', u'又'), + (0x2F1D, 'M', u'口'), + (0x2F1E, 'M', u'囗'), + (0x2F1F, 'M', u'土'), + (0x2F20, 'M', u'士'), + (0x2F21, 'M', u'夂'), + (0x2F22, 'M', u'夊'), + ] + +def _seg_27(): + return [ + (0x2F23, 'M', u'夕'), + (0x2F24, 'M', u'大'), + (0x2F25, 'M', u'女'), + (0x2F26, 'M', u'子'), + (0x2F27, 'M', u'宀'), + (0x2F28, 'M', u'寸'), + (0x2F29, 'M', u'小'), + (0x2F2A, 'M', u'尢'), + (0x2F2B, 'M', u'尸'), + (0x2F2C, 'M', u'屮'), + (0x2F2D, 'M', u'山'), + (0x2F2E, 'M', u'巛'), + (0x2F2F, 'M', u'工'), + (0x2F30, 'M', u'己'), + (0x2F31, 'M', u'巾'), + (0x2F32, 'M', u'干'), + (0x2F33, 'M', u'幺'), + (0x2F34, 'M', u'广'), + (0x2F35, 'M', u'廴'), + (0x2F36, 'M', u'廾'), + (0x2F37, 'M', u'弋'), + (0x2F38, 'M', u'弓'), + (0x2F39, 'M', u'彐'), + (0x2F3A, 'M', u'彡'), + (0x2F3B, 'M', u'彳'), + (0x2F3C, 'M', u'心'), + (0x2F3D, 'M', u'戈'), + (0x2F3E, 'M', u'戶'), + (0x2F3F, 'M', u'手'), + (0x2F40, 'M', u'支'), + (0x2F41, 'M', u'攴'), + (0x2F42, 'M', u'文'), + (0x2F43, 'M', u'斗'), + (0x2F44, 'M', u'斤'), + (0x2F45, 'M', u'方'), + (0x2F46, 'M', u'无'), + (0x2F47, 'M', u'日'), + (0x2F48, 'M', u'曰'), + (0x2F49, 'M', u'月'), + (0x2F4A, 'M', u'木'), + (0x2F4B, 'M', u'欠'), + (0x2F4C, 'M', u'止'), + (0x2F4D, 'M', u'歹'), + (0x2F4E, 'M', u'殳'), + (0x2F4F, 'M', u'毋'), + (0x2F50, 'M', u'比'), + (0x2F51, 'M', u'毛'), + (0x2F52, 'M', u'氏'), + (0x2F53, 'M', u'气'), + (0x2F54, 'M', u'水'), + (0x2F55, 'M', u'火'), + (0x2F56, 'M', u'爪'), + (0x2F57, 'M', u'父'), + (0x2F58, 'M', u'爻'), + (0x2F59, 'M', u'爿'), + (0x2F5A, 'M', u'片'), + (0x2F5B, 'M', u'牙'), + (0x2F5C, 'M', u'牛'), + (0x2F5D, 'M', u'犬'), + (0x2F5E, 'M', u'玄'), + (0x2F5F, 'M', u'玉'), + (0x2F60, 'M', u'瓜'), + (0x2F61, 'M', u'瓦'), + (0x2F62, 'M', u'甘'), + (0x2F63, 'M', u'生'), + (0x2F64, 'M', u'用'), + (0x2F65, 'M', u'田'), + (0x2F66, 'M', u'疋'), + (0x2F67, 'M', u'疒'), + (0x2F68, 'M', u'癶'), + (0x2F69, 'M', u'白'), + (0x2F6A, 'M', u'皮'), + (0x2F6B, 'M', u'皿'), + (0x2F6C, 'M', u'目'), + (0x2F6D, 'M', u'矛'), + (0x2F6E, 'M', u'矢'), + (0x2F6F, 'M', u'石'), + (0x2F70, 'M', u'示'), + (0x2F71, 'M', u'禸'), + (0x2F72, 'M', u'禾'), + (0x2F73, 'M', u'穴'), + (0x2F74, 'M', u'立'), + (0x2F75, 'M', u'竹'), + (0x2F76, 'M', u'米'), + (0x2F77, 'M', u'糸'), + (0x2F78, 'M', u'缶'), + (0x2F79, 'M', u'网'), + (0x2F7A, 'M', u'羊'), + (0x2F7B, 'M', u'羽'), + (0x2F7C, 'M', u'老'), + (0x2F7D, 'M', u'而'), + (0x2F7E, 'M', u'耒'), + (0x2F7F, 'M', u'耳'), + (0x2F80, 'M', u'聿'), + (0x2F81, 'M', u'肉'), + (0x2F82, 'M', u'臣'), + (0x2F83, 'M', u'自'), + (0x2F84, 'M', u'至'), + (0x2F85, 'M', u'臼'), + (0x2F86, 'M', u'舌'), + ] + +def _seg_28(): + return [ + (0x2F87, 'M', u'舛'), + (0x2F88, 'M', u'舟'), + (0x2F89, 'M', u'艮'), + (0x2F8A, 'M', u'色'), + (0x2F8B, 'M', u'艸'), + (0x2F8C, 'M', u'虍'), + (0x2F8D, 'M', u'虫'), + (0x2F8E, 'M', u'血'), + (0x2F8F, 'M', u'行'), + (0x2F90, 'M', u'衣'), + (0x2F91, 'M', u'襾'), + (0x2F92, 'M', u'見'), + (0x2F93, 'M', u'角'), + (0x2F94, 'M', u'言'), + (0x2F95, 'M', u'谷'), + (0x2F96, 'M', u'豆'), + (0x2F97, 'M', u'豕'), + (0x2F98, 'M', u'豸'), + (0x2F99, 'M', u'貝'), + (0x2F9A, 'M', u'赤'), + (0x2F9B, 'M', u'走'), + (0x2F9C, 'M', u'足'), + (0x2F9D, 'M', u'身'), + (0x2F9E, 'M', u'車'), + (0x2F9F, 'M', u'辛'), + (0x2FA0, 'M', u'辰'), + (0x2FA1, 'M', u'辵'), + (0x2FA2, 'M', u'邑'), + (0x2FA3, 'M', u'酉'), + (0x2FA4, 'M', u'釆'), + (0x2FA5, 'M', u'里'), + (0x2FA6, 'M', u'金'), + (0x2FA7, 'M', u'長'), + (0x2FA8, 'M', u'門'), + (0x2FA9, 'M', u'阜'), + (0x2FAA, 'M', u'隶'), + (0x2FAB, 'M', u'隹'), + (0x2FAC, 'M', u'雨'), + (0x2FAD, 'M', u'靑'), + (0x2FAE, 'M', u'非'), + (0x2FAF, 'M', u'面'), + (0x2FB0, 'M', u'革'), + (0x2FB1, 'M', u'韋'), + (0x2FB2, 'M', u'韭'), + (0x2FB3, 'M', u'音'), + (0x2FB4, 'M', u'頁'), + (0x2FB5, 'M', u'風'), + (0x2FB6, 'M', u'飛'), + (0x2FB7, 'M', u'食'), + (0x2FB8, 'M', u'首'), + (0x2FB9, 'M', u'香'), + (0x2FBA, 'M', u'馬'), + (0x2FBB, 'M', u'骨'), + (0x2FBC, 'M', u'高'), + (0x2FBD, 'M', u'髟'), + (0x2FBE, 'M', u'鬥'), + (0x2FBF, 'M', u'鬯'), + (0x2FC0, 'M', u'鬲'), + (0x2FC1, 'M', u'鬼'), + (0x2FC2, 'M', u'魚'), + (0x2FC3, 'M', u'鳥'), + (0x2FC4, 'M', u'鹵'), + (0x2FC5, 'M', u'鹿'), + (0x2FC6, 'M', u'麥'), + (0x2FC7, 'M', u'麻'), + (0x2FC8, 'M', u'黃'), + (0x2FC9, 'M', u'黍'), + (0x2FCA, 'M', u'黑'), + (0x2FCB, 'M', u'黹'), + (0x2FCC, 'M', u'黽'), + (0x2FCD, 'M', u'鼎'), + (0x2FCE, 'M', u'鼓'), + (0x2FCF, 'M', u'鼠'), + (0x2FD0, 'M', u'鼻'), + (0x2FD1, 'M', u'齊'), + (0x2FD2, 'M', u'齒'), + (0x2FD3, 'M', u'龍'), + (0x2FD4, 'M', u'龜'), + (0x2FD5, 'M', u'龠'), + (0x2FD6, 'X'), + (0x3000, '3', u' '), + (0x3001, 'V'), + (0x3002, 'M', u'.'), + (0x3003, 'V'), + (0x3036, 'M', u'〒'), + (0x3037, 'V'), + (0x3038, 'M', u'十'), + (0x3039, 'M', u'卄'), + (0x303A, 'M', u'卅'), + (0x303B, 'V'), + (0x3040, 'X'), + (0x3041, 'V'), + (0x3097, 'X'), + (0x3099, 'V'), + (0x309B, '3', u' ゙'), + (0x309C, '3', u' ゚'), + (0x309D, 'V'), + (0x309F, 'M', u'より'), + (0x30A0, 'V'), + (0x30FF, 'M', u'コト'), + ] + +def _seg_29(): + return [ + (0x3100, 'X'), + (0x3105, 'V'), + (0x312F, 'X'), + (0x3131, 'M', u'ᄀ'), + (0x3132, 'M', u'ᄁ'), + (0x3133, 'M', u'ᆪ'), + (0x3134, 'M', u'ᄂ'), + (0x3135, 'M', u'ᆬ'), + (0x3136, 'M', u'ᆭ'), + (0x3137, 'M', u'ᄃ'), + (0x3138, 'M', u'ᄄ'), + (0x3139, 'M', u'ᄅ'), + (0x313A, 'M', u'ᆰ'), + (0x313B, 'M', u'ᆱ'), + (0x313C, 'M', u'ᆲ'), + (0x313D, 'M', u'ᆳ'), + (0x313E, 'M', u'ᆴ'), + (0x313F, 'M', u'ᆵ'), + (0x3140, 'M', u'ᄚ'), + (0x3141, 'M', u'ᄆ'), + (0x3142, 'M', u'ᄇ'), + (0x3143, 'M', u'ᄈ'), + (0x3144, 'M', u'ᄡ'), + (0x3145, 'M', u'ᄉ'), + (0x3146, 'M', u'ᄊ'), + (0x3147, 'M', u'ᄋ'), + (0x3148, 'M', u'ᄌ'), + (0x3149, 'M', u'ᄍ'), + (0x314A, 'M', u'ᄎ'), + (0x314B, 'M', u'ᄏ'), + (0x314C, 'M', u'ᄐ'), + (0x314D, 'M', u'ᄑ'), + (0x314E, 'M', u'ᄒ'), + (0x314F, 'M', u'ᅡ'), + (0x3150, 'M', u'ᅢ'), + (0x3151, 'M', u'ᅣ'), + (0x3152, 'M', u'ᅤ'), + (0x3153, 'M', u'ᅥ'), + (0x3154, 'M', u'ᅦ'), + (0x3155, 'M', u'ᅧ'), + (0x3156, 'M', u'ᅨ'), + (0x3157, 'M', u'ᅩ'), + (0x3158, 'M', u'ᅪ'), + (0x3159, 'M', u'ᅫ'), + (0x315A, 'M', u'ᅬ'), + (0x315B, 'M', u'ᅭ'), + (0x315C, 'M', u'ᅮ'), + (0x315D, 'M', u'ᅯ'), + (0x315E, 'M', u'ᅰ'), + (0x315F, 'M', u'ᅱ'), + (0x3160, 'M', u'ᅲ'), + (0x3161, 'M', u'ᅳ'), + (0x3162, 'M', u'ᅴ'), + (0x3163, 'M', u'ᅵ'), + (0x3164, 'X'), + (0x3165, 'M', u'ᄔ'), + (0x3166, 'M', u'ᄕ'), + (0x3167, 'M', u'ᇇ'), + (0x3168, 'M', u'ᇈ'), + (0x3169, 'M', u'ᇌ'), + (0x316A, 'M', u'ᇎ'), + (0x316B, 'M', u'ᇓ'), + (0x316C, 'M', u'ᇗ'), + (0x316D, 'M', u'ᇙ'), + (0x316E, 'M', u'ᄜ'), + (0x316F, 'M', u'ᇝ'), + (0x3170, 'M', u'ᇟ'), + (0x3171, 'M', u'ᄝ'), + (0x3172, 'M', u'ᄞ'), + (0x3173, 'M', u'ᄠ'), + (0x3174, 'M', u'ᄢ'), + (0x3175, 'M', u'ᄣ'), + (0x3176, 'M', u'ᄧ'), + (0x3177, 'M', u'ᄩ'), + (0x3178, 'M', u'ᄫ'), + (0x3179, 'M', u'ᄬ'), + (0x317A, 'M', u'ᄭ'), + (0x317B, 'M', u'ᄮ'), + (0x317C, 'M', u'ᄯ'), + (0x317D, 'M', u'ᄲ'), + (0x317E, 'M', u'ᄶ'), + (0x317F, 'M', u'ᅀ'), + (0x3180, 'M', u'ᅇ'), + (0x3181, 'M', u'ᅌ'), + (0x3182, 'M', u'ᇱ'), + (0x3183, 'M', u'ᇲ'), + (0x3184, 'M', u'ᅗ'), + (0x3185, 'M', u'ᅘ'), + (0x3186, 'M', u'ᅙ'), + (0x3187, 'M', u'ᆄ'), + (0x3188, 'M', u'ᆅ'), + (0x3189, 'M', u'ᆈ'), + (0x318A, 'M', u'ᆑ'), + (0x318B, 'M', u'ᆒ'), + (0x318C, 'M', u'ᆔ'), + (0x318D, 'M', u'ᆞ'), + (0x318E, 'M', u'ᆡ'), + (0x318F, 'X'), + (0x3190, 'V'), + (0x3192, 'M', u'一'), + ] + +def _seg_30(): + return [ + (0x3193, 'M', u'二'), + (0x3194, 'M', u'三'), + (0x3195, 'M', u'四'), + (0x3196, 'M', u'上'), + (0x3197, 'M', u'中'), + (0x3198, 'M', u'下'), + (0x3199, 'M', u'甲'), + (0x319A, 'M', u'乙'), + (0x319B, 'M', u'丙'), + (0x319C, 'M', u'丁'), + (0x319D, 'M', u'天'), + (0x319E, 'M', u'地'), + (0x319F, 'M', u'人'), + (0x31A0, 'V'), + (0x31BB, 'X'), + (0x31C0, 'V'), + (0x31E4, 'X'), + (0x31F0, 'V'), + (0x3200, '3', u'(ᄀ)'), + (0x3201, '3', u'(ᄂ)'), + (0x3202, '3', u'(ᄃ)'), + (0x3203, '3', u'(ᄅ)'), + (0x3204, '3', u'(ᄆ)'), + (0x3205, '3', u'(ᄇ)'), + (0x3206, '3', u'(ᄉ)'), + (0x3207, '3', u'(ᄋ)'), + (0x3208, '3', u'(ᄌ)'), + (0x3209, '3', u'(ᄎ)'), + (0x320A, '3', u'(ᄏ)'), + (0x320B, '3', u'(ᄐ)'), + (0x320C, '3', u'(ᄑ)'), + (0x320D, '3', u'(ᄒ)'), + (0x320E, '3', u'(가)'), + (0x320F, '3', u'(나)'), + (0x3210, '3', u'(다)'), + (0x3211, '3', u'(라)'), + (0x3212, '3', u'(마)'), + (0x3213, '3', u'(바)'), + (0x3214, '3', u'(사)'), + (0x3215, '3', u'(아)'), + (0x3216, '3', u'(자)'), + (0x3217, '3', u'(차)'), + (0x3218, '3', u'(카)'), + (0x3219, '3', u'(타)'), + (0x321A, '3', u'(파)'), + (0x321B, '3', u'(하)'), + (0x321C, '3', u'(주)'), + (0x321D, '3', u'(오전)'), + (0x321E, '3', u'(오후)'), + (0x321F, 'X'), + (0x3220, '3', u'(一)'), + (0x3221, '3', u'(二)'), + (0x3222, '3', u'(三)'), + (0x3223, '3', u'(四)'), + (0x3224, '3', u'(五)'), + (0x3225, '3', u'(六)'), + (0x3226, '3', u'(七)'), + (0x3227, '3', u'(八)'), + (0x3228, '3', u'(九)'), + (0x3229, '3', u'(十)'), + (0x322A, '3', u'(月)'), + (0x322B, '3', u'(火)'), + (0x322C, '3', u'(水)'), + (0x322D, '3', u'(木)'), + (0x322E, '3', u'(金)'), + (0x322F, '3', u'(土)'), + (0x3230, '3', u'(日)'), + (0x3231, '3', u'(株)'), + (0x3232, '3', u'(有)'), + (0x3233, '3', u'(社)'), + (0x3234, '3', u'(名)'), + (0x3235, '3', u'(特)'), + (0x3236, '3', u'(財)'), + (0x3237, '3', u'(祝)'), + (0x3238, '3', u'(労)'), + (0x3239, '3', u'(代)'), + (0x323A, '3', u'(呼)'), + (0x323B, '3', u'(学)'), + (0x323C, '3', u'(監)'), + (0x323D, '3', u'(企)'), + (0x323E, '3', u'(資)'), + (0x323F, '3', u'(協)'), + (0x3240, '3', u'(祭)'), + (0x3241, '3', u'(休)'), + (0x3242, '3', u'(自)'), + (0x3243, '3', u'(至)'), + (0x3244, 'M', u'問'), + (0x3245, 'M', u'幼'), + (0x3246, 'M', u'文'), + (0x3247, 'M', u'箏'), + (0x3248, 'V'), + (0x3250, 'M', u'pte'), + (0x3251, 'M', u'21'), + (0x3252, 'M', u'22'), + (0x3253, 'M', u'23'), + (0x3254, 'M', u'24'), + (0x3255, 'M', u'25'), + (0x3256, 'M', u'26'), + (0x3257, 'M', u'27'), + (0x3258, 'M', u'28'), + ] + +def _seg_31(): + return [ + (0x3259, 'M', u'29'), + (0x325A, 'M', u'30'), + (0x325B, 'M', u'31'), + (0x325C, 'M', u'32'), + (0x325D, 'M', u'33'), + (0x325E, 'M', u'34'), + (0x325F, 'M', u'35'), + (0x3260, 'M', u'ᄀ'), + (0x3261, 'M', u'ᄂ'), + (0x3262, 'M', u'ᄃ'), + (0x3263, 'M', u'ᄅ'), + (0x3264, 'M', u'ᄆ'), + (0x3265, 'M', u'ᄇ'), + (0x3266, 'M', u'ᄉ'), + (0x3267, 'M', u'ᄋ'), + (0x3268, 'M', u'ᄌ'), + (0x3269, 'M', u'ᄎ'), + (0x326A, 'M', u'ᄏ'), + (0x326B, 'M', u'ᄐ'), + (0x326C, 'M', u'ᄑ'), + (0x326D, 'M', u'ᄒ'), + (0x326E, 'M', u'가'), + (0x326F, 'M', u'나'), + (0x3270, 'M', u'다'), + (0x3271, 'M', u'라'), + (0x3272, 'M', u'마'), + (0x3273, 'M', u'바'), + (0x3274, 'M', u'사'), + (0x3275, 'M', u'아'), + (0x3276, 'M', u'자'), + (0x3277, 'M', u'차'), + (0x3278, 'M', u'카'), + (0x3279, 'M', u'타'), + (0x327A, 'M', u'파'), + (0x327B, 'M', u'하'), + (0x327C, 'M', u'참고'), + (0x327D, 'M', u'주의'), + (0x327E, 'M', u'우'), + (0x327F, 'V'), + (0x3280, 'M', u'一'), + (0x3281, 'M', u'二'), + (0x3282, 'M', u'三'), + (0x3283, 'M', u'四'), + (0x3284, 'M', u'五'), + (0x3285, 'M', u'六'), + (0x3286, 'M', u'七'), + (0x3287, 'M', u'八'), + (0x3288, 'M', u'九'), + (0x3289, 'M', u'十'), + (0x328A, 'M', u'月'), + (0x328B, 'M', u'火'), + (0x328C, 'M', u'水'), + (0x328D, 'M', u'木'), + (0x328E, 'M', u'金'), + (0x328F, 'M', u'土'), + (0x3290, 'M', u'日'), + (0x3291, 'M', u'株'), + (0x3292, 'M', u'有'), + (0x3293, 'M', u'社'), + (0x3294, 'M', u'名'), + (0x3295, 'M', u'特'), + (0x3296, 'M', u'財'), + (0x3297, 'M', u'祝'), + (0x3298, 'M', u'労'), + (0x3299, 'M', u'秘'), + (0x329A, 'M', u'男'), + (0x329B, 'M', u'女'), + (0x329C, 'M', u'適'), + (0x329D, 'M', u'優'), + (0x329E, 'M', u'印'), + (0x329F, 'M', u'注'), + (0x32A0, 'M', u'項'), + (0x32A1, 'M', u'休'), + (0x32A2, 'M', u'写'), + (0x32A3, 'M', u'正'), + (0x32A4, 'M', u'上'), + (0x32A5, 'M', u'中'), + (0x32A6, 'M', u'下'), + (0x32A7, 'M', u'左'), + (0x32A8, 'M', u'右'), + (0x32A9, 'M', u'医'), + (0x32AA, 'M', u'宗'), + (0x32AB, 'M', u'学'), + (0x32AC, 'M', u'監'), + (0x32AD, 'M', u'企'), + (0x32AE, 'M', u'資'), + (0x32AF, 'M', u'協'), + (0x32B0, 'M', u'夜'), + (0x32B1, 'M', u'36'), + (0x32B2, 'M', u'37'), + (0x32B3, 'M', u'38'), + (0x32B4, 'M', u'39'), + (0x32B5, 'M', u'40'), + (0x32B6, 'M', u'41'), + (0x32B7, 'M', u'42'), + (0x32B8, 'M', u'43'), + (0x32B9, 'M', u'44'), + (0x32BA, 'M', u'45'), + (0x32BB, 'M', u'46'), + (0x32BC, 'M', u'47'), + ] + +def _seg_32(): + return [ + (0x32BD, 'M', u'48'), + (0x32BE, 'M', u'49'), + (0x32BF, 'M', u'50'), + (0x32C0, 'M', u'1月'), + (0x32C1, 'M', u'2月'), + (0x32C2, 'M', u'3月'), + (0x32C3, 'M', u'4月'), + (0x32C4, 'M', u'5月'), + (0x32C5, 'M', u'6月'), + (0x32C6, 'M', u'7月'), + (0x32C7, 'M', u'8月'), + (0x32C8, 'M', u'9月'), + (0x32C9, 'M', u'10月'), + (0x32CA, 'M', u'11月'), + (0x32CB, 'M', u'12月'), + (0x32CC, 'M', u'hg'), + (0x32CD, 'M', u'erg'), + (0x32CE, 'M', u'ev'), + (0x32CF, 'M', u'ltd'), + (0x32D0, 'M', u'ア'), + (0x32D1, 'M', u'イ'), + (0x32D2, 'M', u'ウ'), + (0x32D3, 'M', u'エ'), + (0x32D4, 'M', u'オ'), + (0x32D5, 'M', u'カ'), + (0x32D6, 'M', u'キ'), + (0x32D7, 'M', u'ク'), + (0x32D8, 'M', u'ケ'), + (0x32D9, 'M', u'コ'), + (0x32DA, 'M', u'サ'), + (0x32DB, 'M', u'シ'), + (0x32DC, 'M', u'ス'), + (0x32DD, 'M', u'セ'), + (0x32DE, 'M', u'ソ'), + (0x32DF, 'M', u'タ'), + (0x32E0, 'M', u'チ'), + (0x32E1, 'M', u'ツ'), + (0x32E2, 'M', u'テ'), + (0x32E3, 'M', u'ト'), + (0x32E4, 'M', u'ナ'), + (0x32E5, 'M', u'ニ'), + (0x32E6, 'M', u'ヌ'), + (0x32E7, 'M', u'ネ'), + (0x32E8, 'M', u'ノ'), + (0x32E9, 'M', u'ハ'), + (0x32EA, 'M', u'ヒ'), + (0x32EB, 'M', u'フ'), + (0x32EC, 'M', u'ヘ'), + (0x32ED, 'M', u'ホ'), + (0x32EE, 'M', u'マ'), + (0x32EF, 'M', u'ミ'), + (0x32F0, 'M', u'ム'), + (0x32F1, 'M', u'メ'), + (0x32F2, 'M', u'モ'), + (0x32F3, 'M', u'ヤ'), + (0x32F4, 'M', u'ユ'), + (0x32F5, 'M', u'ヨ'), + (0x32F6, 'M', u'ラ'), + (0x32F7, 'M', u'リ'), + (0x32F8, 'M', u'ル'), + (0x32F9, 'M', u'レ'), + (0x32FA, 'M', u'ロ'), + (0x32FB, 'M', u'ワ'), + (0x32FC, 'M', u'ヰ'), + (0x32FD, 'M', u'ヱ'), + (0x32FE, 'M', u'ヲ'), + (0x32FF, 'X'), + (0x3300, 'M', u'アパート'), + (0x3301, 'M', u'アルファ'), + (0x3302, 'M', u'アンペア'), + (0x3303, 'M', u'アール'), + (0x3304, 'M', u'イニング'), + (0x3305, 'M', u'インチ'), + (0x3306, 'M', u'ウォン'), + (0x3307, 'M', u'エスクード'), + (0x3308, 'M', u'エーカー'), + (0x3309, 'M', u'オンス'), + (0x330A, 'M', u'オーム'), + (0x330B, 'M', u'カイリ'), + (0x330C, 'M', u'カラット'), + (0x330D, 'M', u'カロリー'), + (0x330E, 'M', u'ガロン'), + (0x330F, 'M', u'ガンマ'), + (0x3310, 'M', u'ギガ'), + (0x3311, 'M', u'ギニー'), + (0x3312, 'M', u'キュリー'), + (0x3313, 'M', u'ギルダー'), + (0x3314, 'M', u'キロ'), + (0x3315, 'M', u'キログラム'), + (0x3316, 'M', u'キロメートル'), + (0x3317, 'M', u'キロワット'), + (0x3318, 'M', u'グラム'), + (0x3319, 'M', u'グラムトン'), + (0x331A, 'M', u'クルゼイロ'), + (0x331B, 'M', u'クローネ'), + (0x331C, 'M', u'ケース'), + (0x331D, 'M', u'コルナ'), + (0x331E, 'M', u'コーポ'), + (0x331F, 'M', u'サイクル'), + (0x3320, 'M', u'サンチーム'), + ] + +def _seg_33(): + return [ + (0x3321, 'M', u'シリング'), + (0x3322, 'M', u'センチ'), + (0x3323, 'M', u'セント'), + (0x3324, 'M', u'ダース'), + (0x3325, 'M', u'デシ'), + (0x3326, 'M', u'ドル'), + (0x3327, 'M', u'トン'), + (0x3328, 'M', u'ナノ'), + (0x3329, 'M', u'ノット'), + (0x332A, 'M', u'ハイツ'), + (0x332B, 'M', u'パーセント'), + (0x332C, 'M', u'パーツ'), + (0x332D, 'M', u'バーレル'), + (0x332E, 'M', u'ピアストル'), + (0x332F, 'M', u'ピクル'), + (0x3330, 'M', u'ピコ'), + (0x3331, 'M', u'ビル'), + (0x3332, 'M', u'ファラッド'), + (0x3333, 'M', u'フィート'), + (0x3334, 'M', u'ブッシェル'), + (0x3335, 'M', u'フラン'), + (0x3336, 'M', u'ヘクタール'), + (0x3337, 'M', u'ペソ'), + (0x3338, 'M', u'ペニヒ'), + (0x3339, 'M', u'ヘルツ'), + (0x333A, 'M', u'ペンス'), + (0x333B, 'M', u'ページ'), + (0x333C, 'M', u'ベータ'), + (0x333D, 'M', u'ポイント'), + (0x333E, 'M', u'ボルト'), + (0x333F, 'M', u'ホン'), + (0x3340, 'M', u'ポンド'), + (0x3341, 'M', u'ホール'), + (0x3342, 'M', u'ホーン'), + (0x3343, 'M', u'マイクロ'), + (0x3344, 'M', u'マイル'), + (0x3345, 'M', u'マッハ'), + (0x3346, 'M', u'マルク'), + (0x3347, 'M', u'マンション'), + (0x3348, 'M', u'ミクロン'), + (0x3349, 'M', u'ミリ'), + (0x334A, 'M', u'ミリバール'), + (0x334B, 'M', u'メガ'), + (0x334C, 'M', u'メガトン'), + (0x334D, 'M', u'メートル'), + (0x334E, 'M', u'ヤード'), + (0x334F, 'M', u'ヤール'), + (0x3350, 'M', u'ユアン'), + (0x3351, 'M', u'リットル'), + (0x3352, 'M', u'リラ'), + (0x3353, 'M', u'ルピー'), + (0x3354, 'M', u'ルーブル'), + (0x3355, 'M', u'レム'), + (0x3356, 'M', u'レントゲン'), + (0x3357, 'M', u'ワット'), + (0x3358, 'M', u'0点'), + (0x3359, 'M', u'1点'), + (0x335A, 'M', u'2点'), + (0x335B, 'M', u'3点'), + (0x335C, 'M', u'4点'), + (0x335D, 'M', u'5点'), + (0x335E, 'M', u'6点'), + (0x335F, 'M', u'7点'), + (0x3360, 'M', u'8点'), + (0x3361, 'M', u'9点'), + (0x3362, 'M', u'10点'), + (0x3363, 'M', u'11点'), + (0x3364, 'M', u'12点'), + (0x3365, 'M', u'13点'), + (0x3366, 'M', u'14点'), + (0x3367, 'M', u'15点'), + (0x3368, 'M', u'16点'), + (0x3369, 'M', u'17点'), + (0x336A, 'M', u'18点'), + (0x336B, 'M', u'19点'), + (0x336C, 'M', u'20点'), + (0x336D, 'M', u'21点'), + (0x336E, 'M', u'22点'), + (0x336F, 'M', u'23点'), + (0x3370, 'M', u'24点'), + (0x3371, 'M', u'hpa'), + (0x3372, 'M', u'da'), + (0x3373, 'M', u'au'), + (0x3374, 'M', u'bar'), + (0x3375, 'M', u'ov'), + (0x3376, 'M', u'pc'), + (0x3377, 'M', u'dm'), + (0x3378, 'M', u'dm2'), + (0x3379, 'M', u'dm3'), + (0x337A, 'M', u'iu'), + (0x337B, 'M', u'平成'), + (0x337C, 'M', u'昭和'), + (0x337D, 'M', u'大正'), + (0x337E, 'M', u'明治'), + (0x337F, 'M', u'株式会社'), + (0x3380, 'M', u'pa'), + (0x3381, 'M', u'na'), + (0x3382, 'M', u'μa'), + (0x3383, 'M', u'ma'), + (0x3384, 'M', u'ka'), + ] + +def _seg_34(): + return [ + (0x3385, 'M', u'kb'), + (0x3386, 'M', u'mb'), + (0x3387, 'M', u'gb'), + (0x3388, 'M', u'cal'), + (0x3389, 'M', u'kcal'), + (0x338A, 'M', u'pf'), + (0x338B, 'M', u'nf'), + (0x338C, 'M', u'μf'), + (0x338D, 'M', u'μg'), + (0x338E, 'M', u'mg'), + (0x338F, 'M', u'kg'), + (0x3390, 'M', u'hz'), + (0x3391, 'M', u'khz'), + (0x3392, 'M', u'mhz'), + (0x3393, 'M', u'ghz'), + (0x3394, 'M', u'thz'), + (0x3395, 'M', u'μl'), + (0x3396, 'M', u'ml'), + (0x3397, 'M', u'dl'), + (0x3398, 'M', u'kl'), + (0x3399, 'M', u'fm'), + (0x339A, 'M', u'nm'), + (0x339B, 'M', u'μm'), + (0x339C, 'M', u'mm'), + (0x339D, 'M', u'cm'), + (0x339E, 'M', u'km'), + (0x339F, 'M', u'mm2'), + (0x33A0, 'M', u'cm2'), + (0x33A1, 'M', u'm2'), + (0x33A2, 'M', u'km2'), + (0x33A3, 'M', u'mm3'), + (0x33A4, 'M', u'cm3'), + (0x33A5, 'M', u'm3'), + (0x33A6, 'M', u'km3'), + (0x33A7, 'M', u'm∕s'), + (0x33A8, 'M', u'm∕s2'), + (0x33A9, 'M', u'pa'), + (0x33AA, 'M', u'kpa'), + (0x33AB, 'M', u'mpa'), + (0x33AC, 'M', u'gpa'), + (0x33AD, 'M', u'rad'), + (0x33AE, 'M', u'rad∕s'), + (0x33AF, 'M', u'rad∕s2'), + (0x33B0, 'M', u'ps'), + (0x33B1, 'M', u'ns'), + (0x33B2, 'M', u'μs'), + (0x33B3, 'M', u'ms'), + (0x33B4, 'M', u'pv'), + (0x33B5, 'M', u'nv'), + (0x33B6, 'M', u'μv'), + (0x33B7, 'M', u'mv'), + (0x33B8, 'M', u'kv'), + (0x33B9, 'M', u'mv'), + (0x33BA, 'M', u'pw'), + (0x33BB, 'M', u'nw'), + (0x33BC, 'M', u'μw'), + (0x33BD, 'M', u'mw'), + (0x33BE, 'M', u'kw'), + (0x33BF, 'M', u'mw'), + (0x33C0, 'M', u'kω'), + (0x33C1, 'M', u'mω'), + (0x33C2, 'X'), + (0x33C3, 'M', u'bq'), + (0x33C4, 'M', u'cc'), + (0x33C5, 'M', u'cd'), + (0x33C6, 'M', u'c∕kg'), + (0x33C7, 'X'), + (0x33C8, 'M', u'db'), + (0x33C9, 'M', u'gy'), + (0x33CA, 'M', u'ha'), + (0x33CB, 'M', u'hp'), + (0x33CC, 'M', u'in'), + (0x33CD, 'M', u'kk'), + (0x33CE, 'M', u'km'), + (0x33CF, 'M', u'kt'), + (0x33D0, 'M', u'lm'), + (0x33D1, 'M', u'ln'), + (0x33D2, 'M', u'log'), + (0x33D3, 'M', u'lx'), + (0x33D4, 'M', u'mb'), + (0x33D5, 'M', u'mil'), + (0x33D6, 'M', u'mol'), + (0x33D7, 'M', u'ph'), + (0x33D8, 'X'), + (0x33D9, 'M', u'ppm'), + (0x33DA, 'M', u'pr'), + (0x33DB, 'M', u'sr'), + (0x33DC, 'M', u'sv'), + (0x33DD, 'M', u'wb'), + (0x33DE, 'M', u'v∕m'), + (0x33DF, 'M', u'a∕m'), + (0x33E0, 'M', u'1日'), + (0x33E1, 'M', u'2日'), + (0x33E2, 'M', u'3日'), + (0x33E3, 'M', u'4日'), + (0x33E4, 'M', u'5日'), + (0x33E5, 'M', u'6日'), + (0x33E6, 'M', u'7日'), + (0x33E7, 'M', u'8日'), + (0x33E8, 'M', u'9日'), + ] + +def _seg_35(): + return [ + (0x33E9, 'M', u'10日'), + (0x33EA, 'M', u'11日'), + (0x33EB, 'M', u'12日'), + (0x33EC, 'M', u'13日'), + (0x33ED, 'M', u'14日'), + (0x33EE, 'M', u'15日'), + (0x33EF, 'M', u'16日'), + (0x33F0, 'M', u'17日'), + (0x33F1, 'M', u'18日'), + (0x33F2, 'M', u'19日'), + (0x33F3, 'M', u'20日'), + (0x33F4, 'M', u'21日'), + (0x33F5, 'M', u'22日'), + (0x33F6, 'M', u'23日'), + (0x33F7, 'M', u'24日'), + (0x33F8, 'M', u'25日'), + (0x33F9, 'M', u'26日'), + (0x33FA, 'M', u'27日'), + (0x33FB, 'M', u'28日'), + (0x33FC, 'M', u'29日'), + (0x33FD, 'M', u'30日'), + (0x33FE, 'M', u'31日'), + (0x33FF, 'M', u'gal'), + (0x3400, 'V'), + (0x4DB6, 'X'), + (0x4DC0, 'V'), + (0x9FEB, 'X'), + (0xA000, 'V'), + (0xA48D, 'X'), + (0xA490, 'V'), + (0xA4C7, 'X'), + (0xA4D0, 'V'), + (0xA62C, 'X'), + (0xA640, 'M', u'ꙁ'), + (0xA641, 'V'), + (0xA642, 'M', u'ꙃ'), + (0xA643, 'V'), + (0xA644, 'M', u'ꙅ'), + (0xA645, 'V'), + (0xA646, 'M', u'ꙇ'), + (0xA647, 'V'), + (0xA648, 'M', u'ꙉ'), + (0xA649, 'V'), + (0xA64A, 'M', u'ꙋ'), + (0xA64B, 'V'), + (0xA64C, 'M', u'ꙍ'), + (0xA64D, 'V'), + (0xA64E, 'M', u'ꙏ'), + (0xA64F, 'V'), + (0xA650, 'M', u'ꙑ'), + (0xA651, 'V'), + (0xA652, 'M', u'ꙓ'), + (0xA653, 'V'), + (0xA654, 'M', u'ꙕ'), + (0xA655, 'V'), + (0xA656, 'M', u'ꙗ'), + (0xA657, 'V'), + (0xA658, 'M', u'ꙙ'), + (0xA659, 'V'), + (0xA65A, 'M', u'ꙛ'), + (0xA65B, 'V'), + (0xA65C, 'M', u'ꙝ'), + (0xA65D, 'V'), + (0xA65E, 'M', u'ꙟ'), + (0xA65F, 'V'), + (0xA660, 'M', u'ꙡ'), + (0xA661, 'V'), + (0xA662, 'M', u'ꙣ'), + (0xA663, 'V'), + (0xA664, 'M', u'ꙥ'), + (0xA665, 'V'), + (0xA666, 'M', u'ꙧ'), + (0xA667, 'V'), + (0xA668, 'M', u'ꙩ'), + (0xA669, 'V'), + (0xA66A, 'M', u'ꙫ'), + (0xA66B, 'V'), + (0xA66C, 'M', u'ꙭ'), + (0xA66D, 'V'), + (0xA680, 'M', u'ꚁ'), + (0xA681, 'V'), + (0xA682, 'M', u'ꚃ'), + (0xA683, 'V'), + (0xA684, 'M', u'ꚅ'), + (0xA685, 'V'), + (0xA686, 'M', u'ꚇ'), + (0xA687, 'V'), + (0xA688, 'M', u'ꚉ'), + (0xA689, 'V'), + (0xA68A, 'M', u'ꚋ'), + (0xA68B, 'V'), + (0xA68C, 'M', u'ꚍ'), + (0xA68D, 'V'), + (0xA68E, 'M', u'ꚏ'), + (0xA68F, 'V'), + (0xA690, 'M', u'ꚑ'), + (0xA691, 'V'), + (0xA692, 'M', u'ꚓ'), + (0xA693, 'V'), + (0xA694, 'M', u'ꚕ'), + ] + +def _seg_36(): + return [ + (0xA695, 'V'), + (0xA696, 'M', u'ꚗ'), + (0xA697, 'V'), + (0xA698, 'M', u'ꚙ'), + (0xA699, 'V'), + (0xA69A, 'M', u'ꚛ'), + (0xA69B, 'V'), + (0xA69C, 'M', u'ъ'), + (0xA69D, 'M', u'ь'), + (0xA69E, 'V'), + (0xA6F8, 'X'), + (0xA700, 'V'), + (0xA722, 'M', u'ꜣ'), + (0xA723, 'V'), + (0xA724, 'M', u'ꜥ'), + (0xA725, 'V'), + (0xA726, 'M', u'ꜧ'), + (0xA727, 'V'), + (0xA728, 'M', u'ꜩ'), + (0xA729, 'V'), + (0xA72A, 'M', u'ꜫ'), + (0xA72B, 'V'), + (0xA72C, 'M', u'ꜭ'), + (0xA72D, 'V'), + (0xA72E, 'M', u'ꜯ'), + (0xA72F, 'V'), + (0xA732, 'M', u'ꜳ'), + (0xA733, 'V'), + (0xA734, 'M', u'ꜵ'), + (0xA735, 'V'), + (0xA736, 'M', u'ꜷ'), + (0xA737, 'V'), + (0xA738, 'M', u'ꜹ'), + (0xA739, 'V'), + (0xA73A, 'M', u'ꜻ'), + (0xA73B, 'V'), + (0xA73C, 'M', u'ꜽ'), + (0xA73D, 'V'), + (0xA73E, 'M', u'ꜿ'), + (0xA73F, 'V'), + (0xA740, 'M', u'ꝁ'), + (0xA741, 'V'), + (0xA742, 'M', u'ꝃ'), + (0xA743, 'V'), + (0xA744, 'M', u'ꝅ'), + (0xA745, 'V'), + (0xA746, 'M', u'ꝇ'), + (0xA747, 'V'), + (0xA748, 'M', u'ꝉ'), + (0xA749, 'V'), + (0xA74A, 'M', u'ꝋ'), + (0xA74B, 'V'), + (0xA74C, 'M', u'ꝍ'), + (0xA74D, 'V'), + (0xA74E, 'M', u'ꝏ'), + (0xA74F, 'V'), + (0xA750, 'M', u'ꝑ'), + (0xA751, 'V'), + (0xA752, 'M', u'ꝓ'), + (0xA753, 'V'), + (0xA754, 'M', u'ꝕ'), + (0xA755, 'V'), + (0xA756, 'M', u'ꝗ'), + (0xA757, 'V'), + (0xA758, 'M', u'ꝙ'), + (0xA759, 'V'), + (0xA75A, 'M', u'ꝛ'), + (0xA75B, 'V'), + (0xA75C, 'M', u'ꝝ'), + (0xA75D, 'V'), + (0xA75E, 'M', u'ꝟ'), + (0xA75F, 'V'), + (0xA760, 'M', u'ꝡ'), + (0xA761, 'V'), + (0xA762, 'M', u'ꝣ'), + (0xA763, 'V'), + (0xA764, 'M', u'ꝥ'), + (0xA765, 'V'), + (0xA766, 'M', u'ꝧ'), + (0xA767, 'V'), + (0xA768, 'M', u'ꝩ'), + (0xA769, 'V'), + (0xA76A, 'M', u'ꝫ'), + (0xA76B, 'V'), + (0xA76C, 'M', u'ꝭ'), + (0xA76D, 'V'), + (0xA76E, 'M', u'ꝯ'), + (0xA76F, 'V'), + (0xA770, 'M', u'ꝯ'), + (0xA771, 'V'), + (0xA779, 'M', u'ꝺ'), + (0xA77A, 'V'), + (0xA77B, 'M', u'ꝼ'), + (0xA77C, 'V'), + (0xA77D, 'M', u'ᵹ'), + (0xA77E, 'M', u'ꝿ'), + (0xA77F, 'V'), + (0xA780, 'M', u'ꞁ'), + (0xA781, 'V'), + (0xA782, 'M', u'ꞃ'), + ] + +def _seg_37(): + return [ + (0xA783, 'V'), + (0xA784, 'M', u'ꞅ'), + (0xA785, 'V'), + (0xA786, 'M', u'ꞇ'), + (0xA787, 'V'), + (0xA78B, 'M', u'ꞌ'), + (0xA78C, 'V'), + (0xA78D, 'M', u'ɥ'), + (0xA78E, 'V'), + (0xA790, 'M', u'ꞑ'), + (0xA791, 'V'), + (0xA792, 'M', u'ꞓ'), + (0xA793, 'V'), + (0xA796, 'M', u'ꞗ'), + (0xA797, 'V'), + (0xA798, 'M', u'ꞙ'), + (0xA799, 'V'), + (0xA79A, 'M', u'ꞛ'), + (0xA79B, 'V'), + (0xA79C, 'M', u'ꞝ'), + (0xA79D, 'V'), + (0xA79E, 'M', u'ꞟ'), + (0xA79F, 'V'), + (0xA7A0, 'M', u'ꞡ'), + (0xA7A1, 'V'), + (0xA7A2, 'M', u'ꞣ'), + (0xA7A3, 'V'), + (0xA7A4, 'M', u'ꞥ'), + (0xA7A5, 'V'), + (0xA7A6, 'M', u'ꞧ'), + (0xA7A7, 'V'), + (0xA7A8, 'M', u'ꞩ'), + (0xA7A9, 'V'), + (0xA7AA, 'M', u'ɦ'), + (0xA7AB, 'M', u'ɜ'), + (0xA7AC, 'M', u'ɡ'), + (0xA7AD, 'M', u'ɬ'), + (0xA7AE, 'M', u'ɪ'), + (0xA7AF, 'X'), + (0xA7B0, 'M', u'ʞ'), + (0xA7B1, 'M', u'ʇ'), + (0xA7B2, 'M', u'ʝ'), + (0xA7B3, 'M', u'ꭓ'), + (0xA7B4, 'M', u'ꞵ'), + (0xA7B5, 'V'), + (0xA7B6, 'M', u'ꞷ'), + (0xA7B7, 'V'), + (0xA7B8, 'X'), + (0xA7F7, 'V'), + (0xA7F8, 'M', u'ħ'), + (0xA7F9, 'M', u'œ'), + (0xA7FA, 'V'), + (0xA82C, 'X'), + (0xA830, 'V'), + (0xA83A, 'X'), + (0xA840, 'V'), + (0xA878, 'X'), + (0xA880, 'V'), + (0xA8C6, 'X'), + (0xA8CE, 'V'), + (0xA8DA, 'X'), + (0xA8E0, 'V'), + (0xA8FE, 'X'), + (0xA900, 'V'), + (0xA954, 'X'), + (0xA95F, 'V'), + (0xA97D, 'X'), + (0xA980, 'V'), + (0xA9CE, 'X'), + (0xA9CF, 'V'), + (0xA9DA, 'X'), + (0xA9DE, 'V'), + (0xA9FF, 'X'), + (0xAA00, 'V'), + (0xAA37, 'X'), + (0xAA40, 'V'), + (0xAA4E, 'X'), + (0xAA50, 'V'), + (0xAA5A, 'X'), + (0xAA5C, 'V'), + (0xAAC3, 'X'), + (0xAADB, 'V'), + (0xAAF7, 'X'), + (0xAB01, 'V'), + (0xAB07, 'X'), + (0xAB09, 'V'), + (0xAB0F, 'X'), + (0xAB11, 'V'), + (0xAB17, 'X'), + (0xAB20, 'V'), + (0xAB27, 'X'), + (0xAB28, 'V'), + (0xAB2F, 'X'), + (0xAB30, 'V'), + (0xAB5C, 'M', u'ꜧ'), + (0xAB5D, 'M', u'ꬷ'), + (0xAB5E, 'M', u'ɫ'), + (0xAB5F, 'M', u'ꭒ'), + (0xAB60, 'V'), + (0xAB66, 'X'), + ] + +def _seg_38(): + return [ + (0xAB70, 'M', u'Ꭰ'), + (0xAB71, 'M', u'Ꭱ'), + (0xAB72, 'M', u'Ꭲ'), + (0xAB73, 'M', u'Ꭳ'), + (0xAB74, 'M', u'Ꭴ'), + (0xAB75, 'M', u'Ꭵ'), + (0xAB76, 'M', u'Ꭶ'), + (0xAB77, 'M', u'Ꭷ'), + (0xAB78, 'M', u'Ꭸ'), + (0xAB79, 'M', u'Ꭹ'), + (0xAB7A, 'M', u'Ꭺ'), + (0xAB7B, 'M', u'Ꭻ'), + (0xAB7C, 'M', u'Ꭼ'), + (0xAB7D, 'M', u'Ꭽ'), + (0xAB7E, 'M', u'Ꭾ'), + (0xAB7F, 'M', u'Ꭿ'), + (0xAB80, 'M', u'Ꮀ'), + (0xAB81, 'M', u'Ꮁ'), + (0xAB82, 'M', u'Ꮂ'), + (0xAB83, 'M', u'Ꮃ'), + (0xAB84, 'M', u'Ꮄ'), + (0xAB85, 'M', u'Ꮅ'), + (0xAB86, 'M', u'Ꮆ'), + (0xAB87, 'M', u'Ꮇ'), + (0xAB88, 'M', u'Ꮈ'), + (0xAB89, 'M', u'Ꮉ'), + (0xAB8A, 'M', u'Ꮊ'), + (0xAB8B, 'M', u'Ꮋ'), + (0xAB8C, 'M', u'Ꮌ'), + (0xAB8D, 'M', u'Ꮍ'), + (0xAB8E, 'M', u'Ꮎ'), + (0xAB8F, 'M', u'Ꮏ'), + (0xAB90, 'M', u'Ꮐ'), + (0xAB91, 'M', u'Ꮑ'), + (0xAB92, 'M', u'Ꮒ'), + (0xAB93, 'M', u'Ꮓ'), + (0xAB94, 'M', u'Ꮔ'), + (0xAB95, 'M', u'Ꮕ'), + (0xAB96, 'M', u'Ꮖ'), + (0xAB97, 'M', u'Ꮗ'), + (0xAB98, 'M', u'Ꮘ'), + (0xAB99, 'M', u'Ꮙ'), + (0xAB9A, 'M', u'Ꮚ'), + (0xAB9B, 'M', u'Ꮛ'), + (0xAB9C, 'M', u'Ꮜ'), + (0xAB9D, 'M', u'Ꮝ'), + (0xAB9E, 'M', u'Ꮞ'), + (0xAB9F, 'M', u'Ꮟ'), + (0xABA0, 'M', u'Ꮠ'), + (0xABA1, 'M', u'Ꮡ'), + (0xABA2, 'M', u'Ꮢ'), + (0xABA3, 'M', u'Ꮣ'), + (0xABA4, 'M', u'Ꮤ'), + (0xABA5, 'M', u'Ꮥ'), + (0xABA6, 'M', u'Ꮦ'), + (0xABA7, 'M', u'Ꮧ'), + (0xABA8, 'M', u'Ꮨ'), + (0xABA9, 'M', u'Ꮩ'), + (0xABAA, 'M', u'Ꮪ'), + (0xABAB, 'M', u'Ꮫ'), + (0xABAC, 'M', u'Ꮬ'), + (0xABAD, 'M', u'Ꮭ'), + (0xABAE, 'M', u'Ꮮ'), + (0xABAF, 'M', u'Ꮯ'), + (0xABB0, 'M', u'Ꮰ'), + (0xABB1, 'M', u'Ꮱ'), + (0xABB2, 'M', u'Ꮲ'), + (0xABB3, 'M', u'Ꮳ'), + (0xABB4, 'M', u'Ꮴ'), + (0xABB5, 'M', u'Ꮵ'), + (0xABB6, 'M', u'Ꮶ'), + (0xABB7, 'M', u'Ꮷ'), + (0xABB8, 'M', u'Ꮸ'), + (0xABB9, 'M', u'Ꮹ'), + (0xABBA, 'M', u'Ꮺ'), + (0xABBB, 'M', u'Ꮻ'), + (0xABBC, 'M', u'Ꮼ'), + (0xABBD, 'M', u'Ꮽ'), + (0xABBE, 'M', u'Ꮾ'), + (0xABBF, 'M', u'Ꮿ'), + (0xABC0, 'V'), + (0xABEE, 'X'), + (0xABF0, 'V'), + (0xABFA, 'X'), + (0xAC00, 'V'), + (0xD7A4, 'X'), + (0xD7B0, 'V'), + (0xD7C7, 'X'), + (0xD7CB, 'V'), + (0xD7FC, 'X'), + (0xF900, 'M', u'豈'), + (0xF901, 'M', u'更'), + (0xF902, 'M', u'車'), + (0xF903, 'M', u'賈'), + (0xF904, 'M', u'滑'), + (0xF905, 'M', u'串'), + (0xF906, 'M', u'句'), + (0xF907, 'M', u'龜'), + (0xF909, 'M', u'契'), + (0xF90A, 'M', u'金'), + ] + +def _seg_39(): + return [ + (0xF90B, 'M', u'喇'), + (0xF90C, 'M', u'奈'), + (0xF90D, 'M', u'懶'), + (0xF90E, 'M', u'癩'), + (0xF90F, 'M', u'羅'), + (0xF910, 'M', u'蘿'), + (0xF911, 'M', u'螺'), + (0xF912, 'M', u'裸'), + (0xF913, 'M', u'邏'), + (0xF914, 'M', u'樂'), + (0xF915, 'M', u'洛'), + (0xF916, 'M', u'烙'), + (0xF917, 'M', u'珞'), + (0xF918, 'M', u'落'), + (0xF919, 'M', u'酪'), + (0xF91A, 'M', u'駱'), + (0xF91B, 'M', u'亂'), + (0xF91C, 'M', u'卵'), + (0xF91D, 'M', u'欄'), + (0xF91E, 'M', u'爛'), + (0xF91F, 'M', u'蘭'), + (0xF920, 'M', u'鸞'), + (0xF921, 'M', u'嵐'), + (0xF922, 'M', u'濫'), + (0xF923, 'M', u'藍'), + (0xF924, 'M', u'襤'), + (0xF925, 'M', u'拉'), + (0xF926, 'M', u'臘'), + (0xF927, 'M', u'蠟'), + (0xF928, 'M', u'廊'), + (0xF929, 'M', u'朗'), + (0xF92A, 'M', u'浪'), + (0xF92B, 'M', u'狼'), + (0xF92C, 'M', u'郎'), + (0xF92D, 'M', u'來'), + (0xF92E, 'M', u'冷'), + (0xF92F, 'M', u'勞'), + (0xF930, 'M', u'擄'), + (0xF931, 'M', u'櫓'), + (0xF932, 'M', u'爐'), + (0xF933, 'M', u'盧'), + (0xF934, 'M', u'老'), + (0xF935, 'M', u'蘆'), + (0xF936, 'M', u'虜'), + (0xF937, 'M', u'路'), + (0xF938, 'M', u'露'), + (0xF939, 'M', u'魯'), + (0xF93A, 'M', u'鷺'), + (0xF93B, 'M', u'碌'), + (0xF93C, 'M', u'祿'), + (0xF93D, 'M', u'綠'), + (0xF93E, 'M', u'菉'), + (0xF93F, 'M', u'錄'), + (0xF940, 'M', u'鹿'), + (0xF941, 'M', u'論'), + (0xF942, 'M', u'壟'), + (0xF943, 'M', u'弄'), + (0xF944, 'M', u'籠'), + (0xF945, 'M', u'聾'), + (0xF946, 'M', u'牢'), + (0xF947, 'M', u'磊'), + (0xF948, 'M', u'賂'), + (0xF949, 'M', u'雷'), + (0xF94A, 'M', u'壘'), + (0xF94B, 'M', u'屢'), + (0xF94C, 'M', u'樓'), + (0xF94D, 'M', u'淚'), + (0xF94E, 'M', u'漏'), + (0xF94F, 'M', u'累'), + (0xF950, 'M', u'縷'), + (0xF951, 'M', u'陋'), + (0xF952, 'M', u'勒'), + (0xF953, 'M', u'肋'), + (0xF954, 'M', u'凜'), + (0xF955, 'M', u'凌'), + (0xF956, 'M', u'稜'), + (0xF957, 'M', u'綾'), + (0xF958, 'M', u'菱'), + (0xF959, 'M', u'陵'), + (0xF95A, 'M', u'讀'), + (0xF95B, 'M', u'拏'), + (0xF95C, 'M', u'樂'), + (0xF95D, 'M', u'諾'), + (0xF95E, 'M', u'丹'), + (0xF95F, 'M', u'寧'), + (0xF960, 'M', u'怒'), + (0xF961, 'M', u'率'), + (0xF962, 'M', u'異'), + (0xF963, 'M', u'北'), + (0xF964, 'M', u'磻'), + (0xF965, 'M', u'便'), + (0xF966, 'M', u'復'), + (0xF967, 'M', u'不'), + (0xF968, 'M', u'泌'), + (0xF969, 'M', u'數'), + (0xF96A, 'M', u'索'), + (0xF96B, 'M', u'參'), + (0xF96C, 'M', u'塞'), + (0xF96D, 'M', u'省'), + (0xF96E, 'M', u'葉'), + ] + +def _seg_40(): + return [ + (0xF96F, 'M', u'說'), + (0xF970, 'M', u'殺'), + (0xF971, 'M', u'辰'), + (0xF972, 'M', u'沈'), + (0xF973, 'M', u'拾'), + (0xF974, 'M', u'若'), + (0xF975, 'M', u'掠'), + (0xF976, 'M', u'略'), + (0xF977, 'M', u'亮'), + (0xF978, 'M', u'兩'), + (0xF979, 'M', u'凉'), + (0xF97A, 'M', u'梁'), + (0xF97B, 'M', u'糧'), + (0xF97C, 'M', u'良'), + (0xF97D, 'M', u'諒'), + (0xF97E, 'M', u'量'), + (0xF97F, 'M', u'勵'), + (0xF980, 'M', u'呂'), + (0xF981, 'M', u'女'), + (0xF982, 'M', u'廬'), + (0xF983, 'M', u'旅'), + (0xF984, 'M', u'濾'), + (0xF985, 'M', u'礪'), + (0xF986, 'M', u'閭'), + (0xF987, 'M', u'驪'), + (0xF988, 'M', u'麗'), + (0xF989, 'M', u'黎'), + (0xF98A, 'M', u'力'), + (0xF98B, 'M', u'曆'), + (0xF98C, 'M', u'歷'), + (0xF98D, 'M', u'轢'), + (0xF98E, 'M', u'年'), + (0xF98F, 'M', u'憐'), + (0xF990, 'M', u'戀'), + (0xF991, 'M', u'撚'), + (0xF992, 'M', u'漣'), + (0xF993, 'M', u'煉'), + (0xF994, 'M', u'璉'), + (0xF995, 'M', u'秊'), + (0xF996, 'M', u'練'), + (0xF997, 'M', u'聯'), + (0xF998, 'M', u'輦'), + (0xF999, 'M', u'蓮'), + (0xF99A, 'M', u'連'), + (0xF99B, 'M', u'鍊'), + (0xF99C, 'M', u'列'), + (0xF99D, 'M', u'劣'), + (0xF99E, 'M', u'咽'), + (0xF99F, 'M', u'烈'), + (0xF9A0, 'M', u'裂'), + (0xF9A1, 'M', u'說'), + (0xF9A2, 'M', u'廉'), + (0xF9A3, 'M', u'念'), + (0xF9A4, 'M', u'捻'), + (0xF9A5, 'M', u'殮'), + (0xF9A6, 'M', u'簾'), + (0xF9A7, 'M', u'獵'), + (0xF9A8, 'M', u'令'), + (0xF9A9, 'M', u'囹'), + (0xF9AA, 'M', u'寧'), + (0xF9AB, 'M', u'嶺'), + (0xF9AC, 'M', u'怜'), + (0xF9AD, 'M', u'玲'), + (0xF9AE, 'M', u'瑩'), + (0xF9AF, 'M', u'羚'), + (0xF9B0, 'M', u'聆'), + (0xF9B1, 'M', u'鈴'), + (0xF9B2, 'M', u'零'), + (0xF9B3, 'M', u'靈'), + (0xF9B4, 'M', u'領'), + (0xF9B5, 'M', u'例'), + (0xF9B6, 'M', u'禮'), + (0xF9B7, 'M', u'醴'), + (0xF9B8, 'M', u'隸'), + (0xF9B9, 'M', u'惡'), + (0xF9BA, 'M', u'了'), + (0xF9BB, 'M', u'僚'), + (0xF9BC, 'M', u'寮'), + (0xF9BD, 'M', u'尿'), + (0xF9BE, 'M', u'料'), + (0xF9BF, 'M', u'樂'), + (0xF9C0, 'M', u'燎'), + (0xF9C1, 'M', u'療'), + (0xF9C2, 'M', u'蓼'), + (0xF9C3, 'M', u'遼'), + (0xF9C4, 'M', u'龍'), + (0xF9C5, 'M', u'暈'), + (0xF9C6, 'M', u'阮'), + (0xF9C7, 'M', u'劉'), + (0xF9C8, 'M', u'杻'), + (0xF9C9, 'M', u'柳'), + (0xF9CA, 'M', u'流'), + (0xF9CB, 'M', u'溜'), + (0xF9CC, 'M', u'琉'), + (0xF9CD, 'M', u'留'), + (0xF9CE, 'M', u'硫'), + (0xF9CF, 'M', u'紐'), + (0xF9D0, 'M', u'類'), + (0xF9D1, 'M', u'六'), + (0xF9D2, 'M', u'戮'), + ] + +def _seg_41(): + return [ + (0xF9D3, 'M', u'陸'), + (0xF9D4, 'M', u'倫'), + (0xF9D5, 'M', u'崙'), + (0xF9D6, 'M', u'淪'), + (0xF9D7, 'M', u'輪'), + (0xF9D8, 'M', u'律'), + (0xF9D9, 'M', u'慄'), + (0xF9DA, 'M', u'栗'), + (0xF9DB, 'M', u'率'), + (0xF9DC, 'M', u'隆'), + (0xF9DD, 'M', u'利'), + (0xF9DE, 'M', u'吏'), + (0xF9DF, 'M', u'履'), + (0xF9E0, 'M', u'易'), + (0xF9E1, 'M', u'李'), + (0xF9E2, 'M', u'梨'), + (0xF9E3, 'M', u'泥'), + (0xF9E4, 'M', u'理'), + (0xF9E5, 'M', u'痢'), + (0xF9E6, 'M', u'罹'), + (0xF9E7, 'M', u'裏'), + (0xF9E8, 'M', u'裡'), + (0xF9E9, 'M', u'里'), + (0xF9EA, 'M', u'離'), + (0xF9EB, 'M', u'匿'), + (0xF9EC, 'M', u'溺'), + (0xF9ED, 'M', u'吝'), + (0xF9EE, 'M', u'燐'), + (0xF9EF, 'M', u'璘'), + (0xF9F0, 'M', u'藺'), + (0xF9F1, 'M', u'隣'), + (0xF9F2, 'M', u'鱗'), + (0xF9F3, 'M', u'麟'), + (0xF9F4, 'M', u'林'), + (0xF9F5, 'M', u'淋'), + (0xF9F6, 'M', u'臨'), + (0xF9F7, 'M', u'立'), + (0xF9F8, 'M', u'笠'), + (0xF9F9, 'M', u'粒'), + (0xF9FA, 'M', u'狀'), + (0xF9FB, 'M', u'炙'), + (0xF9FC, 'M', u'識'), + (0xF9FD, 'M', u'什'), + (0xF9FE, 'M', u'茶'), + (0xF9FF, 'M', u'刺'), + (0xFA00, 'M', u'切'), + (0xFA01, 'M', u'度'), + (0xFA02, 'M', u'拓'), + (0xFA03, 'M', u'糖'), + (0xFA04, 'M', u'宅'), + (0xFA05, 'M', u'洞'), + (0xFA06, 'M', u'暴'), + (0xFA07, 'M', u'輻'), + (0xFA08, 'M', u'行'), + (0xFA09, 'M', u'降'), + (0xFA0A, 'M', u'見'), + (0xFA0B, 'M', u'廓'), + (0xFA0C, 'M', u'兀'), + (0xFA0D, 'M', u'嗀'), + (0xFA0E, 'V'), + (0xFA10, 'M', u'塚'), + (0xFA11, 'V'), + (0xFA12, 'M', u'晴'), + (0xFA13, 'V'), + (0xFA15, 'M', u'凞'), + (0xFA16, 'M', u'猪'), + (0xFA17, 'M', u'益'), + (0xFA18, 'M', u'礼'), + (0xFA19, 'M', u'神'), + (0xFA1A, 'M', u'祥'), + (0xFA1B, 'M', u'福'), + (0xFA1C, 'M', u'靖'), + (0xFA1D, 'M', u'精'), + (0xFA1E, 'M', u'羽'), + (0xFA1F, 'V'), + (0xFA20, 'M', u'蘒'), + (0xFA21, 'V'), + (0xFA22, 'M', u'諸'), + (0xFA23, 'V'), + (0xFA25, 'M', u'逸'), + (0xFA26, 'M', u'都'), + (0xFA27, 'V'), + (0xFA2A, 'M', u'飯'), + (0xFA2B, 'M', u'飼'), + (0xFA2C, 'M', u'館'), + (0xFA2D, 'M', u'鶴'), + (0xFA2E, 'M', u'郞'), + (0xFA2F, 'M', u'隷'), + (0xFA30, 'M', u'侮'), + (0xFA31, 'M', u'僧'), + (0xFA32, 'M', u'免'), + (0xFA33, 'M', u'勉'), + (0xFA34, 'M', u'勤'), + (0xFA35, 'M', u'卑'), + (0xFA36, 'M', u'喝'), + (0xFA37, 'M', u'嘆'), + (0xFA38, 'M', u'器'), + (0xFA39, 'M', u'塀'), + (0xFA3A, 'M', u'墨'), + (0xFA3B, 'M', u'層'), + ] + +def _seg_42(): + return [ + (0xFA3C, 'M', u'屮'), + (0xFA3D, 'M', u'悔'), + (0xFA3E, 'M', u'慨'), + (0xFA3F, 'M', u'憎'), + (0xFA40, 'M', u'懲'), + (0xFA41, 'M', u'敏'), + (0xFA42, 'M', u'既'), + (0xFA43, 'M', u'暑'), + (0xFA44, 'M', u'梅'), + (0xFA45, 'M', u'海'), + (0xFA46, 'M', u'渚'), + (0xFA47, 'M', u'漢'), + (0xFA48, 'M', u'煮'), + (0xFA49, 'M', u'爫'), + (0xFA4A, 'M', u'琢'), + (0xFA4B, 'M', u'碑'), + (0xFA4C, 'M', u'社'), + (0xFA4D, 'M', u'祉'), + (0xFA4E, 'M', u'祈'), + (0xFA4F, 'M', u'祐'), + (0xFA50, 'M', u'祖'), + (0xFA51, 'M', u'祝'), + (0xFA52, 'M', u'禍'), + (0xFA53, 'M', u'禎'), + (0xFA54, 'M', u'穀'), + (0xFA55, 'M', u'突'), + (0xFA56, 'M', u'節'), + (0xFA57, 'M', u'練'), + (0xFA58, 'M', u'縉'), + (0xFA59, 'M', u'繁'), + (0xFA5A, 'M', u'署'), + (0xFA5B, 'M', u'者'), + (0xFA5C, 'M', u'臭'), + (0xFA5D, 'M', u'艹'), + (0xFA5F, 'M', u'著'), + (0xFA60, 'M', u'褐'), + (0xFA61, 'M', u'視'), + (0xFA62, 'M', u'謁'), + (0xFA63, 'M', u'謹'), + (0xFA64, 'M', u'賓'), + (0xFA65, 'M', u'贈'), + (0xFA66, 'M', u'辶'), + (0xFA67, 'M', u'逸'), + (0xFA68, 'M', u'難'), + (0xFA69, 'M', u'響'), + (0xFA6A, 'M', u'頻'), + (0xFA6B, 'M', u'恵'), + (0xFA6C, 'M', u'𤋮'), + (0xFA6D, 'M', u'舘'), + (0xFA6E, 'X'), + (0xFA70, 'M', u'並'), + (0xFA71, 'M', u'况'), + (0xFA72, 'M', u'全'), + (0xFA73, 'M', u'侀'), + (0xFA74, 'M', u'充'), + (0xFA75, 'M', u'冀'), + (0xFA76, 'M', u'勇'), + (0xFA77, 'M', u'勺'), + (0xFA78, 'M', u'喝'), + (0xFA79, 'M', u'啕'), + (0xFA7A, 'M', u'喙'), + (0xFA7B, 'M', u'嗢'), + (0xFA7C, 'M', u'塚'), + (0xFA7D, 'M', u'墳'), + (0xFA7E, 'M', u'奄'), + (0xFA7F, 'M', u'奔'), + (0xFA80, 'M', u'婢'), + (0xFA81, 'M', u'嬨'), + (0xFA82, 'M', u'廒'), + (0xFA83, 'M', u'廙'), + (0xFA84, 'M', u'彩'), + (0xFA85, 'M', u'徭'), + (0xFA86, 'M', u'惘'), + (0xFA87, 'M', u'慎'), + (0xFA88, 'M', u'愈'), + (0xFA89, 'M', u'憎'), + (0xFA8A, 'M', u'慠'), + (0xFA8B, 'M', u'懲'), + (0xFA8C, 'M', u'戴'), + (0xFA8D, 'M', u'揄'), + (0xFA8E, 'M', u'搜'), + (0xFA8F, 'M', u'摒'), + (0xFA90, 'M', u'敖'), + (0xFA91, 'M', u'晴'), + (0xFA92, 'M', u'朗'), + (0xFA93, 'M', u'望'), + (0xFA94, 'M', u'杖'), + (0xFA95, 'M', u'歹'), + (0xFA96, 'M', u'殺'), + (0xFA97, 'M', u'流'), + (0xFA98, 'M', u'滛'), + (0xFA99, 'M', u'滋'), + (0xFA9A, 'M', u'漢'), + (0xFA9B, 'M', u'瀞'), + (0xFA9C, 'M', u'煮'), + (0xFA9D, 'M', u'瞧'), + (0xFA9E, 'M', u'爵'), + (0xFA9F, 'M', u'犯'), + (0xFAA0, 'M', u'猪'), + (0xFAA1, 'M', u'瑱'), + ] + +def _seg_43(): + return [ + (0xFAA2, 'M', u'甆'), + (0xFAA3, 'M', u'画'), + (0xFAA4, 'M', u'瘝'), + (0xFAA5, 'M', u'瘟'), + (0xFAA6, 'M', u'益'), + (0xFAA7, 'M', u'盛'), + (0xFAA8, 'M', u'直'), + (0xFAA9, 'M', u'睊'), + (0xFAAA, 'M', u'着'), + (0xFAAB, 'M', u'磌'), + (0xFAAC, 'M', u'窱'), + (0xFAAD, 'M', u'節'), + (0xFAAE, 'M', u'类'), + (0xFAAF, 'M', u'絛'), + (0xFAB0, 'M', u'練'), + (0xFAB1, 'M', u'缾'), + (0xFAB2, 'M', u'者'), + (0xFAB3, 'M', u'荒'), + (0xFAB4, 'M', u'華'), + (0xFAB5, 'M', u'蝹'), + (0xFAB6, 'M', u'襁'), + (0xFAB7, 'M', u'覆'), + (0xFAB8, 'M', u'視'), + (0xFAB9, 'M', u'調'), + (0xFABA, 'M', u'諸'), + (0xFABB, 'M', u'請'), + (0xFABC, 'M', u'謁'), + (0xFABD, 'M', u'諾'), + (0xFABE, 'M', u'諭'), + (0xFABF, 'M', u'謹'), + (0xFAC0, 'M', u'變'), + (0xFAC1, 'M', u'贈'), + (0xFAC2, 'M', u'輸'), + (0xFAC3, 'M', u'遲'), + (0xFAC4, 'M', u'醙'), + (0xFAC5, 'M', u'鉶'), + (0xFAC6, 'M', u'陼'), + (0xFAC7, 'M', u'難'), + (0xFAC8, 'M', u'靖'), + (0xFAC9, 'M', u'韛'), + (0xFACA, 'M', u'響'), + (0xFACB, 'M', u'頋'), + (0xFACC, 'M', u'頻'), + (0xFACD, 'M', u'鬒'), + (0xFACE, 'M', u'龜'), + (0xFACF, 'M', u'𢡊'), + (0xFAD0, 'M', u'𢡄'), + (0xFAD1, 'M', u'𣏕'), + (0xFAD2, 'M', u'㮝'), + (0xFAD3, 'M', u'䀘'), + (0xFAD4, 'M', u'䀹'), + (0xFAD5, 'M', u'𥉉'), + (0xFAD6, 'M', u'𥳐'), + (0xFAD7, 'M', u'𧻓'), + (0xFAD8, 'M', u'齃'), + (0xFAD9, 'M', u'龎'), + (0xFADA, 'X'), + (0xFB00, 'M', u'ff'), + (0xFB01, 'M', u'fi'), + (0xFB02, 'M', u'fl'), + (0xFB03, 'M', u'ffi'), + (0xFB04, 'M', u'ffl'), + (0xFB05, 'M', u'st'), + (0xFB07, 'X'), + (0xFB13, 'M', u'մն'), + (0xFB14, 'M', u'մե'), + (0xFB15, 'M', u'մի'), + (0xFB16, 'M', u'վն'), + (0xFB17, 'M', u'մխ'), + (0xFB18, 'X'), + (0xFB1D, 'M', u'יִ'), + (0xFB1E, 'V'), + (0xFB1F, 'M', u'ײַ'), + (0xFB20, 'M', u'ע'), + (0xFB21, 'M', u'א'), + (0xFB22, 'M', u'ד'), + (0xFB23, 'M', u'ה'), + (0xFB24, 'M', u'כ'), + (0xFB25, 'M', u'ל'), + (0xFB26, 'M', u'ם'), + (0xFB27, 'M', u'ר'), + (0xFB28, 'M', u'ת'), + (0xFB29, '3', u'+'), + (0xFB2A, 'M', u'שׁ'), + (0xFB2B, 'M', u'שׂ'), + (0xFB2C, 'M', u'שּׁ'), + (0xFB2D, 'M', u'שּׂ'), + (0xFB2E, 'M', u'אַ'), + (0xFB2F, 'M', u'אָ'), + (0xFB30, 'M', u'אּ'), + (0xFB31, 'M', u'בּ'), + (0xFB32, 'M', u'גּ'), + (0xFB33, 'M', u'דּ'), + (0xFB34, 'M', u'הּ'), + (0xFB35, 'M', u'וּ'), + (0xFB36, 'M', u'זּ'), + (0xFB37, 'X'), + (0xFB38, 'M', u'טּ'), + (0xFB39, 'M', u'יּ'), + (0xFB3A, 'M', u'ךּ'), + ] + +def _seg_44(): + return [ + (0xFB3B, 'M', u'כּ'), + (0xFB3C, 'M', u'לּ'), + (0xFB3D, 'X'), + (0xFB3E, 'M', u'מּ'), + (0xFB3F, 'X'), + (0xFB40, 'M', u'נּ'), + (0xFB41, 'M', u'סּ'), + (0xFB42, 'X'), + (0xFB43, 'M', u'ףּ'), + (0xFB44, 'M', u'פּ'), + (0xFB45, 'X'), + (0xFB46, 'M', u'צּ'), + (0xFB47, 'M', u'קּ'), + (0xFB48, 'M', u'רּ'), + (0xFB49, 'M', u'שּ'), + (0xFB4A, 'M', u'תּ'), + (0xFB4B, 'M', u'וֹ'), + (0xFB4C, 'M', u'בֿ'), + (0xFB4D, 'M', u'כֿ'), + (0xFB4E, 'M', u'פֿ'), + (0xFB4F, 'M', u'אל'), + (0xFB50, 'M', u'ٱ'), + (0xFB52, 'M', u'ٻ'), + (0xFB56, 'M', u'پ'), + (0xFB5A, 'M', u'ڀ'), + (0xFB5E, 'M', u'ٺ'), + (0xFB62, 'M', u'ٿ'), + (0xFB66, 'M', u'ٹ'), + (0xFB6A, 'M', u'ڤ'), + (0xFB6E, 'M', u'ڦ'), + (0xFB72, 'M', u'ڄ'), + (0xFB76, 'M', u'ڃ'), + (0xFB7A, 'M', u'چ'), + (0xFB7E, 'M', u'ڇ'), + (0xFB82, 'M', u'ڍ'), + (0xFB84, 'M', u'ڌ'), + (0xFB86, 'M', u'ڎ'), + (0xFB88, 'M', u'ڈ'), + (0xFB8A, 'M', u'ژ'), + (0xFB8C, 'M', u'ڑ'), + (0xFB8E, 'M', u'ک'), + (0xFB92, 'M', u'گ'), + (0xFB96, 'M', u'ڳ'), + (0xFB9A, 'M', u'ڱ'), + (0xFB9E, 'M', u'ں'), + (0xFBA0, 'M', u'ڻ'), + (0xFBA4, 'M', u'ۀ'), + (0xFBA6, 'M', u'ہ'), + (0xFBAA, 'M', u'ھ'), + (0xFBAE, 'M', u'ے'), + (0xFBB0, 'M', u'ۓ'), + (0xFBB2, 'V'), + (0xFBC2, 'X'), + (0xFBD3, 'M', u'ڭ'), + (0xFBD7, 'M', u'ۇ'), + (0xFBD9, 'M', u'ۆ'), + (0xFBDB, 'M', u'ۈ'), + (0xFBDD, 'M', u'ۇٴ'), + (0xFBDE, 'M', u'ۋ'), + (0xFBE0, 'M', u'ۅ'), + (0xFBE2, 'M', u'ۉ'), + (0xFBE4, 'M', u'ې'), + (0xFBE8, 'M', u'ى'), + (0xFBEA, 'M', u'ئا'), + (0xFBEC, 'M', u'ئە'), + (0xFBEE, 'M', u'ئو'), + (0xFBF0, 'M', u'ئۇ'), + (0xFBF2, 'M', u'ئۆ'), + (0xFBF4, 'M', u'ئۈ'), + (0xFBF6, 'M', u'ئې'), + (0xFBF9, 'M', u'ئى'), + (0xFBFC, 'M', u'ی'), + (0xFC00, 'M', u'ئج'), + (0xFC01, 'M', u'ئح'), + (0xFC02, 'M', u'ئم'), + (0xFC03, 'M', u'ئى'), + (0xFC04, 'M', u'ئي'), + (0xFC05, 'M', u'بج'), + (0xFC06, 'M', u'بح'), + (0xFC07, 'M', u'بخ'), + (0xFC08, 'M', u'بم'), + (0xFC09, 'M', u'بى'), + (0xFC0A, 'M', u'بي'), + (0xFC0B, 'M', u'تج'), + (0xFC0C, 'M', u'تح'), + (0xFC0D, 'M', u'تخ'), + (0xFC0E, 'M', u'تم'), + (0xFC0F, 'M', u'تى'), + (0xFC10, 'M', u'تي'), + (0xFC11, 'M', u'ثج'), + (0xFC12, 'M', u'ثم'), + (0xFC13, 'M', u'ثى'), + (0xFC14, 'M', u'ثي'), + (0xFC15, 'M', u'جح'), + (0xFC16, 'M', u'جم'), + (0xFC17, 'M', u'حج'), + (0xFC18, 'M', u'حم'), + (0xFC19, 'M', u'خج'), + (0xFC1A, 'M', u'خح'), + (0xFC1B, 'M', u'خم'), + ] + +def _seg_45(): + return [ + (0xFC1C, 'M', u'سج'), + (0xFC1D, 'M', u'سح'), + (0xFC1E, 'M', u'سخ'), + (0xFC1F, 'M', u'سم'), + (0xFC20, 'M', u'صح'), + (0xFC21, 'M', u'صم'), + (0xFC22, 'M', u'ضج'), + (0xFC23, 'M', u'ضح'), + (0xFC24, 'M', u'ضخ'), + (0xFC25, 'M', u'ضم'), + (0xFC26, 'M', u'طح'), + (0xFC27, 'M', u'طم'), + (0xFC28, 'M', u'ظم'), + (0xFC29, 'M', u'عج'), + (0xFC2A, 'M', u'عم'), + (0xFC2B, 'M', u'غج'), + (0xFC2C, 'M', u'غم'), + (0xFC2D, 'M', u'فج'), + (0xFC2E, 'M', u'فح'), + (0xFC2F, 'M', u'فخ'), + (0xFC30, 'M', u'فم'), + (0xFC31, 'M', u'فى'), + (0xFC32, 'M', u'في'), + (0xFC33, 'M', u'قح'), + (0xFC34, 'M', u'قم'), + (0xFC35, 'M', u'قى'), + (0xFC36, 'M', u'قي'), + (0xFC37, 'M', u'كا'), + (0xFC38, 'M', u'كج'), + (0xFC39, 'M', u'كح'), + (0xFC3A, 'M', u'كخ'), + (0xFC3B, 'M', u'كل'), + (0xFC3C, 'M', u'كم'), + (0xFC3D, 'M', u'كى'), + (0xFC3E, 'M', u'كي'), + (0xFC3F, 'M', u'لج'), + (0xFC40, 'M', u'لح'), + (0xFC41, 'M', u'لخ'), + (0xFC42, 'M', u'لم'), + (0xFC43, 'M', u'لى'), + (0xFC44, 'M', u'لي'), + (0xFC45, 'M', u'مج'), + (0xFC46, 'M', u'مح'), + (0xFC47, 'M', u'مخ'), + (0xFC48, 'M', u'مم'), + (0xFC49, 'M', u'مى'), + (0xFC4A, 'M', u'مي'), + (0xFC4B, 'M', u'نج'), + (0xFC4C, 'M', u'نح'), + (0xFC4D, 'M', u'نخ'), + (0xFC4E, 'M', u'نم'), + (0xFC4F, 'M', u'نى'), + (0xFC50, 'M', u'ني'), + (0xFC51, 'M', u'هج'), + (0xFC52, 'M', u'هم'), + (0xFC53, 'M', u'هى'), + (0xFC54, 'M', u'هي'), + (0xFC55, 'M', u'يج'), + (0xFC56, 'M', u'يح'), + (0xFC57, 'M', u'يخ'), + (0xFC58, 'M', u'يم'), + (0xFC59, 'M', u'يى'), + (0xFC5A, 'M', u'يي'), + (0xFC5B, 'M', u'ذٰ'), + (0xFC5C, 'M', u'رٰ'), + (0xFC5D, 'M', u'ىٰ'), + (0xFC5E, '3', u' ٌّ'), + (0xFC5F, '3', u' ٍّ'), + (0xFC60, '3', u' َّ'), + (0xFC61, '3', u' ُّ'), + (0xFC62, '3', u' ِّ'), + (0xFC63, '3', u' ّٰ'), + (0xFC64, 'M', u'ئر'), + (0xFC65, 'M', u'ئز'), + (0xFC66, 'M', u'ئم'), + (0xFC67, 'M', u'ئن'), + (0xFC68, 'M', u'ئى'), + (0xFC69, 'M', u'ئي'), + (0xFC6A, 'M', u'بر'), + (0xFC6B, 'M', u'بز'), + (0xFC6C, 'M', u'بم'), + (0xFC6D, 'M', u'بن'), + (0xFC6E, 'M', u'بى'), + (0xFC6F, 'M', u'بي'), + (0xFC70, 'M', u'تر'), + (0xFC71, 'M', u'تز'), + (0xFC72, 'M', u'تم'), + (0xFC73, 'M', u'تن'), + (0xFC74, 'M', u'تى'), + (0xFC75, 'M', u'تي'), + (0xFC76, 'M', u'ثر'), + (0xFC77, 'M', u'ثز'), + (0xFC78, 'M', u'ثم'), + (0xFC79, 'M', u'ثن'), + (0xFC7A, 'M', u'ثى'), + (0xFC7B, 'M', u'ثي'), + (0xFC7C, 'M', u'فى'), + (0xFC7D, 'M', u'في'), + (0xFC7E, 'M', u'قى'), + (0xFC7F, 'M', u'قي'), + ] + +def _seg_46(): + return [ + (0xFC80, 'M', u'كا'), + (0xFC81, 'M', u'كل'), + (0xFC82, 'M', u'كم'), + (0xFC83, 'M', u'كى'), + (0xFC84, 'M', u'كي'), + (0xFC85, 'M', u'لم'), + (0xFC86, 'M', u'لى'), + (0xFC87, 'M', u'لي'), + (0xFC88, 'M', u'ما'), + (0xFC89, 'M', u'مم'), + (0xFC8A, 'M', u'نر'), + (0xFC8B, 'M', u'نز'), + (0xFC8C, 'M', u'نم'), + (0xFC8D, 'M', u'نن'), + (0xFC8E, 'M', u'نى'), + (0xFC8F, 'M', u'ني'), + (0xFC90, 'M', u'ىٰ'), + (0xFC91, 'M', u'ير'), + (0xFC92, 'M', u'يز'), + (0xFC93, 'M', u'يم'), + (0xFC94, 'M', u'ين'), + (0xFC95, 'M', u'يى'), + (0xFC96, 'M', u'يي'), + (0xFC97, 'M', u'ئج'), + (0xFC98, 'M', u'ئح'), + (0xFC99, 'M', u'ئخ'), + (0xFC9A, 'M', u'ئم'), + (0xFC9B, 'M', u'ئه'), + (0xFC9C, 'M', u'بج'), + (0xFC9D, 'M', u'بح'), + (0xFC9E, 'M', u'بخ'), + (0xFC9F, 'M', u'بم'), + (0xFCA0, 'M', u'به'), + (0xFCA1, 'M', u'تج'), + (0xFCA2, 'M', u'تح'), + (0xFCA3, 'M', u'تخ'), + (0xFCA4, 'M', u'تم'), + (0xFCA5, 'M', u'ته'), + (0xFCA6, 'M', u'ثم'), + (0xFCA7, 'M', u'جح'), + (0xFCA8, 'M', u'جم'), + (0xFCA9, 'M', u'حج'), + (0xFCAA, 'M', u'حم'), + (0xFCAB, 'M', u'خج'), + (0xFCAC, 'M', u'خم'), + (0xFCAD, 'M', u'سج'), + (0xFCAE, 'M', u'سح'), + (0xFCAF, 'M', u'سخ'), + (0xFCB0, 'M', u'سم'), + (0xFCB1, 'M', u'صح'), + (0xFCB2, 'M', u'صخ'), + (0xFCB3, 'M', u'صم'), + (0xFCB4, 'M', u'ضج'), + (0xFCB5, 'M', u'ضح'), + (0xFCB6, 'M', u'ضخ'), + (0xFCB7, 'M', u'ضم'), + (0xFCB8, 'M', u'طح'), + (0xFCB9, 'M', u'ظم'), + (0xFCBA, 'M', u'عج'), + (0xFCBB, 'M', u'عم'), + (0xFCBC, 'M', u'غج'), + (0xFCBD, 'M', u'غم'), + (0xFCBE, 'M', u'فج'), + (0xFCBF, 'M', u'فح'), + (0xFCC0, 'M', u'فخ'), + (0xFCC1, 'M', u'فم'), + (0xFCC2, 'M', u'قح'), + (0xFCC3, 'M', u'قم'), + (0xFCC4, 'M', u'كج'), + (0xFCC5, 'M', u'كح'), + (0xFCC6, 'M', u'كخ'), + (0xFCC7, 'M', u'كل'), + (0xFCC8, 'M', u'كم'), + (0xFCC9, 'M', u'لج'), + (0xFCCA, 'M', u'لح'), + (0xFCCB, 'M', u'لخ'), + (0xFCCC, 'M', u'لم'), + (0xFCCD, 'M', u'له'), + (0xFCCE, 'M', u'مج'), + (0xFCCF, 'M', u'مح'), + (0xFCD0, 'M', u'مخ'), + (0xFCD1, 'M', u'مم'), + (0xFCD2, 'M', u'نج'), + (0xFCD3, 'M', u'نح'), + (0xFCD4, 'M', u'نخ'), + (0xFCD5, 'M', u'نم'), + (0xFCD6, 'M', u'نه'), + (0xFCD7, 'M', u'هج'), + (0xFCD8, 'M', u'هم'), + (0xFCD9, 'M', u'هٰ'), + (0xFCDA, 'M', u'يج'), + (0xFCDB, 'M', u'يح'), + (0xFCDC, 'M', u'يخ'), + (0xFCDD, 'M', u'يم'), + (0xFCDE, 'M', u'يه'), + (0xFCDF, 'M', u'ئم'), + (0xFCE0, 'M', u'ئه'), + (0xFCE1, 'M', u'بم'), + (0xFCE2, 'M', u'به'), + (0xFCE3, 'M', u'تم'), + ] + +def _seg_47(): + return [ + (0xFCE4, 'M', u'ته'), + (0xFCE5, 'M', u'ثم'), + (0xFCE6, 'M', u'ثه'), + (0xFCE7, 'M', u'سم'), + (0xFCE8, 'M', u'سه'), + (0xFCE9, 'M', u'شم'), + (0xFCEA, 'M', u'شه'), + (0xFCEB, 'M', u'كل'), + (0xFCEC, 'M', u'كم'), + (0xFCED, 'M', u'لم'), + (0xFCEE, 'M', u'نم'), + (0xFCEF, 'M', u'نه'), + (0xFCF0, 'M', u'يم'), + (0xFCF1, 'M', u'يه'), + (0xFCF2, 'M', u'ـَّ'), + (0xFCF3, 'M', u'ـُّ'), + (0xFCF4, 'M', u'ـِّ'), + (0xFCF5, 'M', u'طى'), + (0xFCF6, 'M', u'طي'), + (0xFCF7, 'M', u'عى'), + (0xFCF8, 'M', u'عي'), + (0xFCF9, 'M', u'غى'), + (0xFCFA, 'M', u'غي'), + (0xFCFB, 'M', u'سى'), + (0xFCFC, 'M', u'سي'), + (0xFCFD, 'M', u'شى'), + (0xFCFE, 'M', u'شي'), + (0xFCFF, 'M', u'حى'), + (0xFD00, 'M', u'حي'), + (0xFD01, 'M', u'جى'), + (0xFD02, 'M', u'جي'), + (0xFD03, 'M', u'خى'), + (0xFD04, 'M', u'خي'), + (0xFD05, 'M', u'صى'), + (0xFD06, 'M', u'صي'), + (0xFD07, 'M', u'ضى'), + (0xFD08, 'M', u'ضي'), + (0xFD09, 'M', u'شج'), + (0xFD0A, 'M', u'شح'), + (0xFD0B, 'M', u'شخ'), + (0xFD0C, 'M', u'شم'), + (0xFD0D, 'M', u'شر'), + (0xFD0E, 'M', u'سر'), + (0xFD0F, 'M', u'صر'), + (0xFD10, 'M', u'ضر'), + (0xFD11, 'M', u'طى'), + (0xFD12, 'M', u'طي'), + (0xFD13, 'M', u'عى'), + (0xFD14, 'M', u'عي'), + (0xFD15, 'M', u'غى'), + (0xFD16, 'M', u'غي'), + (0xFD17, 'M', u'سى'), + (0xFD18, 'M', u'سي'), + (0xFD19, 'M', u'شى'), + (0xFD1A, 'M', u'شي'), + (0xFD1B, 'M', u'حى'), + (0xFD1C, 'M', u'حي'), + (0xFD1D, 'M', u'جى'), + (0xFD1E, 'M', u'جي'), + (0xFD1F, 'M', u'خى'), + (0xFD20, 'M', u'خي'), + (0xFD21, 'M', u'صى'), + (0xFD22, 'M', u'صي'), + (0xFD23, 'M', u'ضى'), + (0xFD24, 'M', u'ضي'), + (0xFD25, 'M', u'شج'), + (0xFD26, 'M', u'شح'), + (0xFD27, 'M', u'شخ'), + (0xFD28, 'M', u'شم'), + (0xFD29, 'M', u'شر'), + (0xFD2A, 'M', u'سر'), + (0xFD2B, 'M', u'صر'), + (0xFD2C, 'M', u'ضر'), + (0xFD2D, 'M', u'شج'), + (0xFD2E, 'M', u'شح'), + (0xFD2F, 'M', u'شخ'), + (0xFD30, 'M', u'شم'), + (0xFD31, 'M', u'سه'), + (0xFD32, 'M', u'شه'), + (0xFD33, 'M', u'طم'), + (0xFD34, 'M', u'سج'), + (0xFD35, 'M', u'سح'), + (0xFD36, 'M', u'سخ'), + (0xFD37, 'M', u'شج'), + (0xFD38, 'M', u'شح'), + (0xFD39, 'M', u'شخ'), + (0xFD3A, 'M', u'طم'), + (0xFD3B, 'M', u'ظم'), + (0xFD3C, 'M', u'اً'), + (0xFD3E, 'V'), + (0xFD40, 'X'), + (0xFD50, 'M', u'تجم'), + (0xFD51, 'M', u'تحج'), + (0xFD53, 'M', u'تحم'), + (0xFD54, 'M', u'تخم'), + (0xFD55, 'M', u'تمج'), + (0xFD56, 'M', u'تمح'), + (0xFD57, 'M', u'تمخ'), + (0xFD58, 'M', u'جمح'), + (0xFD5A, 'M', u'حمي'), + ] + +def _seg_48(): + return [ + (0xFD5B, 'M', u'حمى'), + (0xFD5C, 'M', u'سحج'), + (0xFD5D, 'M', u'سجح'), + (0xFD5E, 'M', u'سجى'), + (0xFD5F, 'M', u'سمح'), + (0xFD61, 'M', u'سمج'), + (0xFD62, 'M', u'سمم'), + (0xFD64, 'M', u'صحح'), + (0xFD66, 'M', u'صمم'), + (0xFD67, 'M', u'شحم'), + (0xFD69, 'M', u'شجي'), + (0xFD6A, 'M', u'شمخ'), + (0xFD6C, 'M', u'شمم'), + (0xFD6E, 'M', u'ضحى'), + (0xFD6F, 'M', u'ضخم'), + (0xFD71, 'M', u'طمح'), + (0xFD73, 'M', u'طمم'), + (0xFD74, 'M', u'طمي'), + (0xFD75, 'M', u'عجم'), + (0xFD76, 'M', u'عمم'), + (0xFD78, 'M', u'عمى'), + (0xFD79, 'M', u'غمم'), + (0xFD7A, 'M', u'غمي'), + (0xFD7B, 'M', u'غمى'), + (0xFD7C, 'M', u'فخم'), + (0xFD7E, 'M', u'قمح'), + (0xFD7F, 'M', u'قمم'), + (0xFD80, 'M', u'لحم'), + (0xFD81, 'M', u'لحي'), + (0xFD82, 'M', u'لحى'), + (0xFD83, 'M', u'لجج'), + (0xFD85, 'M', u'لخم'), + (0xFD87, 'M', u'لمح'), + (0xFD89, 'M', u'محج'), + (0xFD8A, 'M', u'محم'), + (0xFD8B, 'M', u'محي'), + (0xFD8C, 'M', u'مجح'), + (0xFD8D, 'M', u'مجم'), + (0xFD8E, 'M', u'مخج'), + (0xFD8F, 'M', u'مخم'), + (0xFD90, 'X'), + (0xFD92, 'M', u'مجخ'), + (0xFD93, 'M', u'همج'), + (0xFD94, 'M', u'همم'), + (0xFD95, 'M', u'نحم'), + (0xFD96, 'M', u'نحى'), + (0xFD97, 'M', u'نجم'), + (0xFD99, 'M', u'نجى'), + (0xFD9A, 'M', u'نمي'), + (0xFD9B, 'M', u'نمى'), + (0xFD9C, 'M', u'يمم'), + (0xFD9E, 'M', u'بخي'), + (0xFD9F, 'M', u'تجي'), + (0xFDA0, 'M', u'تجى'), + (0xFDA1, 'M', u'تخي'), + (0xFDA2, 'M', u'تخى'), + (0xFDA3, 'M', u'تمي'), + (0xFDA4, 'M', u'تمى'), + (0xFDA5, 'M', u'جمي'), + (0xFDA6, 'M', u'جحى'), + (0xFDA7, 'M', u'جمى'), + (0xFDA8, 'M', u'سخى'), + (0xFDA9, 'M', u'صحي'), + (0xFDAA, 'M', u'شحي'), + (0xFDAB, 'M', u'ضحي'), + (0xFDAC, 'M', u'لجي'), + (0xFDAD, 'M', u'لمي'), + (0xFDAE, 'M', u'يحي'), + (0xFDAF, 'M', u'يجي'), + (0xFDB0, 'M', u'يمي'), + (0xFDB1, 'M', u'ممي'), + (0xFDB2, 'M', u'قمي'), + (0xFDB3, 'M', u'نحي'), + (0xFDB4, 'M', u'قمح'), + (0xFDB5, 'M', u'لحم'), + (0xFDB6, 'M', u'عمي'), + (0xFDB7, 'M', u'كمي'), + (0xFDB8, 'M', u'نجح'), + (0xFDB9, 'M', u'مخي'), + (0xFDBA, 'M', u'لجم'), + (0xFDBB, 'M', u'كمم'), + (0xFDBC, 'M', u'لجم'), + (0xFDBD, 'M', u'نجح'), + (0xFDBE, 'M', u'جحي'), + (0xFDBF, 'M', u'حجي'), + (0xFDC0, 'M', u'مجي'), + (0xFDC1, 'M', u'فمي'), + (0xFDC2, 'M', u'بحي'), + (0xFDC3, 'M', u'كمم'), + (0xFDC4, 'M', u'عجم'), + (0xFDC5, 'M', u'صمم'), + (0xFDC6, 'M', u'سخي'), + (0xFDC7, 'M', u'نجي'), + (0xFDC8, 'X'), + (0xFDF0, 'M', u'صلے'), + (0xFDF1, 'M', u'قلے'), + (0xFDF2, 'M', u'الله'), + (0xFDF3, 'M', u'اكبر'), + (0xFDF4, 'M', u'محمد'), + (0xFDF5, 'M', u'صلعم'), + ] + +def _seg_49(): + return [ + (0xFDF6, 'M', u'رسول'), + (0xFDF7, 'M', u'عليه'), + (0xFDF8, 'M', u'وسلم'), + (0xFDF9, 'M', u'صلى'), + (0xFDFA, '3', u'صلى الله عليه وسلم'), + (0xFDFB, '3', u'جل جلاله'), + (0xFDFC, 'M', u'ریال'), + (0xFDFD, 'V'), + (0xFDFE, 'X'), + (0xFE00, 'I'), + (0xFE10, '3', u','), + (0xFE11, 'M', u'、'), + (0xFE12, 'X'), + (0xFE13, '3', u':'), + (0xFE14, '3', u';'), + (0xFE15, '3', u'!'), + (0xFE16, '3', u'?'), + (0xFE17, 'M', u'〖'), + (0xFE18, 'M', u'〗'), + (0xFE19, 'X'), + (0xFE20, 'V'), + (0xFE30, 'X'), + (0xFE31, 'M', u'—'), + (0xFE32, 'M', u'–'), + (0xFE33, '3', u'_'), + (0xFE35, '3', u'('), + (0xFE36, '3', u')'), + (0xFE37, '3', u'{'), + (0xFE38, '3', u'}'), + (0xFE39, 'M', u'〔'), + (0xFE3A, 'M', u'〕'), + (0xFE3B, 'M', u'【'), + (0xFE3C, 'M', u'】'), + (0xFE3D, 'M', u'《'), + (0xFE3E, 'M', u'》'), + (0xFE3F, 'M', u'〈'), + (0xFE40, 'M', u'〉'), + (0xFE41, 'M', u'「'), + (0xFE42, 'M', u'」'), + (0xFE43, 'M', u'『'), + (0xFE44, 'M', u'』'), + (0xFE45, 'V'), + (0xFE47, '3', u'['), + (0xFE48, '3', u']'), + (0xFE49, '3', u' ̅'), + (0xFE4D, '3', u'_'), + (0xFE50, '3', u','), + (0xFE51, 'M', u'、'), + (0xFE52, 'X'), + (0xFE54, '3', u';'), + (0xFE55, '3', u':'), + (0xFE56, '3', u'?'), + (0xFE57, '3', u'!'), + (0xFE58, 'M', u'—'), + (0xFE59, '3', u'('), + (0xFE5A, '3', u')'), + (0xFE5B, '3', u'{'), + (0xFE5C, '3', u'}'), + (0xFE5D, 'M', u'〔'), + (0xFE5E, 'M', u'〕'), + (0xFE5F, '3', u'#'), + (0xFE60, '3', u'&'), + (0xFE61, '3', u'*'), + (0xFE62, '3', u'+'), + (0xFE63, 'M', u'-'), + (0xFE64, '3', u'<'), + (0xFE65, '3', u'>'), + (0xFE66, '3', u'='), + (0xFE67, 'X'), + (0xFE68, '3', u'\\'), + (0xFE69, '3', u'$'), + (0xFE6A, '3', u'%'), + (0xFE6B, '3', u'@'), + (0xFE6C, 'X'), + (0xFE70, '3', u' ً'), + (0xFE71, 'M', u'ـً'), + (0xFE72, '3', u' ٌ'), + (0xFE73, 'V'), + (0xFE74, '3', u' ٍ'), + (0xFE75, 'X'), + (0xFE76, '3', u' َ'), + (0xFE77, 'M', u'ـَ'), + (0xFE78, '3', u' ُ'), + (0xFE79, 'M', u'ـُ'), + (0xFE7A, '3', u' ِ'), + (0xFE7B, 'M', u'ـِ'), + (0xFE7C, '3', u' ّ'), + (0xFE7D, 'M', u'ـّ'), + (0xFE7E, '3', u' ْ'), + (0xFE7F, 'M', u'ـْ'), + (0xFE80, 'M', u'ء'), + (0xFE81, 'M', u'آ'), + (0xFE83, 'M', u'أ'), + (0xFE85, 'M', u'ؤ'), + (0xFE87, 'M', u'إ'), + (0xFE89, 'M', u'ئ'), + (0xFE8D, 'M', u'ا'), + (0xFE8F, 'M', u'ب'), + (0xFE93, 'M', u'ة'), + (0xFE95, 'M', u'ت'), + ] + +def _seg_50(): + return [ + (0xFE99, 'M', u'ث'), + (0xFE9D, 'M', u'ج'), + (0xFEA1, 'M', u'ح'), + (0xFEA5, 'M', u'خ'), + (0xFEA9, 'M', u'د'), + (0xFEAB, 'M', u'ذ'), + (0xFEAD, 'M', u'ر'), + (0xFEAF, 'M', u'ز'), + (0xFEB1, 'M', u'س'), + (0xFEB5, 'M', u'ش'), + (0xFEB9, 'M', u'ص'), + (0xFEBD, 'M', u'ض'), + (0xFEC1, 'M', u'ط'), + (0xFEC5, 'M', u'ظ'), + (0xFEC9, 'M', u'ع'), + (0xFECD, 'M', u'غ'), + (0xFED1, 'M', u'ف'), + (0xFED5, 'M', u'ق'), + (0xFED9, 'M', u'ك'), + (0xFEDD, 'M', u'ل'), + (0xFEE1, 'M', u'م'), + (0xFEE5, 'M', u'ن'), + (0xFEE9, 'M', u'ه'), + (0xFEED, 'M', u'و'), + (0xFEEF, 'M', u'ى'), + (0xFEF1, 'M', u'ي'), + (0xFEF5, 'M', u'لآ'), + (0xFEF7, 'M', u'لأ'), + (0xFEF9, 'M', u'لإ'), + (0xFEFB, 'M', u'لا'), + (0xFEFD, 'X'), + (0xFEFF, 'I'), + (0xFF00, 'X'), + (0xFF01, '3', u'!'), + (0xFF02, '3', u'"'), + (0xFF03, '3', u'#'), + (0xFF04, '3', u'$'), + (0xFF05, '3', u'%'), + (0xFF06, '3', u'&'), + (0xFF07, '3', u'\''), + (0xFF08, '3', u'('), + (0xFF09, '3', u')'), + (0xFF0A, '3', u'*'), + (0xFF0B, '3', u'+'), + (0xFF0C, '3', u','), + (0xFF0D, 'M', u'-'), + (0xFF0E, 'M', u'.'), + (0xFF0F, '3', u'/'), + (0xFF10, 'M', u'0'), + (0xFF11, 'M', u'1'), + (0xFF12, 'M', u'2'), + (0xFF13, 'M', u'3'), + (0xFF14, 'M', u'4'), + (0xFF15, 'M', u'5'), + (0xFF16, 'M', u'6'), + (0xFF17, 'M', u'7'), + (0xFF18, 'M', u'8'), + (0xFF19, 'M', u'9'), + (0xFF1A, '3', u':'), + (0xFF1B, '3', u';'), + (0xFF1C, '3', u'<'), + (0xFF1D, '3', u'='), + (0xFF1E, '3', u'>'), + (0xFF1F, '3', u'?'), + (0xFF20, '3', u'@'), + (0xFF21, 'M', u'a'), + (0xFF22, 'M', u'b'), + (0xFF23, 'M', u'c'), + (0xFF24, 'M', u'd'), + (0xFF25, 'M', u'e'), + (0xFF26, 'M', u'f'), + (0xFF27, 'M', u'g'), + (0xFF28, 'M', u'h'), + (0xFF29, 'M', u'i'), + (0xFF2A, 'M', u'j'), + (0xFF2B, 'M', u'k'), + (0xFF2C, 'M', u'l'), + (0xFF2D, 'M', u'm'), + (0xFF2E, 'M', u'n'), + (0xFF2F, 'M', u'o'), + (0xFF30, 'M', u'p'), + (0xFF31, 'M', u'q'), + (0xFF32, 'M', u'r'), + (0xFF33, 'M', u's'), + (0xFF34, 'M', u't'), + (0xFF35, 'M', u'u'), + (0xFF36, 'M', u'v'), + (0xFF37, 'M', u'w'), + (0xFF38, 'M', u'x'), + (0xFF39, 'M', u'y'), + (0xFF3A, 'M', u'z'), + (0xFF3B, '3', u'['), + (0xFF3C, '3', u'\\'), + (0xFF3D, '3', u']'), + (0xFF3E, '3', u'^'), + (0xFF3F, '3', u'_'), + (0xFF40, '3', u'`'), + (0xFF41, 'M', u'a'), + (0xFF42, 'M', u'b'), + (0xFF43, 'M', u'c'), + ] + +def _seg_51(): + return [ + (0xFF44, 'M', u'd'), + (0xFF45, 'M', u'e'), + (0xFF46, 'M', u'f'), + (0xFF47, 'M', u'g'), + (0xFF48, 'M', u'h'), + (0xFF49, 'M', u'i'), + (0xFF4A, 'M', u'j'), + (0xFF4B, 'M', u'k'), + (0xFF4C, 'M', u'l'), + (0xFF4D, 'M', u'm'), + (0xFF4E, 'M', u'n'), + (0xFF4F, 'M', u'o'), + (0xFF50, 'M', u'p'), + (0xFF51, 'M', u'q'), + (0xFF52, 'M', u'r'), + (0xFF53, 'M', u's'), + (0xFF54, 'M', u't'), + (0xFF55, 'M', u'u'), + (0xFF56, 'M', u'v'), + (0xFF57, 'M', u'w'), + (0xFF58, 'M', u'x'), + (0xFF59, 'M', u'y'), + (0xFF5A, 'M', u'z'), + (0xFF5B, '3', u'{'), + (0xFF5C, '3', u'|'), + (0xFF5D, '3', u'}'), + (0xFF5E, '3', u'~'), + (0xFF5F, 'M', u'⦅'), + (0xFF60, 'M', u'⦆'), + (0xFF61, 'M', u'.'), + (0xFF62, 'M', u'「'), + (0xFF63, 'M', u'」'), + (0xFF64, 'M', u'、'), + (0xFF65, 'M', u'・'), + (0xFF66, 'M', u'ヲ'), + (0xFF67, 'M', u'ァ'), + (0xFF68, 'M', u'ィ'), + (0xFF69, 'M', u'ゥ'), + (0xFF6A, 'M', u'ェ'), + (0xFF6B, 'M', u'ォ'), + (0xFF6C, 'M', u'ャ'), + (0xFF6D, 'M', u'ュ'), + (0xFF6E, 'M', u'ョ'), + (0xFF6F, 'M', u'ッ'), + (0xFF70, 'M', u'ー'), + (0xFF71, 'M', u'ア'), + (0xFF72, 'M', u'イ'), + (0xFF73, 'M', u'ウ'), + (0xFF74, 'M', u'エ'), + (0xFF75, 'M', u'オ'), + (0xFF76, 'M', u'カ'), + (0xFF77, 'M', u'キ'), + (0xFF78, 'M', u'ク'), + (0xFF79, 'M', u'ケ'), + (0xFF7A, 'M', u'コ'), + (0xFF7B, 'M', u'サ'), + (0xFF7C, 'M', u'シ'), + (0xFF7D, 'M', u'ス'), + (0xFF7E, 'M', u'セ'), + (0xFF7F, 'M', u'ソ'), + (0xFF80, 'M', u'タ'), + (0xFF81, 'M', u'チ'), + (0xFF82, 'M', u'ツ'), + (0xFF83, 'M', u'テ'), + (0xFF84, 'M', u'ト'), + (0xFF85, 'M', u'ナ'), + (0xFF86, 'M', u'ニ'), + (0xFF87, 'M', u'ヌ'), + (0xFF88, 'M', u'ネ'), + (0xFF89, 'M', u'ノ'), + (0xFF8A, 'M', u'ハ'), + (0xFF8B, 'M', u'ヒ'), + (0xFF8C, 'M', u'フ'), + (0xFF8D, 'M', u'ヘ'), + (0xFF8E, 'M', u'ホ'), + (0xFF8F, 'M', u'マ'), + (0xFF90, 'M', u'ミ'), + (0xFF91, 'M', u'ム'), + (0xFF92, 'M', u'メ'), + (0xFF93, 'M', u'モ'), + (0xFF94, 'M', u'ヤ'), + (0xFF95, 'M', u'ユ'), + (0xFF96, 'M', u'ヨ'), + (0xFF97, 'M', u'ラ'), + (0xFF98, 'M', u'リ'), + (0xFF99, 'M', u'ル'), + (0xFF9A, 'M', u'レ'), + (0xFF9B, 'M', u'ロ'), + (0xFF9C, 'M', u'ワ'), + (0xFF9D, 'M', u'ン'), + (0xFF9E, 'M', u'゙'), + (0xFF9F, 'M', u'゚'), + (0xFFA0, 'X'), + (0xFFA1, 'M', u'ᄀ'), + (0xFFA2, 'M', u'ᄁ'), + (0xFFA3, 'M', u'ᆪ'), + (0xFFA4, 'M', u'ᄂ'), + (0xFFA5, 'M', u'ᆬ'), + (0xFFA6, 'M', u'ᆭ'), + (0xFFA7, 'M', u'ᄃ'), + ] + +def _seg_52(): + return [ + (0xFFA8, 'M', u'ᄄ'), + (0xFFA9, 'M', u'ᄅ'), + (0xFFAA, 'M', u'ᆰ'), + (0xFFAB, 'M', u'ᆱ'), + (0xFFAC, 'M', u'ᆲ'), + (0xFFAD, 'M', u'ᆳ'), + (0xFFAE, 'M', u'ᆴ'), + (0xFFAF, 'M', u'ᆵ'), + (0xFFB0, 'M', u'ᄚ'), + (0xFFB1, 'M', u'ᄆ'), + (0xFFB2, 'M', u'ᄇ'), + (0xFFB3, 'M', u'ᄈ'), + (0xFFB4, 'M', u'ᄡ'), + (0xFFB5, 'M', u'ᄉ'), + (0xFFB6, 'M', u'ᄊ'), + (0xFFB7, 'M', u'ᄋ'), + (0xFFB8, 'M', u'ᄌ'), + (0xFFB9, 'M', u'ᄍ'), + (0xFFBA, 'M', u'ᄎ'), + (0xFFBB, 'M', u'ᄏ'), + (0xFFBC, 'M', u'ᄐ'), + (0xFFBD, 'M', u'ᄑ'), + (0xFFBE, 'M', u'ᄒ'), + (0xFFBF, 'X'), + (0xFFC2, 'M', u'ᅡ'), + (0xFFC3, 'M', u'ᅢ'), + (0xFFC4, 'M', u'ᅣ'), + (0xFFC5, 'M', u'ᅤ'), + (0xFFC6, 'M', u'ᅥ'), + (0xFFC7, 'M', u'ᅦ'), + (0xFFC8, 'X'), + (0xFFCA, 'M', u'ᅧ'), + (0xFFCB, 'M', u'ᅨ'), + (0xFFCC, 'M', u'ᅩ'), + (0xFFCD, 'M', u'ᅪ'), + (0xFFCE, 'M', u'ᅫ'), + (0xFFCF, 'M', u'ᅬ'), + (0xFFD0, 'X'), + (0xFFD2, 'M', u'ᅭ'), + (0xFFD3, 'M', u'ᅮ'), + (0xFFD4, 'M', u'ᅯ'), + (0xFFD5, 'M', u'ᅰ'), + (0xFFD6, 'M', u'ᅱ'), + (0xFFD7, 'M', u'ᅲ'), + (0xFFD8, 'X'), + (0xFFDA, 'M', u'ᅳ'), + (0xFFDB, 'M', u'ᅴ'), + (0xFFDC, 'M', u'ᅵ'), + (0xFFDD, 'X'), + (0xFFE0, 'M', u'¢'), + (0xFFE1, 'M', u'£'), + (0xFFE2, 'M', u'¬'), + (0xFFE3, '3', u' ̄'), + (0xFFE4, 'M', u'¦'), + (0xFFE5, 'M', u'¥'), + (0xFFE6, 'M', u'₩'), + (0xFFE7, 'X'), + (0xFFE8, 'M', u'│'), + (0xFFE9, 'M', u'←'), + (0xFFEA, 'M', u'↑'), + (0xFFEB, 'M', u'→'), + (0xFFEC, 'M', u'↓'), + (0xFFED, 'M', u'■'), + (0xFFEE, 'M', u'○'), + (0xFFEF, 'X'), + (0x10000, 'V'), + (0x1000C, 'X'), + (0x1000D, 'V'), + (0x10027, 'X'), + (0x10028, 'V'), + (0x1003B, 'X'), + (0x1003C, 'V'), + (0x1003E, 'X'), + (0x1003F, 'V'), + (0x1004E, 'X'), + (0x10050, 'V'), + (0x1005E, 'X'), + (0x10080, 'V'), + (0x100FB, 'X'), + (0x10100, 'V'), + (0x10103, 'X'), + (0x10107, 'V'), + (0x10134, 'X'), + (0x10137, 'V'), + (0x1018F, 'X'), + (0x10190, 'V'), + (0x1019C, 'X'), + (0x101A0, 'V'), + (0x101A1, 'X'), + (0x101D0, 'V'), + (0x101FE, 'X'), + (0x10280, 'V'), + (0x1029D, 'X'), + (0x102A0, 'V'), + (0x102D1, 'X'), + (0x102E0, 'V'), + (0x102FC, 'X'), + (0x10300, 'V'), + (0x10324, 'X'), + (0x1032D, 'V'), + ] + +def _seg_53(): + return [ + (0x1034B, 'X'), + (0x10350, 'V'), + (0x1037B, 'X'), + (0x10380, 'V'), + (0x1039E, 'X'), + (0x1039F, 'V'), + (0x103C4, 'X'), + (0x103C8, 'V'), + (0x103D6, 'X'), + (0x10400, 'M', u'𐐨'), + (0x10401, 'M', u'𐐩'), + (0x10402, 'M', u'𐐪'), + (0x10403, 'M', u'𐐫'), + (0x10404, 'M', u'𐐬'), + (0x10405, 'M', u'𐐭'), + (0x10406, 'M', u'𐐮'), + (0x10407, 'M', u'𐐯'), + (0x10408, 'M', u'𐐰'), + (0x10409, 'M', u'𐐱'), + (0x1040A, 'M', u'𐐲'), + (0x1040B, 'M', u'𐐳'), + (0x1040C, 'M', u'𐐴'), + (0x1040D, 'M', u'𐐵'), + (0x1040E, 'M', u'𐐶'), + (0x1040F, 'M', u'𐐷'), + (0x10410, 'M', u'𐐸'), + (0x10411, 'M', u'𐐹'), + (0x10412, 'M', u'𐐺'), + (0x10413, 'M', u'𐐻'), + (0x10414, 'M', u'𐐼'), + (0x10415, 'M', u'𐐽'), + (0x10416, 'M', u'𐐾'), + (0x10417, 'M', u'𐐿'), + (0x10418, 'M', u'𐑀'), + (0x10419, 'M', u'𐑁'), + (0x1041A, 'M', u'𐑂'), + (0x1041B, 'M', u'𐑃'), + (0x1041C, 'M', u'𐑄'), + (0x1041D, 'M', u'𐑅'), + (0x1041E, 'M', u'𐑆'), + (0x1041F, 'M', u'𐑇'), + (0x10420, 'M', u'𐑈'), + (0x10421, 'M', u'𐑉'), + (0x10422, 'M', u'𐑊'), + (0x10423, 'M', u'𐑋'), + (0x10424, 'M', u'𐑌'), + (0x10425, 'M', u'𐑍'), + (0x10426, 'M', u'𐑎'), + (0x10427, 'M', u'𐑏'), + (0x10428, 'V'), + (0x1049E, 'X'), + (0x104A0, 'V'), + (0x104AA, 'X'), + (0x104B0, 'M', u'𐓘'), + (0x104B1, 'M', u'𐓙'), + (0x104B2, 'M', u'𐓚'), + (0x104B3, 'M', u'𐓛'), + (0x104B4, 'M', u'𐓜'), + (0x104B5, 'M', u'𐓝'), + (0x104B6, 'M', u'𐓞'), + (0x104B7, 'M', u'𐓟'), + (0x104B8, 'M', u'𐓠'), + (0x104B9, 'M', u'𐓡'), + (0x104BA, 'M', u'𐓢'), + (0x104BB, 'M', u'𐓣'), + (0x104BC, 'M', u'𐓤'), + (0x104BD, 'M', u'𐓥'), + (0x104BE, 'M', u'𐓦'), + (0x104BF, 'M', u'𐓧'), + (0x104C0, 'M', u'𐓨'), + (0x104C1, 'M', u'𐓩'), + (0x104C2, 'M', u'𐓪'), + (0x104C3, 'M', u'𐓫'), + (0x104C4, 'M', u'𐓬'), + (0x104C5, 'M', u'𐓭'), + (0x104C6, 'M', u'𐓮'), + (0x104C7, 'M', u'𐓯'), + (0x104C8, 'M', u'𐓰'), + (0x104C9, 'M', u'𐓱'), + (0x104CA, 'M', u'𐓲'), + (0x104CB, 'M', u'𐓳'), + (0x104CC, 'M', u'𐓴'), + (0x104CD, 'M', u'𐓵'), + (0x104CE, 'M', u'𐓶'), + (0x104CF, 'M', u'𐓷'), + (0x104D0, 'M', u'𐓸'), + (0x104D1, 'M', u'𐓹'), + (0x104D2, 'M', u'𐓺'), + (0x104D3, 'M', u'𐓻'), + (0x104D4, 'X'), + (0x104D8, 'V'), + (0x104FC, 'X'), + (0x10500, 'V'), + (0x10528, 'X'), + (0x10530, 'V'), + (0x10564, 'X'), + (0x1056F, 'V'), + (0x10570, 'X'), + (0x10600, 'V'), + (0x10737, 'X'), + ] + +def _seg_54(): + return [ + (0x10740, 'V'), + (0x10756, 'X'), + (0x10760, 'V'), + (0x10768, 'X'), + (0x10800, 'V'), + (0x10806, 'X'), + (0x10808, 'V'), + (0x10809, 'X'), + (0x1080A, 'V'), + (0x10836, 'X'), + (0x10837, 'V'), + (0x10839, 'X'), + (0x1083C, 'V'), + (0x1083D, 'X'), + (0x1083F, 'V'), + (0x10856, 'X'), + (0x10857, 'V'), + (0x1089F, 'X'), + (0x108A7, 'V'), + (0x108B0, 'X'), + (0x108E0, 'V'), + (0x108F3, 'X'), + (0x108F4, 'V'), + (0x108F6, 'X'), + (0x108FB, 'V'), + (0x1091C, 'X'), + (0x1091F, 'V'), + (0x1093A, 'X'), + (0x1093F, 'V'), + (0x10940, 'X'), + (0x10980, 'V'), + (0x109B8, 'X'), + (0x109BC, 'V'), + (0x109D0, 'X'), + (0x109D2, 'V'), + (0x10A04, 'X'), + (0x10A05, 'V'), + (0x10A07, 'X'), + (0x10A0C, 'V'), + (0x10A14, 'X'), + (0x10A15, 'V'), + (0x10A18, 'X'), + (0x10A19, 'V'), + (0x10A34, 'X'), + (0x10A38, 'V'), + (0x10A3B, 'X'), + (0x10A3F, 'V'), + (0x10A48, 'X'), + (0x10A50, 'V'), + (0x10A59, 'X'), + (0x10A60, 'V'), + (0x10AA0, 'X'), + (0x10AC0, 'V'), + (0x10AE7, 'X'), + (0x10AEB, 'V'), + (0x10AF7, 'X'), + (0x10B00, 'V'), + (0x10B36, 'X'), + (0x10B39, 'V'), + (0x10B56, 'X'), + (0x10B58, 'V'), + (0x10B73, 'X'), + (0x10B78, 'V'), + (0x10B92, 'X'), + (0x10B99, 'V'), + (0x10B9D, 'X'), + (0x10BA9, 'V'), + (0x10BB0, 'X'), + (0x10C00, 'V'), + (0x10C49, 'X'), + (0x10C80, 'M', u'𐳀'), + (0x10C81, 'M', u'𐳁'), + (0x10C82, 'M', u'𐳂'), + (0x10C83, 'M', u'𐳃'), + (0x10C84, 'M', u'𐳄'), + (0x10C85, 'M', u'𐳅'), + (0x10C86, 'M', u'𐳆'), + (0x10C87, 'M', u'𐳇'), + (0x10C88, 'M', u'𐳈'), + (0x10C89, 'M', u'𐳉'), + (0x10C8A, 'M', u'𐳊'), + (0x10C8B, 'M', u'𐳋'), + (0x10C8C, 'M', u'𐳌'), + (0x10C8D, 'M', u'𐳍'), + (0x10C8E, 'M', u'𐳎'), + (0x10C8F, 'M', u'𐳏'), + (0x10C90, 'M', u'𐳐'), + (0x10C91, 'M', u'𐳑'), + (0x10C92, 'M', u'𐳒'), + (0x10C93, 'M', u'𐳓'), + (0x10C94, 'M', u'𐳔'), + (0x10C95, 'M', u'𐳕'), + (0x10C96, 'M', u'𐳖'), + (0x10C97, 'M', u'𐳗'), + (0x10C98, 'M', u'𐳘'), + (0x10C99, 'M', u'𐳙'), + (0x10C9A, 'M', u'𐳚'), + (0x10C9B, 'M', u'𐳛'), + (0x10C9C, 'M', u'𐳜'), + (0x10C9D, 'M', u'𐳝'), + ] + +def _seg_55(): + return [ + (0x10C9E, 'M', u'𐳞'), + (0x10C9F, 'M', u'𐳟'), + (0x10CA0, 'M', u'𐳠'), + (0x10CA1, 'M', u'𐳡'), + (0x10CA2, 'M', u'𐳢'), + (0x10CA3, 'M', u'𐳣'), + (0x10CA4, 'M', u'𐳤'), + (0x10CA5, 'M', u'𐳥'), + (0x10CA6, 'M', u'𐳦'), + (0x10CA7, 'M', u'𐳧'), + (0x10CA8, 'M', u'𐳨'), + (0x10CA9, 'M', u'𐳩'), + (0x10CAA, 'M', u'𐳪'), + (0x10CAB, 'M', u'𐳫'), + (0x10CAC, 'M', u'𐳬'), + (0x10CAD, 'M', u'𐳭'), + (0x10CAE, 'M', u'𐳮'), + (0x10CAF, 'M', u'𐳯'), + (0x10CB0, 'M', u'𐳰'), + (0x10CB1, 'M', u'𐳱'), + (0x10CB2, 'M', u'𐳲'), + (0x10CB3, 'X'), + (0x10CC0, 'V'), + (0x10CF3, 'X'), + (0x10CFA, 'V'), + (0x10D00, 'X'), + (0x10E60, 'V'), + (0x10E7F, 'X'), + (0x11000, 'V'), + (0x1104E, 'X'), + (0x11052, 'V'), + (0x11070, 'X'), + (0x1107F, 'V'), + (0x110BD, 'X'), + (0x110BE, 'V'), + (0x110C2, 'X'), + (0x110D0, 'V'), + (0x110E9, 'X'), + (0x110F0, 'V'), + (0x110FA, 'X'), + (0x11100, 'V'), + (0x11135, 'X'), + (0x11136, 'V'), + (0x11144, 'X'), + (0x11150, 'V'), + (0x11177, 'X'), + (0x11180, 'V'), + (0x111CE, 'X'), + (0x111D0, 'V'), + (0x111E0, 'X'), + (0x111E1, 'V'), + (0x111F5, 'X'), + (0x11200, 'V'), + (0x11212, 'X'), + (0x11213, 'V'), + (0x1123F, 'X'), + (0x11280, 'V'), + (0x11287, 'X'), + (0x11288, 'V'), + (0x11289, 'X'), + (0x1128A, 'V'), + (0x1128E, 'X'), + (0x1128F, 'V'), + (0x1129E, 'X'), + (0x1129F, 'V'), + (0x112AA, 'X'), + (0x112B0, 'V'), + (0x112EB, 'X'), + (0x112F0, 'V'), + (0x112FA, 'X'), + (0x11300, 'V'), + (0x11304, 'X'), + (0x11305, 'V'), + (0x1130D, 'X'), + (0x1130F, 'V'), + (0x11311, 'X'), + (0x11313, 'V'), + (0x11329, 'X'), + (0x1132A, 'V'), + (0x11331, 'X'), + (0x11332, 'V'), + (0x11334, 'X'), + (0x11335, 'V'), + (0x1133A, 'X'), + (0x1133C, 'V'), + (0x11345, 'X'), + (0x11347, 'V'), + (0x11349, 'X'), + (0x1134B, 'V'), + (0x1134E, 'X'), + (0x11350, 'V'), + (0x11351, 'X'), + (0x11357, 'V'), + (0x11358, 'X'), + (0x1135D, 'V'), + (0x11364, 'X'), + (0x11366, 'V'), + (0x1136D, 'X'), + (0x11370, 'V'), + (0x11375, 'X'), + ] + +def _seg_56(): + return [ + (0x11400, 'V'), + (0x1145A, 'X'), + (0x1145B, 'V'), + (0x1145C, 'X'), + (0x1145D, 'V'), + (0x1145E, 'X'), + (0x11480, 'V'), + (0x114C8, 'X'), + (0x114D0, 'V'), + (0x114DA, 'X'), + (0x11580, 'V'), + (0x115B6, 'X'), + (0x115B8, 'V'), + (0x115DE, 'X'), + (0x11600, 'V'), + (0x11645, 'X'), + (0x11650, 'V'), + (0x1165A, 'X'), + (0x11660, 'V'), + (0x1166D, 'X'), + (0x11680, 'V'), + (0x116B8, 'X'), + (0x116C0, 'V'), + (0x116CA, 'X'), + (0x11700, 'V'), + (0x1171A, 'X'), + (0x1171D, 'V'), + (0x1172C, 'X'), + (0x11730, 'V'), + (0x11740, 'X'), + (0x118A0, 'M', u'𑣀'), + (0x118A1, 'M', u'𑣁'), + (0x118A2, 'M', u'𑣂'), + (0x118A3, 'M', u'𑣃'), + (0x118A4, 'M', u'𑣄'), + (0x118A5, 'M', u'𑣅'), + (0x118A6, 'M', u'𑣆'), + (0x118A7, 'M', u'𑣇'), + (0x118A8, 'M', u'𑣈'), + (0x118A9, 'M', u'𑣉'), + (0x118AA, 'M', u'𑣊'), + (0x118AB, 'M', u'𑣋'), + (0x118AC, 'M', u'𑣌'), + (0x118AD, 'M', u'𑣍'), + (0x118AE, 'M', u'𑣎'), + (0x118AF, 'M', u'𑣏'), + (0x118B0, 'M', u'𑣐'), + (0x118B1, 'M', u'𑣑'), + (0x118B2, 'M', u'𑣒'), + (0x118B3, 'M', u'𑣓'), + (0x118B4, 'M', u'𑣔'), + (0x118B5, 'M', u'𑣕'), + (0x118B6, 'M', u'𑣖'), + (0x118B7, 'M', u'𑣗'), + (0x118B8, 'M', u'𑣘'), + (0x118B9, 'M', u'𑣙'), + (0x118BA, 'M', u'𑣚'), + (0x118BB, 'M', u'𑣛'), + (0x118BC, 'M', u'𑣜'), + (0x118BD, 'M', u'𑣝'), + (0x118BE, 'M', u'𑣞'), + (0x118BF, 'M', u'𑣟'), + (0x118C0, 'V'), + (0x118F3, 'X'), + (0x118FF, 'V'), + (0x11900, 'X'), + (0x11A00, 'V'), + (0x11A48, 'X'), + (0x11A50, 'V'), + (0x11A84, 'X'), + (0x11A86, 'V'), + (0x11A9D, 'X'), + (0x11A9E, 'V'), + (0x11AA3, 'X'), + (0x11AC0, 'V'), + (0x11AF9, 'X'), + (0x11C00, 'V'), + (0x11C09, 'X'), + (0x11C0A, 'V'), + (0x11C37, 'X'), + (0x11C38, 'V'), + (0x11C46, 'X'), + (0x11C50, 'V'), + (0x11C6D, 'X'), + (0x11C70, 'V'), + (0x11C90, 'X'), + (0x11C92, 'V'), + (0x11CA8, 'X'), + (0x11CA9, 'V'), + (0x11CB7, 'X'), + (0x11D00, 'V'), + (0x11D07, 'X'), + (0x11D08, 'V'), + (0x11D0A, 'X'), + (0x11D0B, 'V'), + (0x11D37, 'X'), + (0x11D3A, 'V'), + (0x11D3B, 'X'), + (0x11D3C, 'V'), + (0x11D3E, 'X'), + ] + +def _seg_57(): + return [ + (0x11D3F, 'V'), + (0x11D48, 'X'), + (0x11D50, 'V'), + (0x11D5A, 'X'), + (0x12000, 'V'), + (0x1239A, 'X'), + (0x12400, 'V'), + (0x1246F, 'X'), + (0x12470, 'V'), + (0x12475, 'X'), + (0x12480, 'V'), + (0x12544, 'X'), + (0x13000, 'V'), + (0x1342F, 'X'), + (0x14400, 'V'), + (0x14647, 'X'), + (0x16800, 'V'), + (0x16A39, 'X'), + (0x16A40, 'V'), + (0x16A5F, 'X'), + (0x16A60, 'V'), + (0x16A6A, 'X'), + (0x16A6E, 'V'), + (0x16A70, 'X'), + (0x16AD0, 'V'), + (0x16AEE, 'X'), + (0x16AF0, 'V'), + (0x16AF6, 'X'), + (0x16B00, 'V'), + (0x16B46, 'X'), + (0x16B50, 'V'), + (0x16B5A, 'X'), + (0x16B5B, 'V'), + (0x16B62, 'X'), + (0x16B63, 'V'), + (0x16B78, 'X'), + (0x16B7D, 'V'), + (0x16B90, 'X'), + (0x16F00, 'V'), + (0x16F45, 'X'), + (0x16F50, 'V'), + (0x16F7F, 'X'), + (0x16F8F, 'V'), + (0x16FA0, 'X'), + (0x16FE0, 'V'), + (0x16FE2, 'X'), + (0x17000, 'V'), + (0x187ED, 'X'), + (0x18800, 'V'), + (0x18AF3, 'X'), + (0x1B000, 'V'), + (0x1B11F, 'X'), + (0x1B170, 'V'), + (0x1B2FC, 'X'), + (0x1BC00, 'V'), + (0x1BC6B, 'X'), + (0x1BC70, 'V'), + (0x1BC7D, 'X'), + (0x1BC80, 'V'), + (0x1BC89, 'X'), + (0x1BC90, 'V'), + (0x1BC9A, 'X'), + (0x1BC9C, 'V'), + (0x1BCA0, 'I'), + (0x1BCA4, 'X'), + (0x1D000, 'V'), + (0x1D0F6, 'X'), + (0x1D100, 'V'), + (0x1D127, 'X'), + (0x1D129, 'V'), + (0x1D15E, 'M', u'𝅗𝅥'), + (0x1D15F, 'M', u'𝅘𝅥'), + (0x1D160, 'M', u'𝅘𝅥𝅮'), + (0x1D161, 'M', u'𝅘𝅥𝅯'), + (0x1D162, 'M', u'𝅘𝅥𝅰'), + (0x1D163, 'M', u'𝅘𝅥𝅱'), + (0x1D164, 'M', u'𝅘𝅥𝅲'), + (0x1D165, 'V'), + (0x1D173, 'X'), + (0x1D17B, 'V'), + (0x1D1BB, 'M', u'𝆹𝅥'), + (0x1D1BC, 'M', u'𝆺𝅥'), + (0x1D1BD, 'M', u'𝆹𝅥𝅮'), + (0x1D1BE, 'M', u'𝆺𝅥𝅮'), + (0x1D1BF, 'M', u'𝆹𝅥𝅯'), + (0x1D1C0, 'M', u'𝆺𝅥𝅯'), + (0x1D1C1, 'V'), + (0x1D1E9, 'X'), + (0x1D200, 'V'), + (0x1D246, 'X'), + (0x1D300, 'V'), + (0x1D357, 'X'), + (0x1D360, 'V'), + (0x1D372, 'X'), + (0x1D400, 'M', u'a'), + (0x1D401, 'M', u'b'), + (0x1D402, 'M', u'c'), + (0x1D403, 'M', u'd'), + (0x1D404, 'M', u'e'), + (0x1D405, 'M', u'f'), + ] + +def _seg_58(): + return [ + (0x1D406, 'M', u'g'), + (0x1D407, 'M', u'h'), + (0x1D408, 'M', u'i'), + (0x1D409, 'M', u'j'), + (0x1D40A, 'M', u'k'), + (0x1D40B, 'M', u'l'), + (0x1D40C, 'M', u'm'), + (0x1D40D, 'M', u'n'), + (0x1D40E, 'M', u'o'), + (0x1D40F, 'M', u'p'), + (0x1D410, 'M', u'q'), + (0x1D411, 'M', u'r'), + (0x1D412, 'M', u's'), + (0x1D413, 'M', u't'), + (0x1D414, 'M', u'u'), + (0x1D415, 'M', u'v'), + (0x1D416, 'M', u'w'), + (0x1D417, 'M', u'x'), + (0x1D418, 'M', u'y'), + (0x1D419, 'M', u'z'), + (0x1D41A, 'M', u'a'), + (0x1D41B, 'M', u'b'), + (0x1D41C, 'M', u'c'), + (0x1D41D, 'M', u'd'), + (0x1D41E, 'M', u'e'), + (0x1D41F, 'M', u'f'), + (0x1D420, 'M', u'g'), + (0x1D421, 'M', u'h'), + (0x1D422, 'M', u'i'), + (0x1D423, 'M', u'j'), + (0x1D424, 'M', u'k'), + (0x1D425, 'M', u'l'), + (0x1D426, 'M', u'm'), + (0x1D427, 'M', u'n'), + (0x1D428, 'M', u'o'), + (0x1D429, 'M', u'p'), + (0x1D42A, 'M', u'q'), + (0x1D42B, 'M', u'r'), + (0x1D42C, 'M', u's'), + (0x1D42D, 'M', u't'), + (0x1D42E, 'M', u'u'), + (0x1D42F, 'M', u'v'), + (0x1D430, 'M', u'w'), + (0x1D431, 'M', u'x'), + (0x1D432, 'M', u'y'), + (0x1D433, 'M', u'z'), + (0x1D434, 'M', u'a'), + (0x1D435, 'M', u'b'), + (0x1D436, 'M', u'c'), + (0x1D437, 'M', u'd'), + (0x1D438, 'M', u'e'), + (0x1D439, 'M', u'f'), + (0x1D43A, 'M', u'g'), + (0x1D43B, 'M', u'h'), + (0x1D43C, 'M', u'i'), + (0x1D43D, 'M', u'j'), + (0x1D43E, 'M', u'k'), + (0x1D43F, 'M', u'l'), + (0x1D440, 'M', u'm'), + (0x1D441, 'M', u'n'), + (0x1D442, 'M', u'o'), + (0x1D443, 'M', u'p'), + (0x1D444, 'M', u'q'), + (0x1D445, 'M', u'r'), + (0x1D446, 'M', u's'), + (0x1D447, 'M', u't'), + (0x1D448, 'M', u'u'), + (0x1D449, 'M', u'v'), + (0x1D44A, 'M', u'w'), + (0x1D44B, 'M', u'x'), + (0x1D44C, 'M', u'y'), + (0x1D44D, 'M', u'z'), + (0x1D44E, 'M', u'a'), + (0x1D44F, 'M', u'b'), + (0x1D450, 'M', u'c'), + (0x1D451, 'M', u'd'), + (0x1D452, 'M', u'e'), + (0x1D453, 'M', u'f'), + (0x1D454, 'M', u'g'), + (0x1D455, 'X'), + (0x1D456, 'M', u'i'), + (0x1D457, 'M', u'j'), + (0x1D458, 'M', u'k'), + (0x1D459, 'M', u'l'), + (0x1D45A, 'M', u'm'), + (0x1D45B, 'M', u'n'), + (0x1D45C, 'M', u'o'), + (0x1D45D, 'M', u'p'), + (0x1D45E, 'M', u'q'), + (0x1D45F, 'M', u'r'), + (0x1D460, 'M', u's'), + (0x1D461, 'M', u't'), + (0x1D462, 'M', u'u'), + (0x1D463, 'M', u'v'), + (0x1D464, 'M', u'w'), + (0x1D465, 'M', u'x'), + (0x1D466, 'M', u'y'), + (0x1D467, 'M', u'z'), + (0x1D468, 'M', u'a'), + (0x1D469, 'M', u'b'), + ] + +def _seg_59(): + return [ + (0x1D46A, 'M', u'c'), + (0x1D46B, 'M', u'd'), + (0x1D46C, 'M', u'e'), + (0x1D46D, 'M', u'f'), + (0x1D46E, 'M', u'g'), + (0x1D46F, 'M', u'h'), + (0x1D470, 'M', u'i'), + (0x1D471, 'M', u'j'), + (0x1D472, 'M', u'k'), + (0x1D473, 'M', u'l'), + (0x1D474, 'M', u'm'), + (0x1D475, 'M', u'n'), + (0x1D476, 'M', u'o'), + (0x1D477, 'M', u'p'), + (0x1D478, 'M', u'q'), + (0x1D479, 'M', u'r'), + (0x1D47A, 'M', u's'), + (0x1D47B, 'M', u't'), + (0x1D47C, 'M', u'u'), + (0x1D47D, 'M', u'v'), + (0x1D47E, 'M', u'w'), + (0x1D47F, 'M', u'x'), + (0x1D480, 'M', u'y'), + (0x1D481, 'M', u'z'), + (0x1D482, 'M', u'a'), + (0x1D483, 'M', u'b'), + (0x1D484, 'M', u'c'), + (0x1D485, 'M', u'd'), + (0x1D486, 'M', u'e'), + (0x1D487, 'M', u'f'), + (0x1D488, 'M', u'g'), + (0x1D489, 'M', u'h'), + (0x1D48A, 'M', u'i'), + (0x1D48B, 'M', u'j'), + (0x1D48C, 'M', u'k'), + (0x1D48D, 'M', u'l'), + (0x1D48E, 'M', u'm'), + (0x1D48F, 'M', u'n'), + (0x1D490, 'M', u'o'), + (0x1D491, 'M', u'p'), + (0x1D492, 'M', u'q'), + (0x1D493, 'M', u'r'), + (0x1D494, 'M', u's'), + (0x1D495, 'M', u't'), + (0x1D496, 'M', u'u'), + (0x1D497, 'M', u'v'), + (0x1D498, 'M', u'w'), + (0x1D499, 'M', u'x'), + (0x1D49A, 'M', u'y'), + (0x1D49B, 'M', u'z'), + (0x1D49C, 'M', u'a'), + (0x1D49D, 'X'), + (0x1D49E, 'M', u'c'), + (0x1D49F, 'M', u'd'), + (0x1D4A0, 'X'), + (0x1D4A2, 'M', u'g'), + (0x1D4A3, 'X'), + (0x1D4A5, 'M', u'j'), + (0x1D4A6, 'M', u'k'), + (0x1D4A7, 'X'), + (0x1D4A9, 'M', u'n'), + (0x1D4AA, 'M', u'o'), + (0x1D4AB, 'M', u'p'), + (0x1D4AC, 'M', u'q'), + (0x1D4AD, 'X'), + (0x1D4AE, 'M', u's'), + (0x1D4AF, 'M', u't'), + (0x1D4B0, 'M', u'u'), + (0x1D4B1, 'M', u'v'), + (0x1D4B2, 'M', u'w'), + (0x1D4B3, 'M', u'x'), + (0x1D4B4, 'M', u'y'), + (0x1D4B5, 'M', u'z'), + (0x1D4B6, 'M', u'a'), + (0x1D4B7, 'M', u'b'), + (0x1D4B8, 'M', u'c'), + (0x1D4B9, 'M', u'd'), + (0x1D4BA, 'X'), + (0x1D4BB, 'M', u'f'), + (0x1D4BC, 'X'), + (0x1D4BD, 'M', u'h'), + (0x1D4BE, 'M', u'i'), + (0x1D4BF, 'M', u'j'), + (0x1D4C0, 'M', u'k'), + (0x1D4C1, 'M', u'l'), + (0x1D4C2, 'M', u'm'), + (0x1D4C3, 'M', u'n'), + (0x1D4C4, 'X'), + (0x1D4C5, 'M', u'p'), + (0x1D4C6, 'M', u'q'), + (0x1D4C7, 'M', u'r'), + (0x1D4C8, 'M', u's'), + (0x1D4C9, 'M', u't'), + (0x1D4CA, 'M', u'u'), + (0x1D4CB, 'M', u'v'), + (0x1D4CC, 'M', u'w'), + (0x1D4CD, 'M', u'x'), + (0x1D4CE, 'M', u'y'), + (0x1D4CF, 'M', u'z'), + (0x1D4D0, 'M', u'a'), + ] + +def _seg_60(): + return [ + (0x1D4D1, 'M', u'b'), + (0x1D4D2, 'M', u'c'), + (0x1D4D3, 'M', u'd'), + (0x1D4D4, 'M', u'e'), + (0x1D4D5, 'M', u'f'), + (0x1D4D6, 'M', u'g'), + (0x1D4D7, 'M', u'h'), + (0x1D4D8, 'M', u'i'), + (0x1D4D9, 'M', u'j'), + (0x1D4DA, 'M', u'k'), + (0x1D4DB, 'M', u'l'), + (0x1D4DC, 'M', u'm'), + (0x1D4DD, 'M', u'n'), + (0x1D4DE, 'M', u'o'), + (0x1D4DF, 'M', u'p'), + (0x1D4E0, 'M', u'q'), + (0x1D4E1, 'M', u'r'), + (0x1D4E2, 'M', u's'), + (0x1D4E3, 'M', u't'), + (0x1D4E4, 'M', u'u'), + (0x1D4E5, 'M', u'v'), + (0x1D4E6, 'M', u'w'), + (0x1D4E7, 'M', u'x'), + (0x1D4E8, 'M', u'y'), + (0x1D4E9, 'M', u'z'), + (0x1D4EA, 'M', u'a'), + (0x1D4EB, 'M', u'b'), + (0x1D4EC, 'M', u'c'), + (0x1D4ED, 'M', u'd'), + (0x1D4EE, 'M', u'e'), + (0x1D4EF, 'M', u'f'), + (0x1D4F0, 'M', u'g'), + (0x1D4F1, 'M', u'h'), + (0x1D4F2, 'M', u'i'), + (0x1D4F3, 'M', u'j'), + (0x1D4F4, 'M', u'k'), + (0x1D4F5, 'M', u'l'), + (0x1D4F6, 'M', u'm'), + (0x1D4F7, 'M', u'n'), + (0x1D4F8, 'M', u'o'), + (0x1D4F9, 'M', u'p'), + (0x1D4FA, 'M', u'q'), + (0x1D4FB, 'M', u'r'), + (0x1D4FC, 'M', u's'), + (0x1D4FD, 'M', u't'), + (0x1D4FE, 'M', u'u'), + (0x1D4FF, 'M', u'v'), + (0x1D500, 'M', u'w'), + (0x1D501, 'M', u'x'), + (0x1D502, 'M', u'y'), + (0x1D503, 'M', u'z'), + (0x1D504, 'M', u'a'), + (0x1D505, 'M', u'b'), + (0x1D506, 'X'), + (0x1D507, 'M', u'd'), + (0x1D508, 'M', u'e'), + (0x1D509, 'M', u'f'), + (0x1D50A, 'M', u'g'), + (0x1D50B, 'X'), + (0x1D50D, 'M', u'j'), + (0x1D50E, 'M', u'k'), + (0x1D50F, 'M', u'l'), + (0x1D510, 'M', u'm'), + (0x1D511, 'M', u'n'), + (0x1D512, 'M', u'o'), + (0x1D513, 'M', u'p'), + (0x1D514, 'M', u'q'), + (0x1D515, 'X'), + (0x1D516, 'M', u's'), + (0x1D517, 'M', u't'), + (0x1D518, 'M', u'u'), + (0x1D519, 'M', u'v'), + (0x1D51A, 'M', u'w'), + (0x1D51B, 'M', u'x'), + (0x1D51C, 'M', u'y'), + (0x1D51D, 'X'), + (0x1D51E, 'M', u'a'), + (0x1D51F, 'M', u'b'), + (0x1D520, 'M', u'c'), + (0x1D521, 'M', u'd'), + (0x1D522, 'M', u'e'), + (0x1D523, 'M', u'f'), + (0x1D524, 'M', u'g'), + (0x1D525, 'M', u'h'), + (0x1D526, 'M', u'i'), + (0x1D527, 'M', u'j'), + (0x1D528, 'M', u'k'), + (0x1D529, 'M', u'l'), + (0x1D52A, 'M', u'm'), + (0x1D52B, 'M', u'n'), + (0x1D52C, 'M', u'o'), + (0x1D52D, 'M', u'p'), + (0x1D52E, 'M', u'q'), + (0x1D52F, 'M', u'r'), + (0x1D530, 'M', u's'), + (0x1D531, 'M', u't'), + (0x1D532, 'M', u'u'), + (0x1D533, 'M', u'v'), + (0x1D534, 'M', u'w'), + (0x1D535, 'M', u'x'), + ] + +def _seg_61(): + return [ + (0x1D536, 'M', u'y'), + (0x1D537, 'M', u'z'), + (0x1D538, 'M', u'a'), + (0x1D539, 'M', u'b'), + (0x1D53A, 'X'), + (0x1D53B, 'M', u'd'), + (0x1D53C, 'M', u'e'), + (0x1D53D, 'M', u'f'), + (0x1D53E, 'M', u'g'), + (0x1D53F, 'X'), + (0x1D540, 'M', u'i'), + (0x1D541, 'M', u'j'), + (0x1D542, 'M', u'k'), + (0x1D543, 'M', u'l'), + (0x1D544, 'M', u'm'), + (0x1D545, 'X'), + (0x1D546, 'M', u'o'), + (0x1D547, 'X'), + (0x1D54A, 'M', u's'), + (0x1D54B, 'M', u't'), + (0x1D54C, 'M', u'u'), + (0x1D54D, 'M', u'v'), + (0x1D54E, 'M', u'w'), + (0x1D54F, 'M', u'x'), + (0x1D550, 'M', u'y'), + (0x1D551, 'X'), + (0x1D552, 'M', u'a'), + (0x1D553, 'M', u'b'), + (0x1D554, 'M', u'c'), + (0x1D555, 'M', u'd'), + (0x1D556, 'M', u'e'), + (0x1D557, 'M', u'f'), + (0x1D558, 'M', u'g'), + (0x1D559, 'M', u'h'), + (0x1D55A, 'M', u'i'), + (0x1D55B, 'M', u'j'), + (0x1D55C, 'M', u'k'), + (0x1D55D, 'M', u'l'), + (0x1D55E, 'M', u'm'), + (0x1D55F, 'M', u'n'), + (0x1D560, 'M', u'o'), + (0x1D561, 'M', u'p'), + (0x1D562, 'M', u'q'), + (0x1D563, 'M', u'r'), + (0x1D564, 'M', u's'), + (0x1D565, 'M', u't'), + (0x1D566, 'M', u'u'), + (0x1D567, 'M', u'v'), + (0x1D568, 'M', u'w'), + (0x1D569, 'M', u'x'), + (0x1D56A, 'M', u'y'), + (0x1D56B, 'M', u'z'), + (0x1D56C, 'M', u'a'), + (0x1D56D, 'M', u'b'), + (0x1D56E, 'M', u'c'), + (0x1D56F, 'M', u'd'), + (0x1D570, 'M', u'e'), + (0x1D571, 'M', u'f'), + (0x1D572, 'M', u'g'), + (0x1D573, 'M', u'h'), + (0x1D574, 'M', u'i'), + (0x1D575, 'M', u'j'), + (0x1D576, 'M', u'k'), + (0x1D577, 'M', u'l'), + (0x1D578, 'M', u'm'), + (0x1D579, 'M', u'n'), + (0x1D57A, 'M', u'o'), + (0x1D57B, 'M', u'p'), + (0x1D57C, 'M', u'q'), + (0x1D57D, 'M', u'r'), + (0x1D57E, 'M', u's'), + (0x1D57F, 'M', u't'), + (0x1D580, 'M', u'u'), + (0x1D581, 'M', u'v'), + (0x1D582, 'M', u'w'), + (0x1D583, 'M', u'x'), + (0x1D584, 'M', u'y'), + (0x1D585, 'M', u'z'), + (0x1D586, 'M', u'a'), + (0x1D587, 'M', u'b'), + (0x1D588, 'M', u'c'), + (0x1D589, 'M', u'd'), + (0x1D58A, 'M', u'e'), + (0x1D58B, 'M', u'f'), + (0x1D58C, 'M', u'g'), + (0x1D58D, 'M', u'h'), + (0x1D58E, 'M', u'i'), + (0x1D58F, 'M', u'j'), + (0x1D590, 'M', u'k'), + (0x1D591, 'M', u'l'), + (0x1D592, 'M', u'm'), + (0x1D593, 'M', u'n'), + (0x1D594, 'M', u'o'), + (0x1D595, 'M', u'p'), + (0x1D596, 'M', u'q'), + (0x1D597, 'M', u'r'), + (0x1D598, 'M', u's'), + (0x1D599, 'M', u't'), + (0x1D59A, 'M', u'u'), + (0x1D59B, 'M', u'v'), + ] + +def _seg_62(): + return [ + (0x1D59C, 'M', u'w'), + (0x1D59D, 'M', u'x'), + (0x1D59E, 'M', u'y'), + (0x1D59F, 'M', u'z'), + (0x1D5A0, 'M', u'a'), + (0x1D5A1, 'M', u'b'), + (0x1D5A2, 'M', u'c'), + (0x1D5A3, 'M', u'd'), + (0x1D5A4, 'M', u'e'), + (0x1D5A5, 'M', u'f'), + (0x1D5A6, 'M', u'g'), + (0x1D5A7, 'M', u'h'), + (0x1D5A8, 'M', u'i'), + (0x1D5A9, 'M', u'j'), + (0x1D5AA, 'M', u'k'), + (0x1D5AB, 'M', u'l'), + (0x1D5AC, 'M', u'm'), + (0x1D5AD, 'M', u'n'), + (0x1D5AE, 'M', u'o'), + (0x1D5AF, 'M', u'p'), + (0x1D5B0, 'M', u'q'), + (0x1D5B1, 'M', u'r'), + (0x1D5B2, 'M', u's'), + (0x1D5B3, 'M', u't'), + (0x1D5B4, 'M', u'u'), + (0x1D5B5, 'M', u'v'), + (0x1D5B6, 'M', u'w'), + (0x1D5B7, 'M', u'x'), + (0x1D5B8, 'M', u'y'), + (0x1D5B9, 'M', u'z'), + (0x1D5BA, 'M', u'a'), + (0x1D5BB, 'M', u'b'), + (0x1D5BC, 'M', u'c'), + (0x1D5BD, 'M', u'd'), + (0x1D5BE, 'M', u'e'), + (0x1D5BF, 'M', u'f'), + (0x1D5C0, 'M', u'g'), + (0x1D5C1, 'M', u'h'), + (0x1D5C2, 'M', u'i'), + (0x1D5C3, 'M', u'j'), + (0x1D5C4, 'M', u'k'), + (0x1D5C5, 'M', u'l'), + (0x1D5C6, 'M', u'm'), + (0x1D5C7, 'M', u'n'), + (0x1D5C8, 'M', u'o'), + (0x1D5C9, 'M', u'p'), + (0x1D5CA, 'M', u'q'), + (0x1D5CB, 'M', u'r'), + (0x1D5CC, 'M', u's'), + (0x1D5CD, 'M', u't'), + (0x1D5CE, 'M', u'u'), + (0x1D5CF, 'M', u'v'), + (0x1D5D0, 'M', u'w'), + (0x1D5D1, 'M', u'x'), + (0x1D5D2, 'M', u'y'), + (0x1D5D3, 'M', u'z'), + (0x1D5D4, 'M', u'a'), + (0x1D5D5, 'M', u'b'), + (0x1D5D6, 'M', u'c'), + (0x1D5D7, 'M', u'd'), + (0x1D5D8, 'M', u'e'), + (0x1D5D9, 'M', u'f'), + (0x1D5DA, 'M', u'g'), + (0x1D5DB, 'M', u'h'), + (0x1D5DC, 'M', u'i'), + (0x1D5DD, 'M', u'j'), + (0x1D5DE, 'M', u'k'), + (0x1D5DF, 'M', u'l'), + (0x1D5E0, 'M', u'm'), + (0x1D5E1, 'M', u'n'), + (0x1D5E2, 'M', u'o'), + (0x1D5E3, 'M', u'p'), + (0x1D5E4, 'M', u'q'), + (0x1D5E5, 'M', u'r'), + (0x1D5E6, 'M', u's'), + (0x1D5E7, 'M', u't'), + (0x1D5E8, 'M', u'u'), + (0x1D5E9, 'M', u'v'), + (0x1D5EA, 'M', u'w'), + (0x1D5EB, 'M', u'x'), + (0x1D5EC, 'M', u'y'), + (0x1D5ED, 'M', u'z'), + (0x1D5EE, 'M', u'a'), + (0x1D5EF, 'M', u'b'), + (0x1D5F0, 'M', u'c'), + (0x1D5F1, 'M', u'd'), + (0x1D5F2, 'M', u'e'), + (0x1D5F3, 'M', u'f'), + (0x1D5F4, 'M', u'g'), + (0x1D5F5, 'M', u'h'), + (0x1D5F6, 'M', u'i'), + (0x1D5F7, 'M', u'j'), + (0x1D5F8, 'M', u'k'), + (0x1D5F9, 'M', u'l'), + (0x1D5FA, 'M', u'm'), + (0x1D5FB, 'M', u'n'), + (0x1D5FC, 'M', u'o'), + (0x1D5FD, 'M', u'p'), + (0x1D5FE, 'M', u'q'), + (0x1D5FF, 'M', u'r'), + ] + +def _seg_63(): + return [ + (0x1D600, 'M', u's'), + (0x1D601, 'M', u't'), + (0x1D602, 'M', u'u'), + (0x1D603, 'M', u'v'), + (0x1D604, 'M', u'w'), + (0x1D605, 'M', u'x'), + (0x1D606, 'M', u'y'), + (0x1D607, 'M', u'z'), + (0x1D608, 'M', u'a'), + (0x1D609, 'M', u'b'), + (0x1D60A, 'M', u'c'), + (0x1D60B, 'M', u'd'), + (0x1D60C, 'M', u'e'), + (0x1D60D, 'M', u'f'), + (0x1D60E, 'M', u'g'), + (0x1D60F, 'M', u'h'), + (0x1D610, 'M', u'i'), + (0x1D611, 'M', u'j'), + (0x1D612, 'M', u'k'), + (0x1D613, 'M', u'l'), + (0x1D614, 'M', u'm'), + (0x1D615, 'M', u'n'), + (0x1D616, 'M', u'o'), + (0x1D617, 'M', u'p'), + (0x1D618, 'M', u'q'), + (0x1D619, 'M', u'r'), + (0x1D61A, 'M', u's'), + (0x1D61B, 'M', u't'), + (0x1D61C, 'M', u'u'), + (0x1D61D, 'M', u'v'), + (0x1D61E, 'M', u'w'), + (0x1D61F, 'M', u'x'), + (0x1D620, 'M', u'y'), + (0x1D621, 'M', u'z'), + (0x1D622, 'M', u'a'), + (0x1D623, 'M', u'b'), + (0x1D624, 'M', u'c'), + (0x1D625, 'M', u'd'), + (0x1D626, 'M', u'e'), + (0x1D627, 'M', u'f'), + (0x1D628, 'M', u'g'), + (0x1D629, 'M', u'h'), + (0x1D62A, 'M', u'i'), + (0x1D62B, 'M', u'j'), + (0x1D62C, 'M', u'k'), + (0x1D62D, 'M', u'l'), + (0x1D62E, 'M', u'm'), + (0x1D62F, 'M', u'n'), + (0x1D630, 'M', u'o'), + (0x1D631, 'M', u'p'), + (0x1D632, 'M', u'q'), + (0x1D633, 'M', u'r'), + (0x1D634, 'M', u's'), + (0x1D635, 'M', u't'), + (0x1D636, 'M', u'u'), + (0x1D637, 'M', u'v'), + (0x1D638, 'M', u'w'), + (0x1D639, 'M', u'x'), + (0x1D63A, 'M', u'y'), + (0x1D63B, 'M', u'z'), + (0x1D63C, 'M', u'a'), + (0x1D63D, 'M', u'b'), + (0x1D63E, 'M', u'c'), + (0x1D63F, 'M', u'd'), + (0x1D640, 'M', u'e'), + (0x1D641, 'M', u'f'), + (0x1D642, 'M', u'g'), + (0x1D643, 'M', u'h'), + (0x1D644, 'M', u'i'), + (0x1D645, 'M', u'j'), + (0x1D646, 'M', u'k'), + (0x1D647, 'M', u'l'), + (0x1D648, 'M', u'm'), + (0x1D649, 'M', u'n'), + (0x1D64A, 'M', u'o'), + (0x1D64B, 'M', u'p'), + (0x1D64C, 'M', u'q'), + (0x1D64D, 'M', u'r'), + (0x1D64E, 'M', u's'), + (0x1D64F, 'M', u't'), + (0x1D650, 'M', u'u'), + (0x1D651, 'M', u'v'), + (0x1D652, 'M', u'w'), + (0x1D653, 'M', u'x'), + (0x1D654, 'M', u'y'), + (0x1D655, 'M', u'z'), + (0x1D656, 'M', u'a'), + (0x1D657, 'M', u'b'), + (0x1D658, 'M', u'c'), + (0x1D659, 'M', u'd'), + (0x1D65A, 'M', u'e'), + (0x1D65B, 'M', u'f'), + (0x1D65C, 'M', u'g'), + (0x1D65D, 'M', u'h'), + (0x1D65E, 'M', u'i'), + (0x1D65F, 'M', u'j'), + (0x1D660, 'M', u'k'), + (0x1D661, 'M', u'l'), + (0x1D662, 'M', u'm'), + (0x1D663, 'M', u'n'), + ] + +def _seg_64(): + return [ + (0x1D664, 'M', u'o'), + (0x1D665, 'M', u'p'), + (0x1D666, 'M', u'q'), + (0x1D667, 'M', u'r'), + (0x1D668, 'M', u's'), + (0x1D669, 'M', u't'), + (0x1D66A, 'M', u'u'), + (0x1D66B, 'M', u'v'), + (0x1D66C, 'M', u'w'), + (0x1D66D, 'M', u'x'), + (0x1D66E, 'M', u'y'), + (0x1D66F, 'M', u'z'), + (0x1D670, 'M', u'a'), + (0x1D671, 'M', u'b'), + (0x1D672, 'M', u'c'), + (0x1D673, 'M', u'd'), + (0x1D674, 'M', u'e'), + (0x1D675, 'M', u'f'), + (0x1D676, 'M', u'g'), + (0x1D677, 'M', u'h'), + (0x1D678, 'M', u'i'), + (0x1D679, 'M', u'j'), + (0x1D67A, 'M', u'k'), + (0x1D67B, 'M', u'l'), + (0x1D67C, 'M', u'm'), + (0x1D67D, 'M', u'n'), + (0x1D67E, 'M', u'o'), + (0x1D67F, 'M', u'p'), + (0x1D680, 'M', u'q'), + (0x1D681, 'M', u'r'), + (0x1D682, 'M', u's'), + (0x1D683, 'M', u't'), + (0x1D684, 'M', u'u'), + (0x1D685, 'M', u'v'), + (0x1D686, 'M', u'w'), + (0x1D687, 'M', u'x'), + (0x1D688, 'M', u'y'), + (0x1D689, 'M', u'z'), + (0x1D68A, 'M', u'a'), + (0x1D68B, 'M', u'b'), + (0x1D68C, 'M', u'c'), + (0x1D68D, 'M', u'd'), + (0x1D68E, 'M', u'e'), + (0x1D68F, 'M', u'f'), + (0x1D690, 'M', u'g'), + (0x1D691, 'M', u'h'), + (0x1D692, 'M', u'i'), + (0x1D693, 'M', u'j'), + (0x1D694, 'M', u'k'), + (0x1D695, 'M', u'l'), + (0x1D696, 'M', u'm'), + (0x1D697, 'M', u'n'), + (0x1D698, 'M', u'o'), + (0x1D699, 'M', u'p'), + (0x1D69A, 'M', u'q'), + (0x1D69B, 'M', u'r'), + (0x1D69C, 'M', u's'), + (0x1D69D, 'M', u't'), + (0x1D69E, 'M', u'u'), + (0x1D69F, 'M', u'v'), + (0x1D6A0, 'M', u'w'), + (0x1D6A1, 'M', u'x'), + (0x1D6A2, 'M', u'y'), + (0x1D6A3, 'M', u'z'), + (0x1D6A4, 'M', u'ı'), + (0x1D6A5, 'M', u'ȷ'), + (0x1D6A6, 'X'), + (0x1D6A8, 'M', u'α'), + (0x1D6A9, 'M', u'β'), + (0x1D6AA, 'M', u'γ'), + (0x1D6AB, 'M', u'δ'), + (0x1D6AC, 'M', u'ε'), + (0x1D6AD, 'M', u'ζ'), + (0x1D6AE, 'M', u'η'), + (0x1D6AF, 'M', u'θ'), + (0x1D6B0, 'M', u'ι'), + (0x1D6B1, 'M', u'κ'), + (0x1D6B2, 'M', u'λ'), + (0x1D6B3, 'M', u'μ'), + (0x1D6B4, 'M', u'ν'), + (0x1D6B5, 'M', u'ξ'), + (0x1D6B6, 'M', u'ο'), + (0x1D6B7, 'M', u'π'), + (0x1D6B8, 'M', u'ρ'), + (0x1D6B9, 'M', u'θ'), + (0x1D6BA, 'M', u'σ'), + (0x1D6BB, 'M', u'τ'), + (0x1D6BC, 'M', u'υ'), + (0x1D6BD, 'M', u'φ'), + (0x1D6BE, 'M', u'χ'), + (0x1D6BF, 'M', u'ψ'), + (0x1D6C0, 'M', u'ω'), + (0x1D6C1, 'M', u'∇'), + (0x1D6C2, 'M', u'α'), + (0x1D6C3, 'M', u'β'), + (0x1D6C4, 'M', u'γ'), + (0x1D6C5, 'M', u'δ'), + (0x1D6C6, 'M', u'ε'), + (0x1D6C7, 'M', u'ζ'), + (0x1D6C8, 'M', u'η'), + ] + +def _seg_65(): + return [ + (0x1D6C9, 'M', u'θ'), + (0x1D6CA, 'M', u'ι'), + (0x1D6CB, 'M', u'κ'), + (0x1D6CC, 'M', u'λ'), + (0x1D6CD, 'M', u'μ'), + (0x1D6CE, 'M', u'ν'), + (0x1D6CF, 'M', u'ξ'), + (0x1D6D0, 'M', u'ο'), + (0x1D6D1, 'M', u'π'), + (0x1D6D2, 'M', u'ρ'), + (0x1D6D3, 'M', u'σ'), + (0x1D6D5, 'M', u'τ'), + (0x1D6D6, 'M', u'υ'), + (0x1D6D7, 'M', u'φ'), + (0x1D6D8, 'M', u'χ'), + (0x1D6D9, 'M', u'ψ'), + (0x1D6DA, 'M', u'ω'), + (0x1D6DB, 'M', u'∂'), + (0x1D6DC, 'M', u'ε'), + (0x1D6DD, 'M', u'θ'), + (0x1D6DE, 'M', u'κ'), + (0x1D6DF, 'M', u'φ'), + (0x1D6E0, 'M', u'ρ'), + (0x1D6E1, 'M', u'π'), + (0x1D6E2, 'M', u'α'), + (0x1D6E3, 'M', u'β'), + (0x1D6E4, 'M', u'γ'), + (0x1D6E5, 'M', u'δ'), + (0x1D6E6, 'M', u'ε'), + (0x1D6E7, 'M', u'ζ'), + (0x1D6E8, 'M', u'η'), + (0x1D6E9, 'M', u'θ'), + (0x1D6EA, 'M', u'ι'), + (0x1D6EB, 'M', u'κ'), + (0x1D6EC, 'M', u'λ'), + (0x1D6ED, 'M', u'μ'), + (0x1D6EE, 'M', u'ν'), + (0x1D6EF, 'M', u'ξ'), + (0x1D6F0, 'M', u'ο'), + (0x1D6F1, 'M', u'π'), + (0x1D6F2, 'M', u'ρ'), + (0x1D6F3, 'M', u'θ'), + (0x1D6F4, 'M', u'σ'), + (0x1D6F5, 'M', u'τ'), + (0x1D6F6, 'M', u'υ'), + (0x1D6F7, 'M', u'φ'), + (0x1D6F8, 'M', u'χ'), + (0x1D6F9, 'M', u'ψ'), + (0x1D6FA, 'M', u'ω'), + (0x1D6FB, 'M', u'∇'), + (0x1D6FC, 'M', u'α'), + (0x1D6FD, 'M', u'β'), + (0x1D6FE, 'M', u'γ'), + (0x1D6FF, 'M', u'δ'), + (0x1D700, 'M', u'ε'), + (0x1D701, 'M', u'ζ'), + (0x1D702, 'M', u'η'), + (0x1D703, 'M', u'θ'), + (0x1D704, 'M', u'ι'), + (0x1D705, 'M', u'κ'), + (0x1D706, 'M', u'λ'), + (0x1D707, 'M', u'μ'), + (0x1D708, 'M', u'ν'), + (0x1D709, 'M', u'ξ'), + (0x1D70A, 'M', u'ο'), + (0x1D70B, 'M', u'π'), + (0x1D70C, 'M', u'ρ'), + (0x1D70D, 'M', u'σ'), + (0x1D70F, 'M', u'τ'), + (0x1D710, 'M', u'υ'), + (0x1D711, 'M', u'φ'), + (0x1D712, 'M', u'χ'), + (0x1D713, 'M', u'ψ'), + (0x1D714, 'M', u'ω'), + (0x1D715, 'M', u'∂'), + (0x1D716, 'M', u'ε'), + (0x1D717, 'M', u'θ'), + (0x1D718, 'M', u'κ'), + (0x1D719, 'M', u'φ'), + (0x1D71A, 'M', u'ρ'), + (0x1D71B, 'M', u'π'), + (0x1D71C, 'M', u'α'), + (0x1D71D, 'M', u'β'), + (0x1D71E, 'M', u'γ'), + (0x1D71F, 'M', u'δ'), + (0x1D720, 'M', u'ε'), + (0x1D721, 'M', u'ζ'), + (0x1D722, 'M', u'η'), + (0x1D723, 'M', u'θ'), + (0x1D724, 'M', u'ι'), + (0x1D725, 'M', u'κ'), + (0x1D726, 'M', u'λ'), + (0x1D727, 'M', u'μ'), + (0x1D728, 'M', u'ν'), + (0x1D729, 'M', u'ξ'), + (0x1D72A, 'M', u'ο'), + (0x1D72B, 'M', u'π'), + (0x1D72C, 'M', u'ρ'), + (0x1D72D, 'M', u'θ'), + (0x1D72E, 'M', u'σ'), + ] + +def _seg_66(): + return [ + (0x1D72F, 'M', u'τ'), + (0x1D730, 'M', u'υ'), + (0x1D731, 'M', u'φ'), + (0x1D732, 'M', u'χ'), + (0x1D733, 'M', u'ψ'), + (0x1D734, 'M', u'ω'), + (0x1D735, 'M', u'∇'), + (0x1D736, 'M', u'α'), + (0x1D737, 'M', u'β'), + (0x1D738, 'M', u'γ'), + (0x1D739, 'M', u'δ'), + (0x1D73A, 'M', u'ε'), + (0x1D73B, 'M', u'ζ'), + (0x1D73C, 'M', u'η'), + (0x1D73D, 'M', u'θ'), + (0x1D73E, 'M', u'ι'), + (0x1D73F, 'M', u'κ'), + (0x1D740, 'M', u'λ'), + (0x1D741, 'M', u'μ'), + (0x1D742, 'M', u'ν'), + (0x1D743, 'M', u'ξ'), + (0x1D744, 'M', u'ο'), + (0x1D745, 'M', u'π'), + (0x1D746, 'M', u'ρ'), + (0x1D747, 'M', u'σ'), + (0x1D749, 'M', u'τ'), + (0x1D74A, 'M', u'υ'), + (0x1D74B, 'M', u'φ'), + (0x1D74C, 'M', u'χ'), + (0x1D74D, 'M', u'ψ'), + (0x1D74E, 'M', u'ω'), + (0x1D74F, 'M', u'∂'), + (0x1D750, 'M', u'ε'), + (0x1D751, 'M', u'θ'), + (0x1D752, 'M', u'κ'), + (0x1D753, 'M', u'φ'), + (0x1D754, 'M', u'ρ'), + (0x1D755, 'M', u'π'), + (0x1D756, 'M', u'α'), + (0x1D757, 'M', u'β'), + (0x1D758, 'M', u'γ'), + (0x1D759, 'M', u'δ'), + (0x1D75A, 'M', u'ε'), + (0x1D75B, 'M', u'ζ'), + (0x1D75C, 'M', u'η'), + (0x1D75D, 'M', u'θ'), + (0x1D75E, 'M', u'ι'), + (0x1D75F, 'M', u'κ'), + (0x1D760, 'M', u'λ'), + (0x1D761, 'M', u'μ'), + (0x1D762, 'M', u'ν'), + (0x1D763, 'M', u'ξ'), + (0x1D764, 'M', u'ο'), + (0x1D765, 'M', u'π'), + (0x1D766, 'M', u'ρ'), + (0x1D767, 'M', u'θ'), + (0x1D768, 'M', u'σ'), + (0x1D769, 'M', u'τ'), + (0x1D76A, 'M', u'υ'), + (0x1D76B, 'M', u'φ'), + (0x1D76C, 'M', u'χ'), + (0x1D76D, 'M', u'ψ'), + (0x1D76E, 'M', u'ω'), + (0x1D76F, 'M', u'∇'), + (0x1D770, 'M', u'α'), + (0x1D771, 'M', u'β'), + (0x1D772, 'M', u'γ'), + (0x1D773, 'M', u'δ'), + (0x1D774, 'M', u'ε'), + (0x1D775, 'M', u'ζ'), + (0x1D776, 'M', u'η'), + (0x1D777, 'M', u'θ'), + (0x1D778, 'M', u'ι'), + (0x1D779, 'M', u'κ'), + (0x1D77A, 'M', u'λ'), + (0x1D77B, 'M', u'μ'), + (0x1D77C, 'M', u'ν'), + (0x1D77D, 'M', u'ξ'), + (0x1D77E, 'M', u'ο'), + (0x1D77F, 'M', u'π'), + (0x1D780, 'M', u'ρ'), + (0x1D781, 'M', u'σ'), + (0x1D783, 'M', u'τ'), + (0x1D784, 'M', u'υ'), + (0x1D785, 'M', u'φ'), + (0x1D786, 'M', u'χ'), + (0x1D787, 'M', u'ψ'), + (0x1D788, 'M', u'ω'), + (0x1D789, 'M', u'∂'), + (0x1D78A, 'M', u'ε'), + (0x1D78B, 'M', u'θ'), + (0x1D78C, 'M', u'κ'), + (0x1D78D, 'M', u'φ'), + (0x1D78E, 'M', u'ρ'), + (0x1D78F, 'M', u'π'), + (0x1D790, 'M', u'α'), + (0x1D791, 'M', u'β'), + (0x1D792, 'M', u'γ'), + (0x1D793, 'M', u'δ'), + (0x1D794, 'M', u'ε'), + ] + +def _seg_67(): + return [ + (0x1D795, 'M', u'ζ'), + (0x1D796, 'M', u'η'), + (0x1D797, 'M', u'θ'), + (0x1D798, 'M', u'ι'), + (0x1D799, 'M', u'κ'), + (0x1D79A, 'M', u'λ'), + (0x1D79B, 'M', u'μ'), + (0x1D79C, 'M', u'ν'), + (0x1D79D, 'M', u'ξ'), + (0x1D79E, 'M', u'ο'), + (0x1D79F, 'M', u'π'), + (0x1D7A0, 'M', u'ρ'), + (0x1D7A1, 'M', u'θ'), + (0x1D7A2, 'M', u'σ'), + (0x1D7A3, 'M', u'τ'), + (0x1D7A4, 'M', u'υ'), + (0x1D7A5, 'M', u'φ'), + (0x1D7A6, 'M', u'χ'), + (0x1D7A7, 'M', u'ψ'), + (0x1D7A8, 'M', u'ω'), + (0x1D7A9, 'M', u'∇'), + (0x1D7AA, 'M', u'α'), + (0x1D7AB, 'M', u'β'), + (0x1D7AC, 'M', u'γ'), + (0x1D7AD, 'M', u'δ'), + (0x1D7AE, 'M', u'ε'), + (0x1D7AF, 'M', u'ζ'), + (0x1D7B0, 'M', u'η'), + (0x1D7B1, 'M', u'θ'), + (0x1D7B2, 'M', u'ι'), + (0x1D7B3, 'M', u'κ'), + (0x1D7B4, 'M', u'λ'), + (0x1D7B5, 'M', u'μ'), + (0x1D7B6, 'M', u'ν'), + (0x1D7B7, 'M', u'ξ'), + (0x1D7B8, 'M', u'ο'), + (0x1D7B9, 'M', u'π'), + (0x1D7BA, 'M', u'ρ'), + (0x1D7BB, 'M', u'σ'), + (0x1D7BD, 'M', u'τ'), + (0x1D7BE, 'M', u'υ'), + (0x1D7BF, 'M', u'φ'), + (0x1D7C0, 'M', u'χ'), + (0x1D7C1, 'M', u'ψ'), + (0x1D7C2, 'M', u'ω'), + (0x1D7C3, 'M', u'∂'), + (0x1D7C4, 'M', u'ε'), + (0x1D7C5, 'M', u'θ'), + (0x1D7C6, 'M', u'κ'), + (0x1D7C7, 'M', u'φ'), + (0x1D7C8, 'M', u'ρ'), + (0x1D7C9, 'M', u'π'), + (0x1D7CA, 'M', u'ϝ'), + (0x1D7CC, 'X'), + (0x1D7CE, 'M', u'0'), + (0x1D7CF, 'M', u'1'), + (0x1D7D0, 'M', u'2'), + (0x1D7D1, 'M', u'3'), + (0x1D7D2, 'M', u'4'), + (0x1D7D3, 'M', u'5'), + (0x1D7D4, 'M', u'6'), + (0x1D7D5, 'M', u'7'), + (0x1D7D6, 'M', u'8'), + (0x1D7D7, 'M', u'9'), + (0x1D7D8, 'M', u'0'), + (0x1D7D9, 'M', u'1'), + (0x1D7DA, 'M', u'2'), + (0x1D7DB, 'M', u'3'), + (0x1D7DC, 'M', u'4'), + (0x1D7DD, 'M', u'5'), + (0x1D7DE, 'M', u'6'), + (0x1D7DF, 'M', u'7'), + (0x1D7E0, 'M', u'8'), + (0x1D7E1, 'M', u'9'), + (0x1D7E2, 'M', u'0'), + (0x1D7E3, 'M', u'1'), + (0x1D7E4, 'M', u'2'), + (0x1D7E5, 'M', u'3'), + (0x1D7E6, 'M', u'4'), + (0x1D7E7, 'M', u'5'), + (0x1D7E8, 'M', u'6'), + (0x1D7E9, 'M', u'7'), + (0x1D7EA, 'M', u'8'), + (0x1D7EB, 'M', u'9'), + (0x1D7EC, 'M', u'0'), + (0x1D7ED, 'M', u'1'), + (0x1D7EE, 'M', u'2'), + (0x1D7EF, 'M', u'3'), + (0x1D7F0, 'M', u'4'), + (0x1D7F1, 'M', u'5'), + (0x1D7F2, 'M', u'6'), + (0x1D7F3, 'M', u'7'), + (0x1D7F4, 'M', u'8'), + (0x1D7F5, 'M', u'9'), + (0x1D7F6, 'M', u'0'), + (0x1D7F7, 'M', u'1'), + (0x1D7F8, 'M', u'2'), + (0x1D7F9, 'M', u'3'), + (0x1D7FA, 'M', u'4'), + (0x1D7FB, 'M', u'5'), + ] + +def _seg_68(): + return [ + (0x1D7FC, 'M', u'6'), + (0x1D7FD, 'M', u'7'), + (0x1D7FE, 'M', u'8'), + (0x1D7FF, 'M', u'9'), + (0x1D800, 'V'), + (0x1DA8C, 'X'), + (0x1DA9B, 'V'), + (0x1DAA0, 'X'), + (0x1DAA1, 'V'), + (0x1DAB0, 'X'), + (0x1E000, 'V'), + (0x1E007, 'X'), + (0x1E008, 'V'), + (0x1E019, 'X'), + (0x1E01B, 'V'), + (0x1E022, 'X'), + (0x1E023, 'V'), + (0x1E025, 'X'), + (0x1E026, 'V'), + (0x1E02B, 'X'), + (0x1E800, 'V'), + (0x1E8C5, 'X'), + (0x1E8C7, 'V'), + (0x1E8D7, 'X'), + (0x1E900, 'M', u'𞤢'), + (0x1E901, 'M', u'𞤣'), + (0x1E902, 'M', u'𞤤'), + (0x1E903, 'M', u'𞤥'), + (0x1E904, 'M', u'𞤦'), + (0x1E905, 'M', u'𞤧'), + (0x1E906, 'M', u'𞤨'), + (0x1E907, 'M', u'𞤩'), + (0x1E908, 'M', u'𞤪'), + (0x1E909, 'M', u'𞤫'), + (0x1E90A, 'M', u'𞤬'), + (0x1E90B, 'M', u'𞤭'), + (0x1E90C, 'M', u'𞤮'), + (0x1E90D, 'M', u'𞤯'), + (0x1E90E, 'M', u'𞤰'), + (0x1E90F, 'M', u'𞤱'), + (0x1E910, 'M', u'𞤲'), + (0x1E911, 'M', u'𞤳'), + (0x1E912, 'M', u'𞤴'), + (0x1E913, 'M', u'𞤵'), + (0x1E914, 'M', u'𞤶'), + (0x1E915, 'M', u'𞤷'), + (0x1E916, 'M', u'𞤸'), + (0x1E917, 'M', u'𞤹'), + (0x1E918, 'M', u'𞤺'), + (0x1E919, 'M', u'𞤻'), + (0x1E91A, 'M', u'𞤼'), + (0x1E91B, 'M', u'𞤽'), + (0x1E91C, 'M', u'𞤾'), + (0x1E91D, 'M', u'𞤿'), + (0x1E91E, 'M', u'𞥀'), + (0x1E91F, 'M', u'𞥁'), + (0x1E920, 'M', u'𞥂'), + (0x1E921, 'M', u'𞥃'), + (0x1E922, 'V'), + (0x1E94B, 'X'), + (0x1E950, 'V'), + (0x1E95A, 'X'), + (0x1E95E, 'V'), + (0x1E960, 'X'), + (0x1EE00, 'M', u'ا'), + (0x1EE01, 'M', u'ب'), + (0x1EE02, 'M', u'ج'), + (0x1EE03, 'M', u'د'), + (0x1EE04, 'X'), + (0x1EE05, 'M', u'و'), + (0x1EE06, 'M', u'ز'), + (0x1EE07, 'M', u'ح'), + (0x1EE08, 'M', u'ط'), + (0x1EE09, 'M', u'ي'), + (0x1EE0A, 'M', u'ك'), + (0x1EE0B, 'M', u'ل'), + (0x1EE0C, 'M', u'م'), + (0x1EE0D, 'M', u'ن'), + (0x1EE0E, 'M', u'س'), + (0x1EE0F, 'M', u'ع'), + (0x1EE10, 'M', u'ف'), + (0x1EE11, 'M', u'ص'), + (0x1EE12, 'M', u'ق'), + (0x1EE13, 'M', u'ر'), + (0x1EE14, 'M', u'ش'), + (0x1EE15, 'M', u'ت'), + (0x1EE16, 'M', u'ث'), + (0x1EE17, 'M', u'خ'), + (0x1EE18, 'M', u'ذ'), + (0x1EE19, 'M', u'ض'), + (0x1EE1A, 'M', u'ظ'), + (0x1EE1B, 'M', u'غ'), + (0x1EE1C, 'M', u'ٮ'), + (0x1EE1D, 'M', u'ں'), + (0x1EE1E, 'M', u'ڡ'), + (0x1EE1F, 'M', u'ٯ'), + (0x1EE20, 'X'), + (0x1EE21, 'M', u'ب'), + (0x1EE22, 'M', u'ج'), + (0x1EE23, 'X'), + ] + +def _seg_69(): + return [ + (0x1EE24, 'M', u'ه'), + (0x1EE25, 'X'), + (0x1EE27, 'M', u'ح'), + (0x1EE28, 'X'), + (0x1EE29, 'M', u'ي'), + (0x1EE2A, 'M', u'ك'), + (0x1EE2B, 'M', u'ل'), + (0x1EE2C, 'M', u'م'), + (0x1EE2D, 'M', u'ن'), + (0x1EE2E, 'M', u'س'), + (0x1EE2F, 'M', u'ع'), + (0x1EE30, 'M', u'ف'), + (0x1EE31, 'M', u'ص'), + (0x1EE32, 'M', u'ق'), + (0x1EE33, 'X'), + (0x1EE34, 'M', u'ش'), + (0x1EE35, 'M', u'ت'), + (0x1EE36, 'M', u'ث'), + (0x1EE37, 'M', u'خ'), + (0x1EE38, 'X'), + (0x1EE39, 'M', u'ض'), + (0x1EE3A, 'X'), + (0x1EE3B, 'M', u'غ'), + (0x1EE3C, 'X'), + (0x1EE42, 'M', u'ج'), + (0x1EE43, 'X'), + (0x1EE47, 'M', u'ح'), + (0x1EE48, 'X'), + (0x1EE49, 'M', u'ي'), + (0x1EE4A, 'X'), + (0x1EE4B, 'M', u'ل'), + (0x1EE4C, 'X'), + (0x1EE4D, 'M', u'ن'), + (0x1EE4E, 'M', u'س'), + (0x1EE4F, 'M', u'ع'), + (0x1EE50, 'X'), + (0x1EE51, 'M', u'ص'), + (0x1EE52, 'M', u'ق'), + (0x1EE53, 'X'), + (0x1EE54, 'M', u'ش'), + (0x1EE55, 'X'), + (0x1EE57, 'M', u'خ'), + (0x1EE58, 'X'), + (0x1EE59, 'M', u'ض'), + (0x1EE5A, 'X'), + (0x1EE5B, 'M', u'غ'), + (0x1EE5C, 'X'), + (0x1EE5D, 'M', u'ں'), + (0x1EE5E, 'X'), + (0x1EE5F, 'M', u'ٯ'), + (0x1EE60, 'X'), + (0x1EE61, 'M', u'ب'), + (0x1EE62, 'M', u'ج'), + (0x1EE63, 'X'), + (0x1EE64, 'M', u'ه'), + (0x1EE65, 'X'), + (0x1EE67, 'M', u'ح'), + (0x1EE68, 'M', u'ط'), + (0x1EE69, 'M', u'ي'), + (0x1EE6A, 'M', u'ك'), + (0x1EE6B, 'X'), + (0x1EE6C, 'M', u'م'), + (0x1EE6D, 'M', u'ن'), + (0x1EE6E, 'M', u'س'), + (0x1EE6F, 'M', u'ع'), + (0x1EE70, 'M', u'ف'), + (0x1EE71, 'M', u'ص'), + (0x1EE72, 'M', u'ق'), + (0x1EE73, 'X'), + (0x1EE74, 'M', u'ش'), + (0x1EE75, 'M', u'ت'), + (0x1EE76, 'M', u'ث'), + (0x1EE77, 'M', u'خ'), + (0x1EE78, 'X'), + (0x1EE79, 'M', u'ض'), + (0x1EE7A, 'M', u'ظ'), + (0x1EE7B, 'M', u'غ'), + (0x1EE7C, 'M', u'ٮ'), + (0x1EE7D, 'X'), + (0x1EE7E, 'M', u'ڡ'), + (0x1EE7F, 'X'), + (0x1EE80, 'M', u'ا'), + (0x1EE81, 'M', u'ب'), + (0x1EE82, 'M', u'ج'), + (0x1EE83, 'M', u'د'), + (0x1EE84, 'M', u'ه'), + (0x1EE85, 'M', u'و'), + (0x1EE86, 'M', u'ز'), + (0x1EE87, 'M', u'ح'), + (0x1EE88, 'M', u'ط'), + (0x1EE89, 'M', u'ي'), + (0x1EE8A, 'X'), + (0x1EE8B, 'M', u'ل'), + (0x1EE8C, 'M', u'م'), + (0x1EE8D, 'M', u'ن'), + (0x1EE8E, 'M', u'س'), + (0x1EE8F, 'M', u'ع'), + (0x1EE90, 'M', u'ف'), + (0x1EE91, 'M', u'ص'), + (0x1EE92, 'M', u'ق'), + ] + +def _seg_70(): + return [ + (0x1EE93, 'M', u'ر'), + (0x1EE94, 'M', u'ش'), + (0x1EE95, 'M', u'ت'), + (0x1EE96, 'M', u'ث'), + (0x1EE97, 'M', u'خ'), + (0x1EE98, 'M', u'ذ'), + (0x1EE99, 'M', u'ض'), + (0x1EE9A, 'M', u'ظ'), + (0x1EE9B, 'M', u'غ'), + (0x1EE9C, 'X'), + (0x1EEA1, 'M', u'ب'), + (0x1EEA2, 'M', u'ج'), + (0x1EEA3, 'M', u'د'), + (0x1EEA4, 'X'), + (0x1EEA5, 'M', u'و'), + (0x1EEA6, 'M', u'ز'), + (0x1EEA7, 'M', u'ح'), + (0x1EEA8, 'M', u'ط'), + (0x1EEA9, 'M', u'ي'), + (0x1EEAA, 'X'), + (0x1EEAB, 'M', u'ل'), + (0x1EEAC, 'M', u'م'), + (0x1EEAD, 'M', u'ن'), + (0x1EEAE, 'M', u'س'), + (0x1EEAF, 'M', u'ع'), + (0x1EEB0, 'M', u'ف'), + (0x1EEB1, 'M', u'ص'), + (0x1EEB2, 'M', u'ق'), + (0x1EEB3, 'M', u'ر'), + (0x1EEB4, 'M', u'ش'), + (0x1EEB5, 'M', u'ت'), + (0x1EEB6, 'M', u'ث'), + (0x1EEB7, 'M', u'خ'), + (0x1EEB8, 'M', u'ذ'), + (0x1EEB9, 'M', u'ض'), + (0x1EEBA, 'M', u'ظ'), + (0x1EEBB, 'M', u'غ'), + (0x1EEBC, 'X'), + (0x1EEF0, 'V'), + (0x1EEF2, 'X'), + (0x1F000, 'V'), + (0x1F02C, 'X'), + (0x1F030, 'V'), + (0x1F094, 'X'), + (0x1F0A0, 'V'), + (0x1F0AF, 'X'), + (0x1F0B1, 'V'), + (0x1F0C0, 'X'), + (0x1F0C1, 'V'), + (0x1F0D0, 'X'), + (0x1F0D1, 'V'), + (0x1F0F6, 'X'), + (0x1F101, '3', u'0,'), + (0x1F102, '3', u'1,'), + (0x1F103, '3', u'2,'), + (0x1F104, '3', u'3,'), + (0x1F105, '3', u'4,'), + (0x1F106, '3', u'5,'), + (0x1F107, '3', u'6,'), + (0x1F108, '3', u'7,'), + (0x1F109, '3', u'8,'), + (0x1F10A, '3', u'9,'), + (0x1F10B, 'V'), + (0x1F10D, 'X'), + (0x1F110, '3', u'(a)'), + (0x1F111, '3', u'(b)'), + (0x1F112, '3', u'(c)'), + (0x1F113, '3', u'(d)'), + (0x1F114, '3', u'(e)'), + (0x1F115, '3', u'(f)'), + (0x1F116, '3', u'(g)'), + (0x1F117, '3', u'(h)'), + (0x1F118, '3', u'(i)'), + (0x1F119, '3', u'(j)'), + (0x1F11A, '3', u'(k)'), + (0x1F11B, '3', u'(l)'), + (0x1F11C, '3', u'(m)'), + (0x1F11D, '3', u'(n)'), + (0x1F11E, '3', u'(o)'), + (0x1F11F, '3', u'(p)'), + (0x1F120, '3', u'(q)'), + (0x1F121, '3', u'(r)'), + (0x1F122, '3', u'(s)'), + (0x1F123, '3', u'(t)'), + (0x1F124, '3', u'(u)'), + (0x1F125, '3', u'(v)'), + (0x1F126, '3', u'(w)'), + (0x1F127, '3', u'(x)'), + (0x1F128, '3', u'(y)'), + (0x1F129, '3', u'(z)'), + (0x1F12A, 'M', u'〔s〕'), + (0x1F12B, 'M', u'c'), + (0x1F12C, 'M', u'r'), + (0x1F12D, 'M', u'cd'), + (0x1F12E, 'M', u'wz'), + (0x1F12F, 'X'), + (0x1F130, 'M', u'a'), + (0x1F131, 'M', u'b'), + (0x1F132, 'M', u'c'), + (0x1F133, 'M', u'd'), + ] + +def _seg_71(): + return [ + (0x1F134, 'M', u'e'), + (0x1F135, 'M', u'f'), + (0x1F136, 'M', u'g'), + (0x1F137, 'M', u'h'), + (0x1F138, 'M', u'i'), + (0x1F139, 'M', u'j'), + (0x1F13A, 'M', u'k'), + (0x1F13B, 'M', u'l'), + (0x1F13C, 'M', u'm'), + (0x1F13D, 'M', u'n'), + (0x1F13E, 'M', u'o'), + (0x1F13F, 'M', u'p'), + (0x1F140, 'M', u'q'), + (0x1F141, 'M', u'r'), + (0x1F142, 'M', u's'), + (0x1F143, 'M', u't'), + (0x1F144, 'M', u'u'), + (0x1F145, 'M', u'v'), + (0x1F146, 'M', u'w'), + (0x1F147, 'M', u'x'), + (0x1F148, 'M', u'y'), + (0x1F149, 'M', u'z'), + (0x1F14A, 'M', u'hv'), + (0x1F14B, 'M', u'mv'), + (0x1F14C, 'M', u'sd'), + (0x1F14D, 'M', u'ss'), + (0x1F14E, 'M', u'ppv'), + (0x1F14F, 'M', u'wc'), + (0x1F150, 'V'), + (0x1F16A, 'M', u'mc'), + (0x1F16B, 'M', u'md'), + (0x1F16C, 'X'), + (0x1F170, 'V'), + (0x1F190, 'M', u'dj'), + (0x1F191, 'V'), + (0x1F1AD, 'X'), + (0x1F1E6, 'V'), + (0x1F200, 'M', u'ほか'), + (0x1F201, 'M', u'ココ'), + (0x1F202, 'M', u'サ'), + (0x1F203, 'X'), + (0x1F210, 'M', u'手'), + (0x1F211, 'M', u'字'), + (0x1F212, 'M', u'双'), + (0x1F213, 'M', u'デ'), + (0x1F214, 'M', u'二'), + (0x1F215, 'M', u'多'), + (0x1F216, 'M', u'解'), + (0x1F217, 'M', u'天'), + (0x1F218, 'M', u'交'), + (0x1F219, 'M', u'映'), + (0x1F21A, 'M', u'無'), + (0x1F21B, 'M', u'料'), + (0x1F21C, 'M', u'前'), + (0x1F21D, 'M', u'後'), + (0x1F21E, 'M', u'再'), + (0x1F21F, 'M', u'新'), + (0x1F220, 'M', u'初'), + (0x1F221, 'M', u'終'), + (0x1F222, 'M', u'生'), + (0x1F223, 'M', u'販'), + (0x1F224, 'M', u'声'), + (0x1F225, 'M', u'吹'), + (0x1F226, 'M', u'演'), + (0x1F227, 'M', u'投'), + (0x1F228, 'M', u'捕'), + (0x1F229, 'M', u'一'), + (0x1F22A, 'M', u'三'), + (0x1F22B, 'M', u'遊'), + (0x1F22C, 'M', u'左'), + (0x1F22D, 'M', u'中'), + (0x1F22E, 'M', u'右'), + (0x1F22F, 'M', u'指'), + (0x1F230, 'M', u'走'), + (0x1F231, 'M', u'打'), + (0x1F232, 'M', u'禁'), + (0x1F233, 'M', u'空'), + (0x1F234, 'M', u'合'), + (0x1F235, 'M', u'満'), + (0x1F236, 'M', u'有'), + (0x1F237, 'M', u'月'), + (0x1F238, 'M', u'申'), + (0x1F239, 'M', u'割'), + (0x1F23A, 'M', u'営'), + (0x1F23B, 'M', u'配'), + (0x1F23C, 'X'), + (0x1F240, 'M', u'〔本〕'), + (0x1F241, 'M', u'〔三〕'), + (0x1F242, 'M', u'〔二〕'), + (0x1F243, 'M', u'〔安〕'), + (0x1F244, 'M', u'〔点〕'), + (0x1F245, 'M', u'〔打〕'), + (0x1F246, 'M', u'〔盗〕'), + (0x1F247, 'M', u'〔勝〕'), + (0x1F248, 'M', u'〔敗〕'), + (0x1F249, 'X'), + (0x1F250, 'M', u'得'), + (0x1F251, 'M', u'可'), + (0x1F252, 'X'), + (0x1F260, 'V'), + ] + +def _seg_72(): + return [ + (0x1F266, 'X'), + (0x1F300, 'V'), + (0x1F6D5, 'X'), + (0x1F6E0, 'V'), + (0x1F6ED, 'X'), + (0x1F6F0, 'V'), + (0x1F6F9, 'X'), + (0x1F700, 'V'), + (0x1F774, 'X'), + (0x1F780, 'V'), + (0x1F7D5, 'X'), + (0x1F800, 'V'), + (0x1F80C, 'X'), + (0x1F810, 'V'), + (0x1F848, 'X'), + (0x1F850, 'V'), + (0x1F85A, 'X'), + (0x1F860, 'V'), + (0x1F888, 'X'), + (0x1F890, 'V'), + (0x1F8AE, 'X'), + (0x1F900, 'V'), + (0x1F90C, 'X'), + (0x1F910, 'V'), + (0x1F93F, 'X'), + (0x1F940, 'V'), + (0x1F94D, 'X'), + (0x1F950, 'V'), + (0x1F96C, 'X'), + (0x1F980, 'V'), + (0x1F998, 'X'), + (0x1F9C0, 'V'), + (0x1F9C1, 'X'), + (0x1F9D0, 'V'), + (0x1F9E7, 'X'), + (0x20000, 'V'), + (0x2A6D7, 'X'), + (0x2A700, 'V'), + (0x2B735, 'X'), + (0x2B740, 'V'), + (0x2B81E, 'X'), + (0x2B820, 'V'), + (0x2CEA2, 'X'), + (0x2CEB0, 'V'), + (0x2EBE1, 'X'), + (0x2F800, 'M', u'丽'), + (0x2F801, 'M', u'丸'), + (0x2F802, 'M', u'乁'), + (0x2F803, 'M', u'𠄢'), + (0x2F804, 'M', u'你'), + (0x2F805, 'M', u'侮'), + (0x2F806, 'M', u'侻'), + (0x2F807, 'M', u'倂'), + (0x2F808, 'M', u'偺'), + (0x2F809, 'M', u'備'), + (0x2F80A, 'M', u'僧'), + (0x2F80B, 'M', u'像'), + (0x2F80C, 'M', u'㒞'), + (0x2F80D, 'M', u'𠘺'), + (0x2F80E, 'M', u'免'), + (0x2F80F, 'M', u'兔'), + (0x2F810, 'M', u'兤'), + (0x2F811, 'M', u'具'), + (0x2F812, 'M', u'𠔜'), + (0x2F813, 'M', u'㒹'), + (0x2F814, 'M', u'內'), + (0x2F815, 'M', u'再'), + (0x2F816, 'M', u'𠕋'), + (0x2F817, 'M', u'冗'), + (0x2F818, 'M', u'冤'), + (0x2F819, 'M', u'仌'), + (0x2F81A, 'M', u'冬'), + (0x2F81B, 'M', u'况'), + (0x2F81C, 'M', u'𩇟'), + (0x2F81D, 'M', u'凵'), + (0x2F81E, 'M', u'刃'), + (0x2F81F, 'M', u'㓟'), + (0x2F820, 'M', u'刻'), + (0x2F821, 'M', u'剆'), + (0x2F822, 'M', u'割'), + (0x2F823, 'M', u'剷'), + (0x2F824, 'M', u'㔕'), + (0x2F825, 'M', u'勇'), + (0x2F826, 'M', u'勉'), + (0x2F827, 'M', u'勤'), + (0x2F828, 'M', u'勺'), + (0x2F829, 'M', u'包'), + (0x2F82A, 'M', u'匆'), + (0x2F82B, 'M', u'北'), + (0x2F82C, 'M', u'卉'), + (0x2F82D, 'M', u'卑'), + (0x2F82E, 'M', u'博'), + (0x2F82F, 'M', u'即'), + (0x2F830, 'M', u'卽'), + (0x2F831, 'M', u'卿'), + (0x2F834, 'M', u'𠨬'), + (0x2F835, 'M', u'灰'), + (0x2F836, 'M', u'及'), + (0x2F837, 'M', u'叟'), + (0x2F838, 'M', u'𠭣'), + ] + +def _seg_73(): + return [ + (0x2F839, 'M', u'叫'), + (0x2F83A, 'M', u'叱'), + (0x2F83B, 'M', u'吆'), + (0x2F83C, 'M', u'咞'), + (0x2F83D, 'M', u'吸'), + (0x2F83E, 'M', u'呈'), + (0x2F83F, 'M', u'周'), + (0x2F840, 'M', u'咢'), + (0x2F841, 'M', u'哶'), + (0x2F842, 'M', u'唐'), + (0x2F843, 'M', u'啓'), + (0x2F844, 'M', u'啣'), + (0x2F845, 'M', u'善'), + (0x2F847, 'M', u'喙'), + (0x2F848, 'M', u'喫'), + (0x2F849, 'M', u'喳'), + (0x2F84A, 'M', u'嗂'), + (0x2F84B, 'M', u'圖'), + (0x2F84C, 'M', u'嘆'), + (0x2F84D, 'M', u'圗'), + (0x2F84E, 'M', u'噑'), + (0x2F84F, 'M', u'噴'), + (0x2F850, 'M', u'切'), + (0x2F851, 'M', u'壮'), + (0x2F852, 'M', u'城'), + (0x2F853, 'M', u'埴'), + (0x2F854, 'M', u'堍'), + (0x2F855, 'M', u'型'), + (0x2F856, 'M', u'堲'), + (0x2F857, 'M', u'報'), + (0x2F858, 'M', u'墬'), + (0x2F859, 'M', u'𡓤'), + (0x2F85A, 'M', u'売'), + (0x2F85B, 'M', u'壷'), + (0x2F85C, 'M', u'夆'), + (0x2F85D, 'M', u'多'), + (0x2F85E, 'M', u'夢'), + (0x2F85F, 'M', u'奢'), + (0x2F860, 'M', u'𡚨'), + (0x2F861, 'M', u'𡛪'), + (0x2F862, 'M', u'姬'), + (0x2F863, 'M', u'娛'), + (0x2F864, 'M', u'娧'), + (0x2F865, 'M', u'姘'), + (0x2F866, 'M', u'婦'), + (0x2F867, 'M', u'㛮'), + (0x2F868, 'X'), + (0x2F869, 'M', u'嬈'), + (0x2F86A, 'M', u'嬾'), + (0x2F86C, 'M', u'𡧈'), + (0x2F86D, 'M', u'寃'), + (0x2F86E, 'M', u'寘'), + (0x2F86F, 'M', u'寧'), + (0x2F870, 'M', u'寳'), + (0x2F871, 'M', u'𡬘'), + (0x2F872, 'M', u'寿'), + (0x2F873, 'M', u'将'), + (0x2F874, 'X'), + (0x2F875, 'M', u'尢'), + (0x2F876, 'M', u'㞁'), + (0x2F877, 'M', u'屠'), + (0x2F878, 'M', u'屮'), + (0x2F879, 'M', u'峀'), + (0x2F87A, 'M', u'岍'), + (0x2F87B, 'M', u'𡷤'), + (0x2F87C, 'M', u'嵃'), + (0x2F87D, 'M', u'𡷦'), + (0x2F87E, 'M', u'嵮'), + (0x2F87F, 'M', u'嵫'), + (0x2F880, 'M', u'嵼'), + (0x2F881, 'M', u'巡'), + (0x2F882, 'M', u'巢'), + (0x2F883, 'M', u'㠯'), + (0x2F884, 'M', u'巽'), + (0x2F885, 'M', u'帨'), + (0x2F886, 'M', u'帽'), + (0x2F887, 'M', u'幩'), + (0x2F888, 'M', u'㡢'), + (0x2F889, 'M', u'𢆃'), + (0x2F88A, 'M', u'㡼'), + (0x2F88B, 'M', u'庰'), + (0x2F88C, 'M', u'庳'), + (0x2F88D, 'M', u'庶'), + (0x2F88E, 'M', u'廊'), + (0x2F88F, 'M', u'𪎒'), + (0x2F890, 'M', u'廾'), + (0x2F891, 'M', u'𢌱'), + (0x2F893, 'M', u'舁'), + (0x2F894, 'M', u'弢'), + (0x2F896, 'M', u'㣇'), + (0x2F897, 'M', u'𣊸'), + (0x2F898, 'M', u'𦇚'), + (0x2F899, 'M', u'形'), + (0x2F89A, 'M', u'彫'), + (0x2F89B, 'M', u'㣣'), + (0x2F89C, 'M', u'徚'), + (0x2F89D, 'M', u'忍'), + (0x2F89E, 'M', u'志'), + (0x2F89F, 'M', u'忹'), + (0x2F8A0, 'M', u'悁'), + ] + +def _seg_74(): + return [ + (0x2F8A1, 'M', u'㤺'), + (0x2F8A2, 'M', u'㤜'), + (0x2F8A3, 'M', u'悔'), + (0x2F8A4, 'M', u'𢛔'), + (0x2F8A5, 'M', u'惇'), + (0x2F8A6, 'M', u'慈'), + (0x2F8A7, 'M', u'慌'), + (0x2F8A8, 'M', u'慎'), + (0x2F8A9, 'M', u'慌'), + (0x2F8AA, 'M', u'慺'), + (0x2F8AB, 'M', u'憎'), + (0x2F8AC, 'M', u'憲'), + (0x2F8AD, 'M', u'憤'), + (0x2F8AE, 'M', u'憯'), + (0x2F8AF, 'M', u'懞'), + (0x2F8B0, 'M', u'懲'), + (0x2F8B1, 'M', u'懶'), + (0x2F8B2, 'M', u'成'), + (0x2F8B3, 'M', u'戛'), + (0x2F8B4, 'M', u'扝'), + (0x2F8B5, 'M', u'抱'), + (0x2F8B6, 'M', u'拔'), + (0x2F8B7, 'M', u'捐'), + (0x2F8B8, 'M', u'𢬌'), + (0x2F8B9, 'M', u'挽'), + (0x2F8BA, 'M', u'拼'), + (0x2F8BB, 'M', u'捨'), + (0x2F8BC, 'M', u'掃'), + (0x2F8BD, 'M', u'揤'), + (0x2F8BE, 'M', u'𢯱'), + (0x2F8BF, 'M', u'搢'), + (0x2F8C0, 'M', u'揅'), + (0x2F8C1, 'M', u'掩'), + (0x2F8C2, 'M', u'㨮'), + (0x2F8C3, 'M', u'摩'), + (0x2F8C4, 'M', u'摾'), + (0x2F8C5, 'M', u'撝'), + (0x2F8C6, 'M', u'摷'), + (0x2F8C7, 'M', u'㩬'), + (0x2F8C8, 'M', u'敏'), + (0x2F8C9, 'M', u'敬'), + (0x2F8CA, 'M', u'𣀊'), + (0x2F8CB, 'M', u'旣'), + (0x2F8CC, 'M', u'書'), + (0x2F8CD, 'M', u'晉'), + (0x2F8CE, 'M', u'㬙'), + (0x2F8CF, 'M', u'暑'), + (0x2F8D0, 'M', u'㬈'), + (0x2F8D1, 'M', u'㫤'), + (0x2F8D2, 'M', u'冒'), + (0x2F8D3, 'M', u'冕'), + (0x2F8D4, 'M', u'最'), + (0x2F8D5, 'M', u'暜'), + (0x2F8D6, 'M', u'肭'), + (0x2F8D7, 'M', u'䏙'), + (0x2F8D8, 'M', u'朗'), + (0x2F8D9, 'M', u'望'), + (0x2F8DA, 'M', u'朡'), + (0x2F8DB, 'M', u'杞'), + (0x2F8DC, 'M', u'杓'), + (0x2F8DD, 'M', u'𣏃'), + (0x2F8DE, 'M', u'㭉'), + (0x2F8DF, 'M', u'柺'), + (0x2F8E0, 'M', u'枅'), + (0x2F8E1, 'M', u'桒'), + (0x2F8E2, 'M', u'梅'), + (0x2F8E3, 'M', u'𣑭'), + (0x2F8E4, 'M', u'梎'), + (0x2F8E5, 'M', u'栟'), + (0x2F8E6, 'M', u'椔'), + (0x2F8E7, 'M', u'㮝'), + (0x2F8E8, 'M', u'楂'), + (0x2F8E9, 'M', u'榣'), + (0x2F8EA, 'M', u'槪'), + (0x2F8EB, 'M', u'檨'), + (0x2F8EC, 'M', u'𣚣'), + (0x2F8ED, 'M', u'櫛'), + (0x2F8EE, 'M', u'㰘'), + (0x2F8EF, 'M', u'次'), + (0x2F8F0, 'M', u'𣢧'), + (0x2F8F1, 'M', u'歔'), + (0x2F8F2, 'M', u'㱎'), + (0x2F8F3, 'M', u'歲'), + (0x2F8F4, 'M', u'殟'), + (0x2F8F5, 'M', u'殺'), + (0x2F8F6, 'M', u'殻'), + (0x2F8F7, 'M', u'𣪍'), + (0x2F8F8, 'M', u'𡴋'), + (0x2F8F9, 'M', u'𣫺'), + (0x2F8FA, 'M', u'汎'), + (0x2F8FB, 'M', u'𣲼'), + (0x2F8FC, 'M', u'沿'), + (0x2F8FD, 'M', u'泍'), + (0x2F8FE, 'M', u'汧'), + (0x2F8FF, 'M', u'洖'), + (0x2F900, 'M', u'派'), + (0x2F901, 'M', u'海'), + (0x2F902, 'M', u'流'), + (0x2F903, 'M', u'浩'), + (0x2F904, 'M', u'浸'), + ] + +def _seg_75(): + return [ + (0x2F905, 'M', u'涅'), + (0x2F906, 'M', u'𣴞'), + (0x2F907, 'M', u'洴'), + (0x2F908, 'M', u'港'), + (0x2F909, 'M', u'湮'), + (0x2F90A, 'M', u'㴳'), + (0x2F90B, 'M', u'滋'), + (0x2F90C, 'M', u'滇'), + (0x2F90D, 'M', u'𣻑'), + (0x2F90E, 'M', u'淹'), + (0x2F90F, 'M', u'潮'), + (0x2F910, 'M', u'𣽞'), + (0x2F911, 'M', u'𣾎'), + (0x2F912, 'M', u'濆'), + (0x2F913, 'M', u'瀹'), + (0x2F914, 'M', u'瀞'), + (0x2F915, 'M', u'瀛'), + (0x2F916, 'M', u'㶖'), + (0x2F917, 'M', u'灊'), + (0x2F918, 'M', u'災'), + (0x2F919, 'M', u'灷'), + (0x2F91A, 'M', u'炭'), + (0x2F91B, 'M', u'𠔥'), + (0x2F91C, 'M', u'煅'), + (0x2F91D, 'M', u'𤉣'), + (0x2F91E, 'M', u'熜'), + (0x2F91F, 'X'), + (0x2F920, 'M', u'爨'), + (0x2F921, 'M', u'爵'), + (0x2F922, 'M', u'牐'), + (0x2F923, 'M', u'𤘈'), + (0x2F924, 'M', u'犀'), + (0x2F925, 'M', u'犕'), + (0x2F926, 'M', u'𤜵'), + (0x2F927, 'M', u'𤠔'), + (0x2F928, 'M', u'獺'), + (0x2F929, 'M', u'王'), + (0x2F92A, 'M', u'㺬'), + (0x2F92B, 'M', u'玥'), + (0x2F92C, 'M', u'㺸'), + (0x2F92E, 'M', u'瑇'), + (0x2F92F, 'M', u'瑜'), + (0x2F930, 'M', u'瑱'), + (0x2F931, 'M', u'璅'), + (0x2F932, 'M', u'瓊'), + (0x2F933, 'M', u'㼛'), + (0x2F934, 'M', u'甤'), + (0x2F935, 'M', u'𤰶'), + (0x2F936, 'M', u'甾'), + (0x2F937, 'M', u'𤲒'), + (0x2F938, 'M', u'異'), + (0x2F939, 'M', u'𢆟'), + (0x2F93A, 'M', u'瘐'), + (0x2F93B, 'M', u'𤾡'), + (0x2F93C, 'M', u'𤾸'), + (0x2F93D, 'M', u'𥁄'), + (0x2F93E, 'M', u'㿼'), + (0x2F93F, 'M', u'䀈'), + (0x2F940, 'M', u'直'), + (0x2F941, 'M', u'𥃳'), + (0x2F942, 'M', u'𥃲'), + (0x2F943, 'M', u'𥄙'), + (0x2F944, 'M', u'𥄳'), + (0x2F945, 'M', u'眞'), + (0x2F946, 'M', u'真'), + (0x2F948, 'M', u'睊'), + (0x2F949, 'M', u'䀹'), + (0x2F94A, 'M', u'瞋'), + (0x2F94B, 'M', u'䁆'), + (0x2F94C, 'M', u'䂖'), + (0x2F94D, 'M', u'𥐝'), + (0x2F94E, 'M', u'硎'), + (0x2F94F, 'M', u'碌'), + (0x2F950, 'M', u'磌'), + (0x2F951, 'M', u'䃣'), + (0x2F952, 'M', u'𥘦'), + (0x2F953, 'M', u'祖'), + (0x2F954, 'M', u'𥚚'), + (0x2F955, 'M', u'𥛅'), + (0x2F956, 'M', u'福'), + (0x2F957, 'M', u'秫'), + (0x2F958, 'M', u'䄯'), + (0x2F959, 'M', u'穀'), + (0x2F95A, 'M', u'穊'), + (0x2F95B, 'M', u'穏'), + (0x2F95C, 'M', u'𥥼'), + (0x2F95D, 'M', u'𥪧'), + (0x2F95F, 'X'), + (0x2F960, 'M', u'䈂'), + (0x2F961, 'M', u'𥮫'), + (0x2F962, 'M', u'篆'), + (0x2F963, 'M', u'築'), + (0x2F964, 'M', u'䈧'), + (0x2F965, 'M', u'𥲀'), + (0x2F966, 'M', u'糒'), + (0x2F967, 'M', u'䊠'), + (0x2F968, 'M', u'糨'), + (0x2F969, 'M', u'糣'), + (0x2F96A, 'M', u'紀'), + (0x2F96B, 'M', u'𥾆'), + ] + +def _seg_76(): + return [ + (0x2F96C, 'M', u'絣'), + (0x2F96D, 'M', u'䌁'), + (0x2F96E, 'M', u'緇'), + (0x2F96F, 'M', u'縂'), + (0x2F970, 'M', u'繅'), + (0x2F971, 'M', u'䌴'), + (0x2F972, 'M', u'𦈨'), + (0x2F973, 'M', u'𦉇'), + (0x2F974, 'M', u'䍙'), + (0x2F975, 'M', u'𦋙'), + (0x2F976, 'M', u'罺'), + (0x2F977, 'M', u'𦌾'), + (0x2F978, 'M', u'羕'), + (0x2F979, 'M', u'翺'), + (0x2F97A, 'M', u'者'), + (0x2F97B, 'M', u'𦓚'), + (0x2F97C, 'M', u'𦔣'), + (0x2F97D, 'M', u'聠'), + (0x2F97E, 'M', u'𦖨'), + (0x2F97F, 'M', u'聰'), + (0x2F980, 'M', u'𣍟'), + (0x2F981, 'M', u'䏕'), + (0x2F982, 'M', u'育'), + (0x2F983, 'M', u'脃'), + (0x2F984, 'M', u'䐋'), + (0x2F985, 'M', u'脾'), + (0x2F986, 'M', u'媵'), + (0x2F987, 'M', u'𦞧'), + (0x2F988, 'M', u'𦞵'), + (0x2F989, 'M', u'𣎓'), + (0x2F98A, 'M', u'𣎜'), + (0x2F98B, 'M', u'舁'), + (0x2F98C, 'M', u'舄'), + (0x2F98D, 'M', u'辞'), + (0x2F98E, 'M', u'䑫'), + (0x2F98F, 'M', u'芑'), + (0x2F990, 'M', u'芋'), + (0x2F991, 'M', u'芝'), + (0x2F992, 'M', u'劳'), + (0x2F993, 'M', u'花'), + (0x2F994, 'M', u'芳'), + (0x2F995, 'M', u'芽'), + (0x2F996, 'M', u'苦'), + (0x2F997, 'M', u'𦬼'), + (0x2F998, 'M', u'若'), + (0x2F999, 'M', u'茝'), + (0x2F99A, 'M', u'荣'), + (0x2F99B, 'M', u'莭'), + (0x2F99C, 'M', u'茣'), + (0x2F99D, 'M', u'莽'), + (0x2F99E, 'M', u'菧'), + (0x2F99F, 'M', u'著'), + (0x2F9A0, 'M', u'荓'), + (0x2F9A1, 'M', u'菊'), + (0x2F9A2, 'M', u'菌'), + (0x2F9A3, 'M', u'菜'), + (0x2F9A4, 'M', u'𦰶'), + (0x2F9A5, 'M', u'𦵫'), + (0x2F9A6, 'M', u'𦳕'), + (0x2F9A7, 'M', u'䔫'), + (0x2F9A8, 'M', u'蓱'), + (0x2F9A9, 'M', u'蓳'), + (0x2F9AA, 'M', u'蔖'), + (0x2F9AB, 'M', u'𧏊'), + (0x2F9AC, 'M', u'蕤'), + (0x2F9AD, 'M', u'𦼬'), + (0x2F9AE, 'M', u'䕝'), + (0x2F9AF, 'M', u'䕡'), + (0x2F9B0, 'M', u'𦾱'), + (0x2F9B1, 'M', u'𧃒'), + (0x2F9B2, 'M', u'䕫'), + (0x2F9B3, 'M', u'虐'), + (0x2F9B4, 'M', u'虜'), + (0x2F9B5, 'M', u'虧'), + (0x2F9B6, 'M', u'虩'), + (0x2F9B7, 'M', u'蚩'), + (0x2F9B8, 'M', u'蚈'), + (0x2F9B9, 'M', u'蜎'), + (0x2F9BA, 'M', u'蛢'), + (0x2F9BB, 'M', u'蝹'), + (0x2F9BC, 'M', u'蜨'), + (0x2F9BD, 'M', u'蝫'), + (0x2F9BE, 'M', u'螆'), + (0x2F9BF, 'X'), + (0x2F9C0, 'M', u'蟡'), + (0x2F9C1, 'M', u'蠁'), + (0x2F9C2, 'M', u'䗹'), + (0x2F9C3, 'M', u'衠'), + (0x2F9C4, 'M', u'衣'), + (0x2F9C5, 'M', u'𧙧'), + (0x2F9C6, 'M', u'裗'), + (0x2F9C7, 'M', u'裞'), + (0x2F9C8, 'M', u'䘵'), + (0x2F9C9, 'M', u'裺'), + (0x2F9CA, 'M', u'㒻'), + (0x2F9CB, 'M', u'𧢮'), + (0x2F9CC, 'M', u'𧥦'), + (0x2F9CD, 'M', u'䚾'), + (0x2F9CE, 'M', u'䛇'), + (0x2F9CF, 'M', u'誠'), + ] + +def _seg_77(): + return [ + (0x2F9D0, 'M', u'諭'), + (0x2F9D1, 'M', u'變'), + (0x2F9D2, 'M', u'豕'), + (0x2F9D3, 'M', u'𧲨'), + (0x2F9D4, 'M', u'貫'), + (0x2F9D5, 'M', u'賁'), + (0x2F9D6, 'M', u'贛'), + (0x2F9D7, 'M', u'起'), + (0x2F9D8, 'M', u'𧼯'), + (0x2F9D9, 'M', u'𠠄'), + (0x2F9DA, 'M', u'跋'), + (0x2F9DB, 'M', u'趼'), + (0x2F9DC, 'M', u'跰'), + (0x2F9DD, 'M', u'𠣞'), + (0x2F9DE, 'M', u'軔'), + (0x2F9DF, 'M', u'輸'), + (0x2F9E0, 'M', u'𨗒'), + (0x2F9E1, 'M', u'𨗭'), + (0x2F9E2, 'M', u'邔'), + (0x2F9E3, 'M', u'郱'), + (0x2F9E4, 'M', u'鄑'), + (0x2F9E5, 'M', u'𨜮'), + (0x2F9E6, 'M', u'鄛'), + (0x2F9E7, 'M', u'鈸'), + (0x2F9E8, 'M', u'鋗'), + (0x2F9E9, 'M', u'鋘'), + (0x2F9EA, 'M', u'鉼'), + (0x2F9EB, 'M', u'鏹'), + (0x2F9EC, 'M', u'鐕'), + (0x2F9ED, 'M', u'𨯺'), + (0x2F9EE, 'M', u'開'), + (0x2F9EF, 'M', u'䦕'), + (0x2F9F0, 'M', u'閷'), + (0x2F9F1, 'M', u'𨵷'), + (0x2F9F2, 'M', u'䧦'), + (0x2F9F3, 'M', u'雃'), + (0x2F9F4, 'M', u'嶲'), + (0x2F9F5, 'M', u'霣'), + (0x2F9F6, 'M', u'𩅅'), + (0x2F9F7, 'M', u'𩈚'), + (0x2F9F8, 'M', u'䩮'), + (0x2F9F9, 'M', u'䩶'), + (0x2F9FA, 'M', u'韠'), + (0x2F9FB, 'M', u'𩐊'), + (0x2F9FC, 'M', u'䪲'), + (0x2F9FD, 'M', u'𩒖'), + (0x2F9FE, 'M', u'頋'), + (0x2FA00, 'M', u'頩'), + (0x2FA01, 'M', u'𩖶'), + (0x2FA02, 'M', u'飢'), + (0x2FA03, 'M', u'䬳'), + (0x2FA04, 'M', u'餩'), + (0x2FA05, 'M', u'馧'), + (0x2FA06, 'M', u'駂'), + (0x2FA07, 'M', u'駾'), + (0x2FA08, 'M', u'䯎'), + (0x2FA09, 'M', u'𩬰'), + (0x2FA0A, 'M', u'鬒'), + (0x2FA0B, 'M', u'鱀'), + (0x2FA0C, 'M', u'鳽'), + (0x2FA0D, 'M', u'䳎'), + (0x2FA0E, 'M', u'䳭'), + (0x2FA0F, 'M', u'鵧'), + (0x2FA10, 'M', u'𪃎'), + (0x2FA11, 'M', u'䳸'), + (0x2FA12, 'M', u'𪄅'), + (0x2FA13, 'M', u'𪈎'), + (0x2FA14, 'M', u'𪊑'), + (0x2FA15, 'M', u'麻'), + (0x2FA16, 'M', u'䵖'), + (0x2FA17, 'M', u'黹'), + (0x2FA18, 'M', u'黾'), + (0x2FA19, 'M', u'鼅'), + (0x2FA1A, 'M', u'鼏'), + (0x2FA1B, 'M', u'鼖'), + (0x2FA1C, 'M', u'鼻'), + (0x2FA1D, 'M', u'𪘀'), + (0x2FA1E, 'X'), + (0xE0100, 'I'), + (0xE01F0, 'X'), + ] + +uts46data = tuple( + _seg_0() + + _seg_1() + + _seg_2() + + _seg_3() + + _seg_4() + + _seg_5() + + _seg_6() + + _seg_7() + + _seg_8() + + _seg_9() + + _seg_10() + + _seg_11() + + _seg_12() + + _seg_13() + + _seg_14() + + _seg_15() + + _seg_16() + + _seg_17() + + _seg_18() + + _seg_19() + + _seg_20() + + _seg_21() + + _seg_22() + + _seg_23() + + _seg_24() + + _seg_25() + + _seg_26() + + _seg_27() + + _seg_28() + + _seg_29() + + _seg_30() + + _seg_31() + + _seg_32() + + _seg_33() + + _seg_34() + + _seg_35() + + _seg_36() + + _seg_37() + + _seg_38() + + _seg_39() + + _seg_40() + + _seg_41() + + _seg_42() + + _seg_43() + + _seg_44() + + _seg_45() + + _seg_46() + + _seg_47() + + _seg_48() + + _seg_49() + + _seg_50() + + _seg_51() + + _seg_52() + + _seg_53() + + _seg_54() + + _seg_55() + + _seg_56() + + _seg_57() + + _seg_58() + + _seg_59() + + _seg_60() + + _seg_61() + + _seg_62() + + _seg_63() + + _seg_64() + + _seg_65() + + _seg_66() + + _seg_67() + + _seg_68() + + _seg_69() + + _seg_70() + + _seg_71() + + _seg_72() + + _seg_73() + + _seg_74() + + _seg_75() + + _seg_76() + + _seg_77() +) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/ipaddress.py b/env/lib/python3.7/site-packages/pip/_vendor/ipaddress.py new file mode 100644 index 0000000..f2d0766 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/ipaddress.py @@ -0,0 +1,2419 @@ +# Copyright 2007 Google Inc. +# Licensed to PSF under a Contributor Agreement. + +"""A fast, lightweight IPv4/IPv6 manipulation library in Python. + +This library is used to create/poke/manipulate IPv4 and IPv6 addresses +and networks. + +""" + +from __future__ import unicode_literals + + +import itertools +import struct + +__version__ = '1.0.22' + +# Compatibility functions +_compat_int_types = (int,) +try: + _compat_int_types = (int, long) +except NameError: + pass +try: + _compat_str = unicode +except NameError: + _compat_str = str + assert bytes != str +if b'\0'[0] == 0: # Python 3 semantics + def _compat_bytes_to_byte_vals(byt): + return byt +else: + def _compat_bytes_to_byte_vals(byt): + return [struct.unpack(b'!B', b)[0] for b in byt] +try: + _compat_int_from_byte_vals = int.from_bytes +except AttributeError: + def _compat_int_from_byte_vals(bytvals, endianess): + assert endianess == 'big' + res = 0 + for bv in bytvals: + assert isinstance(bv, _compat_int_types) + res = (res << 8) + bv + return res + + +def _compat_to_bytes(intval, length, endianess): + assert isinstance(intval, _compat_int_types) + assert endianess == 'big' + if length == 4: + if intval < 0 or intval >= 2 ** 32: + raise struct.error("integer out of range for 'I' format code") + return struct.pack(b'!I', intval) + elif length == 16: + if intval < 0 or intval >= 2 ** 128: + raise struct.error("integer out of range for 'QQ' format code") + return struct.pack(b'!QQ', intval >> 64, intval & 0xffffffffffffffff) + else: + raise NotImplementedError() + + +if hasattr(int, 'bit_length'): + # Not int.bit_length , since that won't work in 2.7 where long exists + def _compat_bit_length(i): + return i.bit_length() +else: + def _compat_bit_length(i): + for res in itertools.count(): + if i >> res == 0: + return res + + +def _compat_range(start, end, step=1): + assert step > 0 + i = start + while i < end: + yield i + i += step + + +class _TotalOrderingMixin(object): + __slots__ = () + + # Helper that derives the other comparison operations from + # __lt__ and __eq__ + # We avoid functools.total_ordering because it doesn't handle + # NotImplemented correctly yet (http://bugs.python.org/issue10042) + def __eq__(self, other): + raise NotImplementedError + + def __ne__(self, other): + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not equal + + def __lt__(self, other): + raise NotImplementedError + + def __le__(self, other): + less = self.__lt__(other) + if less is NotImplemented or not less: + return self.__eq__(other) + return less + + def __gt__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + equal = self.__eq__(other) + if equal is NotImplemented: + return NotImplemented + return not (less or equal) + + def __ge__(self, other): + less = self.__lt__(other) + if less is NotImplemented: + return NotImplemented + return not less + + +IPV4LENGTH = 32 +IPV6LENGTH = 128 + + +class AddressValueError(ValueError): + """A Value Error related to the address.""" + + +class NetmaskValueError(ValueError): + """A Value Error related to the netmask.""" + + +def ip_address(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Address or IPv6Address object. + + Raises: + ValueError: if the *address* passed isn't either a v4 or a v6 + address + + """ + try: + return IPv4Address(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Address(address) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 address' % + address) + + +def ip_network(address, strict=True): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP network. Either IPv4 or + IPv6 networks may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Network or IPv6Network object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. Or if the network has host bits set. + + """ + try: + return IPv4Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Network(address, strict) + except (AddressValueError, NetmaskValueError): + pass + + if isinstance(address, bytes): + raise AddressValueError( + '%r does not appear to be an IPv4 or IPv6 network. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?' % address) + + raise ValueError('%r does not appear to be an IPv4 or IPv6 network' % + address) + + +def ip_interface(address): + """Take an IP string/int and return an object of the correct type. + + Args: + address: A string or integer, the IP address. Either IPv4 or + IPv6 addresses may be supplied; integers less than 2**32 will + be considered to be IPv4 by default. + + Returns: + An IPv4Interface or IPv6Interface object. + + Raises: + ValueError: if the string passed isn't either a v4 or a v6 + address. + + Notes: + The IPv?Interface classes describe an Address on a particular + Network, so they're basically a combination of both the Address + and Network classes. + + """ + try: + return IPv4Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + try: + return IPv6Interface(address) + except (AddressValueError, NetmaskValueError): + pass + + raise ValueError('%r does not appear to be an IPv4 or IPv6 interface' % + address) + + +def v4_int_to_packed(address): + """Represent an address as 4 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv4 IP address. + + Returns: + The integer address packed as 4 bytes in network (big-endian) order. + + Raises: + ValueError: If the integer is negative or too large to be an + IPv4 IP address. + + """ + try: + return _compat_to_bytes(address, 4, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv4") + + +def v6_int_to_packed(address): + """Represent an address as 16 packed bytes in network (big-endian) order. + + Args: + address: An integer representation of an IPv6 IP address. + + Returns: + The integer address packed as 16 bytes in network (big-endian) order. + + """ + try: + return _compat_to_bytes(address, 16, 'big') + except (struct.error, OverflowError): + raise ValueError("Address negative or too large for IPv6") + + +def _split_optional_netmask(address): + """Helper to split the netmask and raise AddressValueError if needed""" + addr = _compat_str(address).split('/') + if len(addr) > 2: + raise AddressValueError("Only one '/' permitted in %r" % address) + return addr + + +def _find_address_range(addresses): + """Find a sequence of sorted deduplicated IPv#Address. + + Args: + addresses: a list of IPv#Address objects. + + Yields: + A tuple containing the first and last IP addresses in the sequence. + + """ + it = iter(addresses) + first = last = next(it) + for ip in it: + if ip._ip != last._ip + 1: + yield first, last + first = ip + last = ip + yield first, last + + +def _count_righthand_zero_bits(number, bits): + """Count the number of zero bits on the right hand side. + + Args: + number: an integer. + bits: maximum number of bits to count. + + Returns: + The number of zero bits on the right hand side of the number. + + """ + if number == 0: + return bits + return min(bits, _compat_bit_length(~number & (number - 1))) + + +def summarize_address_range(first, last): + """Summarize a network range given the first and last IP addresses. + + Example: + >>> list(summarize_address_range(IPv4Address('192.0.2.0'), + ... IPv4Address('192.0.2.130'))) + ... #doctest: +NORMALIZE_WHITESPACE + [IPv4Network('192.0.2.0/25'), IPv4Network('192.0.2.128/31'), + IPv4Network('192.0.2.130/32')] + + Args: + first: the first IPv4Address or IPv6Address in the range. + last: the last IPv4Address or IPv6Address in the range. + + Returns: + An iterator of the summarized IPv(4|6) network objects. + + Raise: + TypeError: + If the first and last objects are not IP addresses. + If the first and last objects are not the same version. + ValueError: + If the last object is not greater than the first. + If the version of the first address is not 4 or 6. + + """ + if (not (isinstance(first, _BaseAddress) and + isinstance(last, _BaseAddress))): + raise TypeError('first and last must be IP addresses, not networks') + if first.version != last.version: + raise TypeError("%s and %s are not of the same version" % ( + first, last)) + if first > last: + raise ValueError('last IP address must be greater than first') + + if first.version == 4: + ip = IPv4Network + elif first.version == 6: + ip = IPv6Network + else: + raise ValueError('unknown IP version') + + ip_bits = first._max_prefixlen + first_int = first._ip + last_int = last._ip + while first_int <= last_int: + nbits = min(_count_righthand_zero_bits(first_int, ip_bits), + _compat_bit_length(last_int - first_int + 1) - 1) + net = ip((first_int, ip_bits - nbits)) + yield net + first_int += 1 << nbits + if first_int - 1 == ip._ALL_ONES: + break + + +def _collapse_addresses_internal(addresses): + """Loops through the addresses, collapsing concurrent netblocks. + + Example: + + ip1 = IPv4Network('192.0.2.0/26') + ip2 = IPv4Network('192.0.2.64/26') + ip3 = IPv4Network('192.0.2.128/26') + ip4 = IPv4Network('192.0.2.192/26') + + _collapse_addresses_internal([ip1, ip2, ip3, ip4]) -> + [IPv4Network('192.0.2.0/24')] + + This shouldn't be called directly; it is called via + collapse_addresses([]). + + Args: + addresses: A list of IPv4Network's or IPv6Network's + + Returns: + A list of IPv4Network's or IPv6Network's depending on what we were + passed. + + """ + # First merge + to_merge = list(addresses) + subnets = {} + while to_merge: + net = to_merge.pop() + supernet = net.supernet() + existing = subnets.get(supernet) + if existing is None: + subnets[supernet] = net + elif existing != net: + # Merge consecutive subnets + del subnets[supernet] + to_merge.append(supernet) + # Then iterate over resulting networks, skipping subsumed subnets + last = None + for net in sorted(subnets.values()): + if last is not None: + # Since they are sorted, + # last.network_address <= net.network_address is a given. + if last.broadcast_address >= net.broadcast_address: + continue + yield net + last = net + + +def collapse_addresses(addresses): + """Collapse a list of IP objects. + + Example: + collapse_addresses([IPv4Network('192.0.2.0/25'), + IPv4Network('192.0.2.128/25')]) -> + [IPv4Network('192.0.2.0/24')] + + Args: + addresses: An iterator of IPv4Network or IPv6Network objects. + + Returns: + An iterator of the collapsed IPv(4|6)Network objects. + + Raises: + TypeError: If passed a list of mixed version objects. + + """ + addrs = [] + ips = [] + nets = [] + + # split IP addresses and networks + for ip in addresses: + if isinstance(ip, _BaseAddress): + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + ips.append(ip) + elif ip._prefixlen == ip._max_prefixlen: + if ips and ips[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, ips[-1])) + try: + ips.append(ip.ip) + except AttributeError: + ips.append(ip.network_address) + else: + if nets and nets[-1]._version != ip._version: + raise TypeError("%s and %s are not of the same version" % ( + ip, nets[-1])) + nets.append(ip) + + # sort and dedup + ips = sorted(set(ips)) + + # find consecutive address ranges in the sorted sequence and summarize them + if ips: + for first, last in _find_address_range(ips): + addrs.extend(summarize_address_range(first, last)) + + return _collapse_addresses_internal(addrs + nets) + + +def get_mixed_type_key(obj): + """Return a key suitable for sorting between networks and addresses. + + Address and Network objects are not sortable by default; they're + fundamentally different so the expression + + IPv4Address('192.0.2.0') <= IPv4Network('192.0.2.0/24') + + doesn't make any sense. There are some times however, where you may wish + to have ipaddress sort these for you anyway. If you need to do this, you + can use this function as the key= argument to sorted(). + + Args: + obj: either a Network or Address object. + Returns: + appropriate key. + + """ + if isinstance(obj, _BaseNetwork): + return obj._get_networks_key() + elif isinstance(obj, _BaseAddress): + return obj._get_address_key() + return NotImplemented + + +class _IPAddressBase(_TotalOrderingMixin): + + """The mother class.""" + + __slots__ = () + + @property + def exploded(self): + """Return the longhand version of the IP address as a string.""" + return self._explode_shorthand_ip_string() + + @property + def compressed(self): + """Return the shorthand version of the IP address as a string.""" + return _compat_str(self) + + @property + def reverse_pointer(self): + """The name of the reverse DNS pointer for the IP address, e.g.: + >>> ipaddress.ip_address("127.0.0.1").reverse_pointer + '1.0.0.127.in-addr.arpa' + >>> ipaddress.ip_address("2001:db8::1").reverse_pointer + '1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa' + + """ + return self._reverse_pointer() + + @property + def version(self): + msg = '%200s has no version specified' % (type(self),) + raise NotImplementedError(msg) + + def _check_int_address(self, address): + if address < 0: + msg = "%d (< 0) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._version)) + if address > self._ALL_ONES: + msg = "%d (>= 2**%d) is not permitted as an IPv%d address" + raise AddressValueError(msg % (address, self._max_prefixlen, + self._version)) + + def _check_packed_address(self, address, expected_len): + address_len = len(address) + if address_len != expected_len: + msg = ( + '%r (len %d != %d) is not permitted as an IPv%d address. ' + 'Did you pass in a bytes (str in Python 2) instead of' + ' a unicode object?') + raise AddressValueError(msg % (address, address_len, + expected_len, self._version)) + + @classmethod + def _ip_int_from_prefix(cls, prefixlen): + """Turn the prefix length into a bitwise netmask + + Args: + prefixlen: An integer, the prefix length. + + Returns: + An integer. + + """ + return cls._ALL_ONES ^ (cls._ALL_ONES >> prefixlen) + + @classmethod + def _prefix_from_ip_int(cls, ip_int): + """Return prefix length from the bitwise netmask. + + Args: + ip_int: An integer, the netmask in expanded bitwise format + + Returns: + An integer, the prefix length. + + Raises: + ValueError: If the input intermingles zeroes & ones + """ + trailing_zeroes = _count_righthand_zero_bits(ip_int, + cls._max_prefixlen) + prefixlen = cls._max_prefixlen - trailing_zeroes + leading_ones = ip_int >> trailing_zeroes + all_ones = (1 << prefixlen) - 1 + if leading_ones != all_ones: + byteslen = cls._max_prefixlen // 8 + details = _compat_to_bytes(ip_int, byteslen, 'big') + msg = 'Netmask pattern %r mixes zeroes & ones' + raise ValueError(msg % details) + return prefixlen + + @classmethod + def _report_invalid_netmask(cls, netmask_str): + msg = '%r is not a valid netmask' % netmask_str + raise NetmaskValueError(msg) + + @classmethod + def _prefix_from_prefix_string(cls, prefixlen_str): + """Return prefix length from a numeric string + + Args: + prefixlen_str: The string to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask + """ + # int allows a leading +/- as well as surrounding whitespace, + # so we ensure that isn't the case + if not _BaseV4._DECIMAL_DIGITS.issuperset(prefixlen_str): + cls._report_invalid_netmask(prefixlen_str) + try: + prefixlen = int(prefixlen_str) + except ValueError: + cls._report_invalid_netmask(prefixlen_str) + if not (0 <= prefixlen <= cls._max_prefixlen): + cls._report_invalid_netmask(prefixlen_str) + return prefixlen + + @classmethod + def _prefix_from_ip_string(cls, ip_str): + """Turn a netmask/hostmask string into a prefix length + + Args: + ip_str: The netmask/hostmask to be converted + + Returns: + An integer, the prefix length. + + Raises: + NetmaskValueError: If the input is not a valid netmask/hostmask + """ + # Parse the netmask/hostmask like an IP address. + try: + ip_int = cls._ip_int_from_string(ip_str) + except AddressValueError: + cls._report_invalid_netmask(ip_str) + + # Try matching a netmask (this would be /1*0*/ as a bitwise regexp). + # Note that the two ambiguous cases (all-ones and all-zeroes) are + # treated as netmasks. + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + pass + + # Invert the bits, and try matching a /0+1+/ hostmask instead. + ip_int ^= cls._ALL_ONES + try: + return cls._prefix_from_ip_int(ip_int) + except ValueError: + cls._report_invalid_netmask(ip_str) + + def __reduce__(self): + return self.__class__, (_compat_str(self),) + + +class _BaseAddress(_IPAddressBase): + + """A generic IP object. + + This IP class contains the version independent methods which are + used by single IP addresses. + """ + + __slots__ = () + + def __int__(self): + return self._ip + + def __eq__(self, other): + try: + return (self._ip == other._ip and + self._version == other._version) + except AttributeError: + return NotImplemented + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseAddress): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self._ip != other._ip: + return self._ip < other._ip + return False + + # Shorthand for Integer addition and subtraction. This is not + # meant to ever support addition/subtraction of addresses. + def __add__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) + other) + + def __sub__(self, other): + if not isinstance(other, _compat_int_types): + return NotImplemented + return self.__class__(int(self) - other) + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return _compat_str(self._string_from_ip_int(self._ip)) + + def __hash__(self): + return hash(hex(int(self._ip))) + + def _get_address_key(self): + return (self._version, self) + + def __reduce__(self): + return self.__class__, (self._ip,) + + +class _BaseNetwork(_IPAddressBase): + + """A generic IP network object. + + This IP class contains the version independent methods which are + used by networks. + + """ + def __init__(self, address): + self._cache = {} + + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, _compat_str(self)) + + def __str__(self): + return '%s/%d' % (self.network_address, self.prefixlen) + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the network + or broadcast addresses. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast): + yield self._address_class(x) + + def __iter__(self): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network, broadcast + 1): + yield self._address_class(x) + + def __getitem__(self, n): + network = int(self.network_address) + broadcast = int(self.broadcast_address) + if n >= 0: + if network + n > broadcast: + raise IndexError('address out of range') + return self._address_class(network + n) + else: + n += 1 + if broadcast + n < network: + raise IndexError('address out of range') + return self._address_class(broadcast + n) + + def __lt__(self, other): + if not isinstance(other, _IPAddressBase): + return NotImplemented + if not isinstance(other, _BaseNetwork): + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + if self._version != other._version: + raise TypeError('%s and %s are not of the same version' % ( + self, other)) + if self.network_address != other.network_address: + return self.network_address < other.network_address + if self.netmask != other.netmask: + return self.netmask < other.netmask + return False + + def __eq__(self, other): + try: + return (self._version == other._version and + self.network_address == other.network_address and + int(self.netmask) == int(other.netmask)) + except AttributeError: + return NotImplemented + + def __hash__(self): + return hash(int(self.network_address) ^ int(self.netmask)) + + def __contains__(self, other): + # always false if one is v4 and the other is v6. + if self._version != other._version: + return False + # dealing with another network. + if isinstance(other, _BaseNetwork): + return False + # dealing with another address + else: + # address + return (int(self.network_address) <= int(other._ip) <= + int(self.broadcast_address)) + + def overlaps(self, other): + """Tell if self is partly contained in other.""" + return self.network_address in other or ( + self.broadcast_address in other or ( + other.network_address in self or ( + other.broadcast_address in self))) + + @property + def broadcast_address(self): + x = self._cache.get('broadcast_address') + if x is None: + x = self._address_class(int(self.network_address) | + int(self.hostmask)) + self._cache['broadcast_address'] = x + return x + + @property + def hostmask(self): + x = self._cache.get('hostmask') + if x is None: + x = self._address_class(int(self.netmask) ^ self._ALL_ONES) + self._cache['hostmask'] = x + return x + + @property + def with_prefixlen(self): + return '%s/%d' % (self.network_address, self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self.network_address, self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self.network_address, self.hostmask) + + @property + def num_addresses(self): + """Number of hosts in the current subnet.""" + return int(self.broadcast_address) - int(self.network_address) + 1 + + @property + def _address_class(self): + # Returning bare address objects (rather than interfaces) allows for + # more consistent behaviour across the network address, broadcast + # address and individual host addresses. + msg = '%200s has no associated address class' % (type(self),) + raise NotImplementedError(msg) + + @property + def prefixlen(self): + return self._prefixlen + + def address_exclude(self, other): + """Remove an address from a larger block. + + For example: + + addr1 = ip_network('192.0.2.0/28') + addr2 = ip_network('192.0.2.1/32') + list(addr1.address_exclude(addr2)) = + [IPv4Network('192.0.2.0/32'), IPv4Network('192.0.2.2/31'), + IPv4Network('192.0.2.4/30'), IPv4Network('192.0.2.8/29')] + + or IPv6: + + addr1 = ip_network('2001:db8::1/32') + addr2 = ip_network('2001:db8::1/128') + list(addr1.address_exclude(addr2)) = + [ip_network('2001:db8::1/128'), + ip_network('2001:db8::2/127'), + ip_network('2001:db8::4/126'), + ip_network('2001:db8::8/125'), + ... + ip_network('2001:db8:8000::/33')] + + Args: + other: An IPv4Network or IPv6Network object of the same type. + + Returns: + An iterator of the IPv(4|6)Network objects which is self + minus other. + + Raises: + TypeError: If self and other are of differing address + versions, or if other is not a network object. + ValueError: If other is not completely contained by self. + + """ + if not self._version == other._version: + raise TypeError("%s and %s are not of the same version" % ( + self, other)) + + if not isinstance(other, _BaseNetwork): + raise TypeError("%s is not a network object" % other) + + if not other.subnet_of(self): + raise ValueError('%s not contained in %s' % (other, self)) + if other == self: + return + + # Make sure we're comparing the network of other. + other = other.__class__('%s/%s' % (other.network_address, + other.prefixlen)) + + s1, s2 = self.subnets() + while s1 != other and s2 != other: + if other.subnet_of(s1): + yield s2 + s1, s2 = s1.subnets() + elif other.subnet_of(s2): + yield s1 + s1, s2 = s2.subnets() + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + if s1 == other: + yield s2 + elif s2 == other: + yield s1 + else: + # If we got here, there's a bug somewhere. + raise AssertionError('Error performing exclusion: ' + 's1: %s s2: %s other: %s' % + (s1, s2, other)) + + def compare_networks(self, other): + """Compare two IP objects. + + This is only concerned about the comparison of the integer + representation of the network addresses. This means that the + host bits aren't considered at all in this method. If you want + to compare host bits, you can easily enough do a + 'HostA._ip < HostB._ip' + + Args: + other: An IP object. + + Returns: + If the IP versions of self and other are the same, returns: + + -1 if self < other: + eg: IPv4Network('192.0.2.0/25') < IPv4Network('192.0.2.128/25') + IPv6Network('2001:db8::1000/124') < + IPv6Network('2001:db8::2000/124') + 0 if self == other + eg: IPv4Network('192.0.2.0/24') == IPv4Network('192.0.2.0/24') + IPv6Network('2001:db8::1000/124') == + IPv6Network('2001:db8::1000/124') + 1 if self > other + eg: IPv4Network('192.0.2.128/25') > IPv4Network('192.0.2.0/25') + IPv6Network('2001:db8::2000/124') > + IPv6Network('2001:db8::1000/124') + + Raises: + TypeError if the IP versions are different. + + """ + # does this need to raise a ValueError? + if self._version != other._version: + raise TypeError('%s and %s are not of the same type' % ( + self, other)) + # self._version == other._version below here: + if self.network_address < other.network_address: + return -1 + if self.network_address > other.network_address: + return 1 + # self.network_address == other.network_address below here: + if self.netmask < other.netmask: + return -1 + if self.netmask > other.netmask: + return 1 + return 0 + + def _get_networks_key(self): + """Network-only key function. + + Returns an object that identifies this address' network and + netmask. This function is a suitable "key" argument for sorted() + and list.sort(). + + """ + return (self._version, self.network_address, self.netmask) + + def subnets(self, prefixlen_diff=1, new_prefix=None): + """The subnets which join to make the current subnet. + + In the case that self contains only one IP + (self._prefixlen == 32 for IPv4 or self._prefixlen == 128 + for IPv6), yield an iterator with just ourself. + + Args: + prefixlen_diff: An integer, the amount the prefix length + should be increased by. This should not be set if + new_prefix is also set. + new_prefix: The desired new prefix length. This must be a + larger number (smaller prefix) than the existing prefix. + This should not be set if prefixlen_diff is also set. + + Returns: + An iterator of IPv(4|6) objects. + + Raises: + ValueError: The prefixlen_diff is too small or too large. + OR + prefixlen_diff and new_prefix are both set or new_prefix + is a smaller number than the current prefix (smaller + number means a larger network) + + """ + if self._prefixlen == self._max_prefixlen: + yield self + return + + if new_prefix is not None: + if new_prefix < self._prefixlen: + raise ValueError('new prefix must be longer') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = new_prefix - self._prefixlen + + if prefixlen_diff < 0: + raise ValueError('prefix length diff must be > 0') + new_prefixlen = self._prefixlen + prefixlen_diff + + if new_prefixlen > self._max_prefixlen: + raise ValueError( + 'prefix length diff %d is invalid for netblock %s' % ( + new_prefixlen, self)) + + start = int(self.network_address) + end = int(self.broadcast_address) + 1 + step = (int(self.hostmask) + 1) >> prefixlen_diff + for new_addr in _compat_range(start, end, step): + current = self.__class__((new_addr, new_prefixlen)) + yield current + + def supernet(self, prefixlen_diff=1, new_prefix=None): + """The supernet containing the current network. + + Args: + prefixlen_diff: An integer, the amount the prefix length of + the network should be decreased by. For example, given a + /24 network and a prefixlen_diff of 3, a supernet with a + /21 netmask is returned. + + Returns: + An IPv4 network object. + + Raises: + ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have + a negative prefix length. + OR + If prefixlen_diff and new_prefix are both set or new_prefix is a + larger number than the current prefix (larger number means a + smaller network) + + """ + if self._prefixlen == 0: + return self + + if new_prefix is not None: + if new_prefix > self._prefixlen: + raise ValueError('new prefix must be shorter') + if prefixlen_diff != 1: + raise ValueError('cannot set prefixlen_diff and new_prefix') + prefixlen_diff = self._prefixlen - new_prefix + + new_prefixlen = self.prefixlen - prefixlen_diff + if new_prefixlen < 0: + raise ValueError( + 'current prefixlen is %d, cannot have a prefixlen_diff of %d' % + (self.prefixlen, prefixlen_diff)) + return self.__class__(( + int(self.network_address) & (int(self.netmask) << prefixlen_diff), + new_prefixlen)) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return (self.network_address.is_multicast and + self.broadcast_address.is_multicast) + + @staticmethod + def _is_subnet_of(a, b): + try: + # Always false if one is v4 and the other is v6. + if a._version != b._version: + raise TypeError("%s and %s are not of the same version" (a, b)) + return (b.network_address <= a.network_address and + b.broadcast_address >= a.broadcast_address) + except AttributeError: + raise TypeError("Unable to test subnet containment " + "between %s and %s" % (a, b)) + + def subnet_of(self, other): + """Return True if this network is a subnet of other.""" + return self._is_subnet_of(self, other) + + def supernet_of(self, other): + """Return True if this network is a supernet of other.""" + return self._is_subnet_of(other, self) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return (self.network_address.is_reserved and + self.broadcast_address.is_reserved) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return (self.network_address.is_link_local and + self.broadcast_address.is_link_local) + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return (self.network_address.is_private and + self.broadcast_address.is_private) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry or iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return (self.network_address.is_unspecified and + self.broadcast_address.is_unspecified) + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return (self.network_address.is_loopback and + self.broadcast_address.is_loopback) + + +class _BaseV4(object): + + """Base IPv4 object. + + The following methods are used by IPv4 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 4 + # Equivalent to 255.255.255.255 or 32 bits of 1's. + _ALL_ONES = (2 ** IPV4LENGTH) - 1 + _DECIMAL_DIGITS = frozenset('0123456789') + + # the valid octets for host and netmasks. only useful for IPv4. + _valid_mask_octets = frozenset([255, 254, 252, 248, 240, 224, 192, 128, 0]) + + _max_prefixlen = IPV4LENGTH + # There are only a handful of valid v4 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + def _explode_shorthand_ip_string(self): + return _compat_str(self) + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + try: + # Check for a netmask in prefix length form + prefixlen = cls._prefix_from_prefix_string(arg) + except NetmaskValueError: + # Check for a netmask or hostmask in dotted-quad form. + # This may raise NetmaskValueError. + prefixlen = cls._prefix_from_ip_string(arg) + netmask = IPv4Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn the given IP string into an integer for comparison. + + Args: + ip_str: A string, the IP ip_str. + + Returns: + The IP ip_str as an integer. + + Raises: + AddressValueError: if ip_str isn't a valid IPv4 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + octets = ip_str.split('.') + if len(octets) != 4: + raise AddressValueError("Expected 4 octets in %r" % ip_str) + + try: + return _compat_int_from_byte_vals( + map(cls._parse_octet, octets), 'big') + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_octet(cls, octet_str): + """Convert a decimal octet into an integer. + + Args: + octet_str: A string, the number to parse. + + Returns: + The octet as an integer. + + Raises: + ValueError: if the octet isn't strictly a decimal from [0..255]. + + """ + if not octet_str: + raise ValueError("Empty octet not permitted") + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._DECIMAL_DIGITS.issuperset(octet_str): + msg = "Only decimal digits permitted in %r" + raise ValueError(msg % octet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(octet_str) > 3: + msg = "At most 3 characters permitted in %r" + raise ValueError(msg % octet_str) + # Convert to integer (we know digits are legal) + octet_int = int(octet_str, 10) + # Any octets that look like they *might* be written in octal, + # and which don't look exactly the same in both octal and + # decimal are rejected as ambiguous + if octet_int > 7 and octet_str[0] == '0': + msg = "Ambiguous (octal/decimal) value in %r not permitted" + raise ValueError(msg % octet_str) + if octet_int > 255: + raise ValueError("Octet %d (> 255) not permitted" % octet_int) + return octet_int + + @classmethod + def _string_from_ip_int(cls, ip_int): + """Turns a 32-bit integer into dotted decimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + The IP address as a string in dotted decimal notation. + + """ + return '.'.join(_compat_str(struct.unpack(b'!B', b)[0] + if isinstance(b, bytes) + else b) + for b in _compat_to_bytes(ip_int, 4, 'big')) + + def _is_hostmask(self, ip_str): + """Test if the IP string is a hostmask (rather than a netmask). + + Args: + ip_str: A string, the potential hostmask. + + Returns: + A boolean, True if the IP string is a hostmask. + + """ + bits = ip_str.split('.') + try: + parts = [x for x in map(int, bits) if x in self._valid_mask_octets] + except ValueError: + return False + if len(parts) != len(bits): + return False + if parts[0] < parts[-1]: + return True + return False + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv4 address. + + This implements the method described in RFC1035 3.5. + + """ + reverse_octets = _compat_str(self).split('.')[::-1] + return '.'.join(reverse_octets) + '.in-addr.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv4Address(_BaseV4, _BaseAddress): + + """Represent and manipulate single IPv4 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + + """ + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv4Address('192.0.2.1') == IPv4Address(3221225985). + or, more generally + IPv4Address(int(IPv4Address('192.0.2.1'))) == + IPv4Address('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 4) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v4_int_to_packed(self._ip) + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within the + reserved IPv4 Network range. + + """ + return self in self._constants._reserved_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv4-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + return ( + self not in self._constants._public_network and + not self.is_private) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is multicast. + See RFC 3171 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 5735 3. + + """ + return self == self._constants._unspecified_address + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback per RFC 3330. + + """ + return self in self._constants._loopback_network + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is link-local per RFC 3927. + + """ + return self in self._constants._linklocal_network + + +class IPv4Interface(IPv4Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv4Address.__init__(self, address) + self.network = IPv4Network(self._ip) + self._prefixlen = self._max_prefixlen + return + + if isinstance(address, tuple): + IPv4Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + + self.network = IPv4Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv4Address.__init__(self, addr[0]) + + self.network = IPv4Network(address, strict=False) + self._prefixlen = self.network._prefixlen + + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv4Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv4Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv4Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + +class IPv4Network(_BaseV4, _BaseNetwork): + + """This class represents and manipulates 32-bit IPv4 network + addresses.. + + Attributes: [examples for IPv4Network('192.0.2.0/27')] + .network_address: IPv4Address('192.0.2.0') + .hostmask: IPv4Address('0.0.0.31') + .broadcast_address: IPv4Address('192.0.2.32') + .netmask: IPv4Address('255.255.255.224') + .prefixlen: 27 + + """ + # Class to use when creating address objects + _address_class = IPv4Address + + def __init__(self, address, strict=True): + + """Instantiate a new IPv4 network object. + + Args: + address: A string or integer representing the IP [& network]. + '192.0.2.0/24' + '192.0.2.0/255.255.255.0' + '192.0.0.2/0.0.0.255' + are all functionally the same in IPv4. Similarly, + '192.0.2.1' + '192.0.2.1/255.255.255.255' + '192.0.2.1/32' + are also functionally equivalent. That is to say, failing to + provide a subnetmask will create an object with a mask of /32. + + If the mask (portion after the / in the argument) is given in + dotted quad form, it is treated as a netmask if it starts with a + non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it + starts with a zero field (e.g. 0.255.255.255 == /8), with the + single exception of an all-zero mask which is treated as a + netmask == /0. If no mask is given, a default of /32 is used. + + Additionally, an integer can be passed, so + IPv4Network('192.0.2.1') == IPv4Network(3221225985) + or, more generally + IPv4Interface(int(IPv4Interface('192.0.2.1'))) == + IPv4Interface('192.0.2.1') + + Raises: + AddressValueError: If ipaddress isn't a valid IPv4 address. + NetmaskValueError: If the netmask isn't valid for + an IPv4 address. + ValueError: If strict is True and a network address is not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Constructing from a packed address or integer + if isinstance(address, (_compat_int_types, bytes)): + self.network_address = IPv4Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + # fixme: address/network test here. + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + # We weren't given an address[1] + arg = self._max_prefixlen + self.network_address = IPv4Address(address[0]) + self.netmask, self._prefixlen = self._make_netmask(arg) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv4Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + self.network_address = IPv4Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv4Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv4Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, True if the address is not reserved per + iana-ipv4-special-registry. + + """ + return (not (self.network_address in IPv4Network('100.64.0.0/10') and + self.broadcast_address in IPv4Network('100.64.0.0/10')) and + not self.is_private) + + +class _IPv4Constants(object): + + _linklocal_network = IPv4Network('169.254.0.0/16') + + _loopback_network = IPv4Network('127.0.0.0/8') + + _multicast_network = IPv4Network('224.0.0.0/4') + + _public_network = IPv4Network('100.64.0.0/10') + + _private_networks = [ + IPv4Network('0.0.0.0/8'), + IPv4Network('10.0.0.0/8'), + IPv4Network('127.0.0.0/8'), + IPv4Network('169.254.0.0/16'), + IPv4Network('172.16.0.0/12'), + IPv4Network('192.0.0.0/29'), + IPv4Network('192.0.0.170/31'), + IPv4Network('192.0.2.0/24'), + IPv4Network('192.168.0.0/16'), + IPv4Network('198.18.0.0/15'), + IPv4Network('198.51.100.0/24'), + IPv4Network('203.0.113.0/24'), + IPv4Network('240.0.0.0/4'), + IPv4Network('255.255.255.255/32'), + ] + + _reserved_network = IPv4Network('240.0.0.0/4') + + _unspecified_address = IPv4Address('0.0.0.0') + + +IPv4Address._constants = _IPv4Constants + + +class _BaseV6(object): + + """Base IPv6 object. + + The following methods are used by IPv6 objects in both single IP + addresses and networks. + + """ + + __slots__ = () + _version = 6 + _ALL_ONES = (2 ** IPV6LENGTH) - 1 + _HEXTET_COUNT = 8 + _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef') + _max_prefixlen = IPV6LENGTH + + # There are only a bunch of valid v6 netmasks, so we cache them all + # when constructed (see _make_netmask()). + _netmask_cache = {} + + @classmethod + def _make_netmask(cls, arg): + """Make a (netmask, prefix_len) tuple from the given argument. + + Argument can be: + - an integer (the prefix length) + - a string representing the prefix length (e.g. "24") + - a string representing the prefix netmask (e.g. "255.255.255.0") + """ + if arg not in cls._netmask_cache: + if isinstance(arg, _compat_int_types): + prefixlen = arg + else: + prefixlen = cls._prefix_from_prefix_string(arg) + netmask = IPv6Address(cls._ip_int_from_prefix(prefixlen)) + cls._netmask_cache[arg] = netmask, prefixlen + return cls._netmask_cache[arg] + + @classmethod + def _ip_int_from_string(cls, ip_str): + """Turn an IPv6 ip_str into an integer. + + Args: + ip_str: A string, the IPv6 ip_str. + + Returns: + An int, the IPv6 address + + Raises: + AddressValueError: if ip_str isn't a valid IPv6 Address. + + """ + if not ip_str: + raise AddressValueError('Address cannot be empty') + + parts = ip_str.split(':') + + # An IPv6 address needs at least 2 colons (3 parts). + _min_parts = 3 + if len(parts) < _min_parts: + msg = "At least %d parts expected in %r" % (_min_parts, ip_str) + raise AddressValueError(msg) + + # If the address has an IPv4-style suffix, convert it to hexadecimal. + if '.' in parts[-1]: + try: + ipv4_int = IPv4Address(parts.pop())._ip + except AddressValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF)) + parts.append('%x' % (ipv4_int & 0xFFFF)) + + # An IPv6 address can't have more than 8 colons (9 parts). + # The extra colon comes from using the "::" notation for a single + # leading or trailing zero part. + _max_parts = cls._HEXTET_COUNT + 1 + if len(parts) > _max_parts: + msg = "At most %d colons permitted in %r" % ( + _max_parts - 1, ip_str) + raise AddressValueError(msg) + + # Disregarding the endpoints, find '::' with nothing in between. + # This indicates that a run of zeroes has been skipped. + skip_index = None + for i in _compat_range(1, len(parts) - 1): + if not parts[i]: + if skip_index is not None: + # Can't have more than one '::' + msg = "At most one '::' permitted in %r" % ip_str + raise AddressValueError(msg) + skip_index = i + + # parts_hi is the number of parts to copy from above/before the '::' + # parts_lo is the number of parts to copy from below/after the '::' + if skip_index is not None: + # If we found a '::', then check if it also covers the endpoints. + parts_hi = skip_index + parts_lo = len(parts) - skip_index - 1 + if not parts[0]: + parts_hi -= 1 + if parts_hi: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + parts_lo -= 1 + if parts_lo: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_skipped = cls._HEXTET_COUNT - (parts_hi + parts_lo) + if parts_skipped < 1: + msg = "Expected at most %d other parts with '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT - 1, ip_str)) + else: + # Otherwise, allocate the entire address to parts_hi. The + # endpoints could still be empty, but _parse_hextet() will check + # for that. + if len(parts) != cls._HEXTET_COUNT: + msg = "Exactly %d parts expected without '::' in %r" + raise AddressValueError(msg % (cls._HEXTET_COUNT, ip_str)) + if not parts[0]: + msg = "Leading ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # ^: requires ^:: + if not parts[-1]: + msg = "Trailing ':' only permitted as part of '::' in %r" + raise AddressValueError(msg % ip_str) # :$ requires ::$ + parts_hi = len(parts) + parts_lo = 0 + parts_skipped = 0 + + try: + # Now, parse the hextets into a 128-bit integer. + ip_int = 0 + for i in range(parts_hi): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + ip_int <<= 16 * parts_skipped + for i in range(-parts_lo, 0): + ip_int <<= 16 + ip_int |= cls._parse_hextet(parts[i]) + return ip_int + except ValueError as exc: + raise AddressValueError("%s in %r" % (exc, ip_str)) + + @classmethod + def _parse_hextet(cls, hextet_str): + """Convert an IPv6 hextet string into an integer. + + Args: + hextet_str: A string, the number to parse. + + Returns: + The hextet as an integer. + + Raises: + ValueError: if the input isn't strictly a hex number from + [0..FFFF]. + + """ + # Whitelist the characters, since int() allows a lot of bizarre stuff. + if not cls._HEX_DIGITS.issuperset(hextet_str): + raise ValueError("Only hex digits permitted in %r" % hextet_str) + # We do the length check second, since the invalid character error + # is likely to be more informative for the user + if len(hextet_str) > 4: + msg = "At most 4 characters permitted in %r" + raise ValueError(msg % hextet_str) + # Length check means we can skip checking the integer value + return int(hextet_str, 16) + + @classmethod + def _compress_hextets(cls, hextets): + """Compresses a list of hextets. + + Compresses a list of strings, replacing the longest continuous + sequence of "0" in the list with "" and adding empty strings at + the beginning or at the end of the string such that subsequently + calling ":".join(hextets) will produce the compressed version of + the IPv6 address. + + Args: + hextets: A list of strings, the hextets to compress. + + Returns: + A list of strings. + + """ + best_doublecolon_start = -1 + best_doublecolon_len = 0 + doublecolon_start = -1 + doublecolon_len = 0 + for index, hextet in enumerate(hextets): + if hextet == '0': + doublecolon_len += 1 + if doublecolon_start == -1: + # Start of a sequence of zeros. + doublecolon_start = index + if doublecolon_len > best_doublecolon_len: + # This is the longest sequence of zeros so far. + best_doublecolon_len = doublecolon_len + best_doublecolon_start = doublecolon_start + else: + doublecolon_len = 0 + doublecolon_start = -1 + + if best_doublecolon_len > 1: + best_doublecolon_end = (best_doublecolon_start + + best_doublecolon_len) + # For zeros at the end of the address. + if best_doublecolon_end == len(hextets): + hextets += [''] + hextets[best_doublecolon_start:best_doublecolon_end] = [''] + # For zeros at the beginning of the address. + if best_doublecolon_start == 0: + hextets = [''] + hextets + + return hextets + + @classmethod + def _string_from_ip_int(cls, ip_int=None): + """Turns a 128-bit integer into hexadecimal notation. + + Args: + ip_int: An integer, the IP address. + + Returns: + A string, the hexadecimal representation of the address. + + Raises: + ValueError: The address is bigger than 128 bits of all ones. + + """ + if ip_int is None: + ip_int = int(cls._ip) + + if ip_int > cls._ALL_ONES: + raise ValueError('IPv6 address is too large') + + hex_str = '%032x' % ip_int + hextets = ['%x' % int(hex_str[x:x + 4], 16) for x in range(0, 32, 4)] + + hextets = cls._compress_hextets(hextets) + return ':'.join(hextets) + + def _explode_shorthand_ip_string(self): + """Expand a shortened IPv6 address. + + Args: + ip_str: A string, the IPv6 address. + + Returns: + A string, the expanded IPv6 address. + + """ + if isinstance(self, IPv6Network): + ip_str = _compat_str(self.network_address) + elif isinstance(self, IPv6Interface): + ip_str = _compat_str(self.ip) + else: + ip_str = _compat_str(self) + + ip_int = self._ip_int_from_string(ip_str) + hex_str = '%032x' % ip_int + parts = [hex_str[x:x + 4] for x in range(0, 32, 4)] + if isinstance(self, (_BaseNetwork, IPv6Interface)): + return '%s/%d' % (':'.join(parts), self._prefixlen) + return ':'.join(parts) + + def _reverse_pointer(self): + """Return the reverse DNS pointer name for the IPv6 address. + + This implements the method described in RFC3596 2.5. + + """ + reverse_chars = self.exploded[::-1].replace(':', '') + return '.'.join(reverse_chars) + '.ip6.arpa' + + @property + def max_prefixlen(self): + return self._max_prefixlen + + @property + def version(self): + return self._version + + +class IPv6Address(_BaseV6, _BaseAddress): + + """Represent and manipulate single IPv6 Addresses.""" + + __slots__ = ('_ip', '__weakref__') + + def __init__(self, address): + """Instantiate a new IPv6 address object. + + Args: + address: A string or integer representing the IP + + Additionally, an integer can be passed, so + IPv6Address('2001:db8::') == + IPv6Address(42540766411282592856903984951653826560) + or, more generally + IPv6Address(int(IPv6Address('2001:db8::'))) == + IPv6Address('2001:db8::') + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + + """ + # Efficient constructor from integer. + if isinstance(address, _compat_int_types): + self._check_int_address(address) + self._ip = address + return + + # Constructing from a packed address + if isinstance(address, bytes): + self._check_packed_address(address, 16) + bvs = _compat_bytes_to_byte_vals(address) + self._ip = _compat_int_from_byte_vals(bvs, 'big') + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP string. + addr_str = _compat_str(address) + if '/' in addr_str: + raise AddressValueError("Unexpected '/' in %r" % address) + self._ip = self._ip_int_from_string(addr_str) + + @property + def packed(self): + """The binary representation of this address.""" + return v6_int_to_packed(self._ip) + + @property + def is_multicast(self): + """Test if the address is reserved for multicast use. + + Returns: + A boolean, True if the address is a multicast address. + See RFC 2373 2.7 for details. + + """ + return self in self._constants._multicast_network + + @property + def is_reserved(self): + """Test if the address is otherwise IETF reserved. + + Returns: + A boolean, True if the address is within one of the + reserved IPv6 Network ranges. + + """ + return any(self in x for x in self._constants._reserved_networks) + + @property + def is_link_local(self): + """Test if the address is reserved for link-local. + + Returns: + A boolean, True if the address is reserved per RFC 4291. + + """ + return self in self._constants._linklocal_network + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return self in self._constants._sitelocal_network + + @property + def is_private(self): + """Test if this address is allocated for private networks. + + Returns: + A boolean, True if the address is reserved per + iana-ipv6-special-registry. + + """ + return any(self in net for net in self._constants._private_networks) + + @property + def is_global(self): + """Test if this address is allocated for public networks. + + Returns: + A boolean, true if the address is not reserved per + iana-ipv6-special-registry. + + """ + return not self.is_private + + @property + def is_unspecified(self): + """Test if the address is unspecified. + + Returns: + A boolean, True if this is the unspecified address as defined in + RFC 2373 2.5.2. + + """ + return self._ip == 0 + + @property + def is_loopback(self): + """Test if the address is a loopback address. + + Returns: + A boolean, True if the address is a loopback address as defined in + RFC 2373 2.5.3. + + """ + return self._ip == 1 + + @property + def ipv4_mapped(self): + """Return the IPv4 mapped address. + + Returns: + If the IPv6 address is a v4 mapped address, return the + IPv4 mapped address. Return None otherwise. + + """ + if (self._ip >> 32) != 0xFFFF: + return None + return IPv4Address(self._ip & 0xFFFFFFFF) + + @property + def teredo(self): + """Tuple of embedded teredo IPs. + + Returns: + Tuple of the (server, client) IPs or None if the address + doesn't appear to be a teredo address (doesn't start with + 2001::/32) + + """ + if (self._ip >> 96) != 0x20010000: + return None + return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF), + IPv4Address(~self._ip & 0xFFFFFFFF)) + + @property + def sixtofour(self): + """Return the IPv4 6to4 embedded address. + + Returns: + The IPv4 6to4-embedded address if present or None if the + address doesn't appear to contain a 6to4 embedded address. + + """ + if (self._ip >> 112) != 0x2002: + return None + return IPv4Address((self._ip >> 80) & 0xFFFFFFFF) + + +class IPv6Interface(IPv6Address): + + def __init__(self, address): + if isinstance(address, (bytes, _compat_int_types)): + IPv6Address.__init__(self, address) + self.network = IPv6Network(self._ip) + self._prefixlen = self._max_prefixlen + return + if isinstance(address, tuple): + IPv6Address.__init__(self, address[0]) + if len(address) > 1: + self._prefixlen = int(address[1]) + else: + self._prefixlen = self._max_prefixlen + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self.hostmask = self.network.hostmask + return + + addr = _split_optional_netmask(address) + IPv6Address.__init__(self, addr[0]) + self.network = IPv6Network(address, strict=False) + self.netmask = self.network.netmask + self._prefixlen = self.network._prefixlen + self.hostmask = self.network.hostmask + + def __str__(self): + return '%s/%d' % (self._string_from_ip_int(self._ip), + self.network.prefixlen) + + def __eq__(self, other): + address_equal = IPv6Address.__eq__(self, other) + if not address_equal or address_equal is NotImplemented: + return address_equal + try: + return self.network == other.network + except AttributeError: + # An interface with an associated network is NOT the + # same as an unassociated address. That's why the hash + # takes the extra info into account. + return False + + def __lt__(self, other): + address_less = IPv6Address.__lt__(self, other) + if address_less is NotImplemented: + return NotImplemented + try: + return (self.network < other.network or + self.network == other.network and address_less) + except AttributeError: + # We *do* allow addresses and interfaces to be sorted. The + # unassociated address is considered less than all interfaces. + return False + + def __hash__(self): + return self._ip ^ self._prefixlen ^ int(self.network.network_address) + + __reduce__ = _IPAddressBase.__reduce__ + + @property + def ip(self): + return IPv6Address(self._ip) + + @property + def with_prefixlen(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self._prefixlen) + + @property + def with_netmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.netmask) + + @property + def with_hostmask(self): + return '%s/%s' % (self._string_from_ip_int(self._ip), + self.hostmask) + + @property + def is_unspecified(self): + return self._ip == 0 and self.network.is_unspecified + + @property + def is_loopback(self): + return self._ip == 1 and self.network.is_loopback + + +class IPv6Network(_BaseV6, _BaseNetwork): + + """This class represents and manipulates 128-bit IPv6 networks. + + Attributes: [examples for IPv6('2001:db8::1000/124')] + .network_address: IPv6Address('2001:db8::1000') + .hostmask: IPv6Address('::f') + .broadcast_address: IPv6Address('2001:db8::100f') + .netmask: IPv6Address('ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0') + .prefixlen: 124 + + """ + + # Class to use when creating address objects + _address_class = IPv6Address + + def __init__(self, address, strict=True): + """Instantiate a new IPv6 Network object. + + Args: + address: A string or integer representing the IPv6 network or the + IP and prefix/netmask. + '2001:db8::/128' + '2001:db8:0000:0000:0000:0000:0000:0000/128' + '2001:db8::' + are all functionally the same in IPv6. That is to say, + failing to provide a subnetmask will create an object with + a mask of /128. + + Additionally, an integer can be passed, so + IPv6Network('2001:db8::') == + IPv6Network(42540766411282592856903984951653826560) + or, more generally + IPv6Network(int(IPv6Network('2001:db8::'))) == + IPv6Network('2001:db8::') + + strict: A boolean. If true, ensure that we have been passed + A true network address, eg, 2001:db8::1000/124 and not an + IP address on a network, eg, 2001:db8::1/124. + + Raises: + AddressValueError: If address isn't a valid IPv6 address. + NetmaskValueError: If the netmask isn't valid for + an IPv6 address. + ValueError: If strict was True and a network address was not + supplied. + + """ + _BaseNetwork.__init__(self, address) + + # Efficient constructor from integer or packed address + if isinstance(address, (bytes, _compat_int_types)): + self.network_address = IPv6Address(address) + self.netmask, self._prefixlen = self._make_netmask( + self._max_prefixlen) + return + + if isinstance(address, tuple): + if len(address) > 1: + arg = address[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + self.network_address = IPv6Address(address[0]) + packed = int(self.network_address) + if packed & int(self.netmask) != packed: + if strict: + raise ValueError('%s has host bits set' % self) + else: + self.network_address = IPv6Address(packed & + int(self.netmask)) + return + + # Assume input argument to be string or any object representation + # which converts into a formatted IP prefix string. + addr = _split_optional_netmask(address) + + self.network_address = IPv6Address(self._ip_int_from_string(addr[0])) + + if len(addr) == 2: + arg = addr[1] + else: + arg = self._max_prefixlen + self.netmask, self._prefixlen = self._make_netmask(arg) + + if strict: + if (IPv6Address(int(self.network_address) & int(self.netmask)) != + self.network_address): + raise ValueError('%s has host bits set' % self) + self.network_address = IPv6Address(int(self.network_address) & + int(self.netmask)) + + if self._prefixlen == (self._max_prefixlen - 1): + self.hosts = self.__iter__ + + def hosts(self): + """Generate Iterator over usable hosts in a network. + + This is like __iter__ except it doesn't return the + Subnet-Router anycast address. + + """ + network = int(self.network_address) + broadcast = int(self.broadcast_address) + for x in _compat_range(network + 1, broadcast + 1): + yield self._address_class(x) + + @property + def is_site_local(self): + """Test if the address is reserved for site-local. + + Note that the site-local address space has been deprecated by RFC 3879. + Use is_private to test if this address is in the space of unique local + addresses as defined by RFC 4193. + + Returns: + A boolean, True if the address is reserved per RFC 3513 2.5.6. + + """ + return (self.network_address.is_site_local and + self.broadcast_address.is_site_local) + + +class _IPv6Constants(object): + + _linklocal_network = IPv6Network('fe80::/10') + + _multicast_network = IPv6Network('ff00::/8') + + _private_networks = [ + IPv6Network('::1/128'), + IPv6Network('::/128'), + IPv6Network('::ffff:0:0/96'), + IPv6Network('100::/64'), + IPv6Network('2001::/23'), + IPv6Network('2001:2::/48'), + IPv6Network('2001:db8::/32'), + IPv6Network('2001:10::/28'), + IPv6Network('fc00::/7'), + IPv6Network('fe80::/10'), + ] + + _reserved_networks = [ + IPv6Network('::/8'), IPv6Network('100::/8'), + IPv6Network('200::/7'), IPv6Network('400::/6'), + IPv6Network('800::/5'), IPv6Network('1000::/4'), + IPv6Network('4000::/3'), IPv6Network('6000::/3'), + IPv6Network('8000::/3'), IPv6Network('A000::/3'), + IPv6Network('C000::/3'), IPv6Network('E000::/4'), + IPv6Network('F000::/5'), IPv6Network('F800::/6'), + IPv6Network('FE00::/9'), + ] + + _sitelocal_network = IPv6Network('fec0::/10') + + +IPv6Address._constants = _IPv6Constants diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py new file mode 100644 index 0000000..a6f44a5 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__init__.py @@ -0,0 +1,347 @@ +# -*- coding: utf-8 -*- + +""" +lockfile.py - Platform-independent advisory file locks. + +Requires Python 2.5 unless you apply 2.4.diff +Locking is done on a per-thread basis instead of a per-process basis. + +Usage: + +>>> lock = LockFile('somefile') +>>> try: +... lock.acquire() +... except AlreadyLocked: +... print 'somefile', 'is locked already.' +... except LockFailed: +... print 'somefile', 'can\\'t be locked.' +... else: +... print 'got lock' +got lock +>>> print lock.is_locked() +True +>>> lock.release() + +>>> lock = LockFile('somefile') +>>> print lock.is_locked() +False +>>> with lock: +... print lock.is_locked() +True +>>> print lock.is_locked() +False + +>>> lock = LockFile('somefile') +>>> # It is okay to lock twice from the same thread... +>>> with lock: +... lock.acquire() +... +>>> # Though no counter is kept, so you can't unlock multiple times... +>>> print lock.is_locked() +False + +Exceptions: + + Error - base class for other exceptions + LockError - base class for all locking exceptions + AlreadyLocked - Another thread or process already holds the lock + LockFailed - Lock failed for some other reason + UnlockError - base class for all unlocking exceptions + AlreadyUnlocked - File was not locked. + NotMyLock - File was locked but not by the current thread/process +""" + +from __future__ import absolute_import + +import functools +import os +import socket +import threading +import warnings + +# Work with PEP8 and non-PEP8 versions of threading module. +if not hasattr(threading, "current_thread"): + threading.current_thread = threading.currentThread +if not hasattr(threading.Thread, "get_name"): + threading.Thread.get_name = threading.Thread.getName + +__all__ = ['Error', 'LockError', 'LockTimeout', 'AlreadyLocked', + 'LockFailed', 'UnlockError', 'NotLocked', 'NotMyLock', + 'LinkFileLock', 'MkdirFileLock', 'SQLiteFileLock', + 'LockBase', 'locked'] + + +class Error(Exception): + """ + Base class for other exceptions. + + >>> try: + ... raise Error + ... except Exception: + ... pass + """ + pass + + +class LockError(Error): + """ + Base class for error arising from attempts to acquire the lock. + + >>> try: + ... raise LockError + ... except Error: + ... pass + """ + pass + + +class LockTimeout(LockError): + """Raised when lock creation fails within a user-defined period of time. + + >>> try: + ... raise LockTimeout + ... except LockError: + ... pass + """ + pass + + +class AlreadyLocked(LockError): + """Some other thread/process is locking the file. + + >>> try: + ... raise AlreadyLocked + ... except LockError: + ... pass + """ + pass + + +class LockFailed(LockError): + """Lock file creation failed for some other reason. + + >>> try: + ... raise LockFailed + ... except LockError: + ... pass + """ + pass + + +class UnlockError(Error): + """ + Base class for errors arising from attempts to release the lock. + + >>> try: + ... raise UnlockError + ... except Error: + ... pass + """ + pass + + +class NotLocked(UnlockError): + """Raised when an attempt is made to unlock an unlocked file. + + >>> try: + ... raise NotLocked + ... except UnlockError: + ... pass + """ + pass + + +class NotMyLock(UnlockError): + """Raised when an attempt is made to unlock a file someone else locked. + + >>> try: + ... raise NotMyLock + ... except UnlockError: + ... pass + """ + pass + + +class _SharedBase(object): + def __init__(self, path): + self.path = path + + def acquire(self, timeout=None): + """ + Acquire the lock. + + * If timeout is omitted (or None), wait forever trying to lock the + file. + + * If timeout > 0, try to acquire the lock for that many seconds. If + the lock period expires and the file is still locked, raise + LockTimeout. + + * If timeout <= 0, raise AlreadyLocked immediately if the file is + already locked. + """ + raise NotImplemented("implement in subclass") + + def release(self): + """ + Release the lock. + + If the file is not locked, raise NotLocked. + """ + raise NotImplemented("implement in subclass") + + def __enter__(self): + """ + Context manager support. + """ + self.acquire() + return self + + def __exit__(self, *_exc): + """ + Context manager support. + """ + self.release() + + def __repr__(self): + return "<%s: %r>" % (self.__class__.__name__, self.path) + + +class LockBase(_SharedBase): + """Base class for platform-specific lock classes.""" + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = LockBase('somefile') + >>> lock = LockBase('somefile', threaded=False) + """ + super(LockBase, self).__init__(path) + self.lock_file = os.path.abspath(path) + ".lock" + self.hostname = socket.gethostname() + self.pid = os.getpid() + if threaded: + t = threading.current_thread() + # Thread objects in Python 2.4 and earlier do not have ident + # attrs. Worm around that. + ident = getattr(t, "ident", hash(t)) + self.tname = "-%x" % (ident & 0xffffffff) + else: + self.tname = "" + dirname = os.path.dirname(self.lock_file) + + # unique name is mostly about the current process, but must + # also contain the path -- otherwise, two adjacent locked + # files conflict (one file gets locked, creating lock-file and + # unique file, the other one gets locked, creating lock-file + # and overwriting the already existing lock-file, then one + # gets unlocked, deleting both lock-file and unique file, + # finally the last lock errors out upon releasing. + self.unique_name = os.path.join(dirname, + "%s%s.%s%s" % (self.hostname, + self.tname, + self.pid, + hash(self.path))) + self.timeout = timeout + + def is_locked(self): + """ + Tell whether or not the file is locked. + """ + raise NotImplemented("implement in subclass") + + def i_am_locking(self): + """ + Return True if this object is locking the file. + """ + raise NotImplemented("implement in subclass") + + def break_lock(self): + """ + Remove a lock. Useful if a locking thread failed to unlock. + """ + raise NotImplemented("implement in subclass") + + def __repr__(self): + return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name, + self.path) + + +def _fl_helper(cls, mod, *args, **kwds): + warnings.warn("Import from %s module instead of lockfile package" % mod, + DeprecationWarning, stacklevel=2) + # This is a bit funky, but it's only for awhile. The way the unit tests + # are constructed this function winds up as an unbound method, so it + # actually takes three args, not two. We want to toss out self. + if not isinstance(args[0], str): + # We are testing, avoid the first arg + args = args[1:] + if len(args) == 1 and not kwds: + kwds["threaded"] = True + return cls(*args, **kwds) + + +def LinkFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import LinkLockFile from the + lockfile.linklockfile module. + """ + from . import linklockfile + return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile", + *args, **kwds) + + +def MkdirFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import MkdirLockFile from the + lockfile.mkdirlockfile module. + """ + from . import mkdirlockfile + return _fl_helper(mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile", + *args, **kwds) + + +def SQLiteFileLock(*args, **kwds): + """Factory function provided for backwards compatibility. + + Do not use in new code. Instead, import SQLiteLockFile from the + lockfile.mkdirlockfile module. + """ + from . import sqlitelockfile + return _fl_helper(sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile", + *args, **kwds) + + +def locked(path, timeout=None): + """Decorator which enables locks for decorated function. + + Arguments: + - path: path for lockfile. + - timeout (optional): Timeout for acquiring lock. + + Usage: + @locked('/var/run/myname', timeout=0) + def myname(...): + ... + """ + def decor(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + lock = FileLock(path, timeout=timeout) + lock.acquire() + try: + return func(*args, **kwargs) + finally: + lock.release() + return wrapper + return decor + + +if hasattr(os, "link"): + from . import linklockfile as _llf + LockFile = _llf.LinkLockFile +else: + from . import mkdirlockfile as _mlf + LockFile = _mlf.MkdirLockFile + +FileLock = LockFile diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c2a6a9d2f2edc94d1b64a97f376c8b9a9c11709a GIT binary patch literal 9864 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 Q=jg9?8ZAv1OjWl24}pA-*Z=?k literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/linklockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..183bb94b70b973cc332786b3db3d3d24f6cfa2da GIT binary patch literal 2245 zcma)7OK%)S5bmD$j@KI}S%o|R4I#0;QW7H+5eX3|7)XQ^Hb_QFGKw@BZ@0tj&STx( zOXAh$Lh=K0-~tk2_lU%a8-Jy*aPc)qPE_@*6FV}9k-ECNtE#KI>g$?~#l?`o7yq*S z@F8%2;$r`EfVl}nehq{XMsrfom{R1e+=?wT+p*1T=HyP{#%|%oUg5`n5yU~!h#N&1 zhm_nV%w^tl!aVLiv*QJ3ZIX_^2d9z_)yL8;S>+?eldKq4LUs2j3OpU$sd|HrRB|06 zcPq_u&UB+&DO}FkuXb^v7m$9F6}%cLz4&P^c*=}~vmW}{|7>7x!jK;W;UuPvz&$A3 zVG(cfoW@QaYwR+g1<y(Bu?7oa_Sph!!W@|BTe^8CD+eYn2y6T^a#7mraVaBJMQOAR z+tEm7<)bK7Rgv|gp{RyjsNJaAj&d+w{jhT-3?ul~*Vm&Q54av3Jau(NRt3j{RyzMv z?^2|`#k+HM{Z^VwUfXqh7F-uUtZ4w_GZ^wbBzm{4$b|GMqtC3VH6xVVBjtIAD0>i! zk0`7uQ4X_E=M;HHzo!pKY27Ci$lRbIKA+Ii0h#-hDsSq|$Wv=B>BDRf9MPY^&NbM7 z@;mtQrvaV>qcO9LuOGlyI0#=*(Vlzrrwgbvqy6SndjeG%SmHNEHurtLtUXOEIQ=D@ zxL9jbl%vPLRExQ=cdU-LY^f#Yy<UU$@j6EE83N~@BQNN%$$}YR`vKX>?*qa&VZLYP zPNS=>$6Mo*+XjGG-5#V^@#vxy2-Q7I?s$2QzUXn9DXco8ptm#11g~qmT?w!lw=c>l zlTlhj)QC9S!&ms|ryueA<3{I%b^t1+UKo|x&WI;vT5#?5@(SL9|K;5;gs6mY!9@FN zj(G<eZB<e`h%MbfJSB)7?cd!r7TS?2RXUI=DUFUdGP6KHXlIxLbQ;LIGUt5QalnA* z+u{W71-xX5@!=UG`703-2>#w!Q^jy?m<=yyC7hq<mwS&Nm3_5y6*tXDz60Y*tYJtP z(HeT+UtAgPYJZ-n<8Yw-00^NLZPONQTPJ8hmuO(Y2Rlnviw3r1w`mjh9jj?MG^7{o zar@xAxiUYlht<IkXMFhv_1MiOWJ+d4o>qW+K!!C(%G=8BTT_GQ8I@O+XK+84DtqdK zu8Sy{^9C`9m5$vVFV%%DD>X0b_*}h%H|6Y7v^7!@O1E~Sf_ECak;$Z%2@hft=a964 zXpcY1q>|zo?)XT~A~^-5L&ZDDN3Y0xz-eFboI|U;1`F8)LQLLTki#Z@BRg}|qqEZj zQw6VYiZ9-tQMeoJb{rE|9pMGg_>WM;`yjsoLz<pL$EOaJ=GC2#cE1XSb#ba?MWGlr zgyGC6uBP~?f$w{a4)7OZbp>9v;~SrEhG>#^8sy>(Djl7-W|pLdsRBIN4bYQV3QS&$ zj?Wy9{D9`s!M_WZ2XiORDq_$CdBneFolE!4K(VZ*!2c3sxCQNIV1m32suFuR!T8=f z6yIwttXM+_iRl|jqQfL9DmKbF@XaLI8KpUP6j=F5!m3`9i1Qf3MI=~0v5aH|NpzSX z*aS8!90q8C>saA(5CnGM8cC;#4!1{YB*2A06o`{Z477>B@J;ioQE%Xl9mw<^bHY(h Vb?`}jhjo0+5)GPG0F5DX{sHTA6te&T literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/mkdirlockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..036ef7bddd418b5674232d860f720b8ba44d410d GIT binary patch literal 2607 zcmb7FOK;mo5Z>iOqNs-z$8ns;fe7lPY7@IigZ9$6c^4@XHGmByC0Y=)mP#n`A@8md zTaYhxenD@|rP8rKp+L|51v%}hKu@{$*i&bgQXCt;bcvmv<t#a`Z)We*>n?%e|9bg{ zl^P*`<7PfAU~a(_3<x8PCM2akO%30mxHl5hH}z`ymR@b&)@#WxF_T$IIdyy|t@xGH z_1(1USJRqbOY44}l5YsJS?M)lrN}uj{RT5ONvr%0G?A8}7Q$_jCqo$paXQGkR1S+@ z#v;zM_B)D4O3HbZclvii5h)kB2VtB<OjX*s#O;iIyoVcAMY<KIQ9hKaemmh&$h0J4 z9n?4<CNQ^PihDpJ;!{R^gHiCZ$t-5Srr_r(R$^t~Z04}aYXY9StO{$H)mR-?hc(y& ztQBU0M~kZdxX)s)O#}-^myq+iz<S$zUI#3ZarWE`JvbC~WX|{2w%Q#GJq}#UFz><? zUjUJ0LdRrG$Hv&4T9inmXHKj!>Ddh4_ewC!FrBWsOs2+|1Qi`vb0l1EHa0dkyabK7 z=^Zic<0~RhBed*F>;D|S>d6-v(1_i95GEoz{CHGe6>F<vRkT|!x50Yl1VNm|G6<BB z3uO&L`9fK}JkC@FO$t!Ea$e*@W?>pByI9OY%v5!l#XG|&Ktan=mWYxrZ|I-S^{cWh za{L?ND<Jvz?z&6|>w|c3EzX1tljK_G)$^<;cW&TIJ%g7~#&W)n>QVc8is_o~)&_eV z%7UOCp)191nl3F-i;k9$L~m{GS;v60IM87Srp{dxP&)=V^((wKrWt08>{Cf6bV~M( zndCaGv~Th2kX`!a{Jq0(F=OA%8WNxgC(H}v0QS3o>^0>q_ftyAQ<D8`5n1ZH{2xm2 zk>!aqCCoZU_N}qitH?^v?Hl|rY4)m<8dy-DQvQaK&ADZ73wy=}*zk5{%b&8rY&ct8 zCI|E<3RWyIMA>W)Uo-)UpdTcs7-G*ZPJT~zo;)LR5%n<Vz?ht#f=#Gx=gCvOwkmCo z#r*uuFF1bx`W;4?Bj!h!XVvPx3S(U$GWWvH&Jc>E0B<+v-l`ZatqLy|URad07Da4y zx~sc^2OsGQi{Pj-UTwFQ_*wY7vJfZAOv7DX$GxqS&YQ@WzuUaedCrw7_Jnex-3~yu zn=3owJj+$-{{3eUH@6Dpm7?8PNWqujLta6G9w=KRQ8eHs<gI)VWy<a(IaG$t&)^|# zg9Eq=v>g`us7(03Mr}dP;m75f%NJlHt^*--kvg<V9mAm|qhT1-fL(*uXbpB2T>`0P z)J%)Iv}P_DO*%Sr6sEI3b};ZbaK*N#QTha!F`1Al5i1g~2)Q$6dA|s#F^WzzrQ(Jx zG3YLHDd13N9&rG?1Ck2znC+I?9yN<BWx1SZ=tA)Z>nvhdz3rj&Pzo&(s@qkSSOkTP zWBb$5)~Vtj;a0~RYfF`eSrTV`W%CruR%ft9izs6U_%N0{N+P%}Zo_MVHBEFR8#;Q& zqcl5va+I(cNYbMdi~wLCe5CD`RoI8Z!bn8Z$+qyTAbJQ>=w3lbXOHISz4IsQUxqJ> zEagj*LRL($!<yS+>%Sj21|xQ|F{%~^VXC7I7ttfMO5Z*ZozeMYc71U0y=mye`zz{O z*nAio{$TeLxU#U_L7?uDAJ0S6BNJPn!8T%!>C`}|>|A_`mm9)Jw-XH=2&;44lcGoy zs5?yfHBiVGkgNe|89MdK!b{?KF}d4tOZBy*h;xDXA&~t=dY+C}j(U1{v}J6yF}*I{ zUHDtLyWAj1b2dznuLZ%*Fid8WauBe*69oFw;Gcp5zK#SF&Obx)Ig&$YY7T3iSAifb z1tJKln7VcMvg0_WV`*7y0rhr=a>zk1$FOrOTz(M=wlVG@xdcQJeckE~R1^?8d)T4$ Z4^Of}IbRi?ZD3!}WzvLJqaVYw{sR~BXi@+G literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/pidlockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc9a5eddacec27cdfe826719efcaed595206dcd3 GIT binary patch literal 4807 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 Tby6PcvuAU6{ukbR-i7}FZNkNw literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/sqlitelockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..296d15d5e6813aa251584c9d44496a896dbddf51 GIT binary patch literal 3706 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 aepFj~hvG#+@5K$=K@QzL2ym|UP5pm)a)LDg literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/__pycache__/symlinklockfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac8c5f8fb3aa097fccccf7c1dc1371794cfd1156 GIT binary patch literal 2130 zcmah~%WfP+6s@X$&clxwlf;P$Eg&H+5nHk%U;)8|1UAXAu%#p|q*i;X?X;&K<Em<c zN0SZl2OxH^2s2Bz?2z~ZKB2d){0pqOx4MnPWF%@-Rkt2}>)dl6b9Z5(O`rw8-1z2W zkp9BOSu;V{hAtn#zzL@*$!I_+$}D98)3Xs6+~8(vW>#Qjc3@{t;AC##X04z_$ybD1 z+&&@Pj;$9)(B^E1_|7S4BtET{qCHuprHaEO8x}(KPAMK(mHVLR5AH@Xu3Ei9;UeZ* ze0YqDs)OThlEp=-s)f%}5l38~#JrEX&zb?kHgtIphL{AD6TnRY^D;NNbwUG^U*I-( zK(e^YTPGy2d7F1&c6gUB!0hrxz65iN8-RVKTG~0z(j*@sgfEjc9=(r}7xnwGl%6WQ z$lHf)uarrC;K};(%`Japx7SBbvEgh({{p(a34<aNIwoT}W@BS&Qli+QF)_#F(3(<C z*T|TJ7ANpN>j^Z<w*~5`+%Qb?M1^6+3R#)MNIk7AIZP8(b;>+BD&sJZve-8(Q^x7O z=<1KuQzQ&1byUsauSBfC$=~-kRW{rlCc|4vE>)DKxBAZx@<VlW8#i?izm0QVh|Ls? zMmskf3(wXY!()L#wE$ged)YD@U7jIr;|zD7!98qfl?z={@+SymaMqwDx?`Fn5#%{l zbV8@(IcrX~V5S38YyoNXBiR4$$KzGSCI;NDsbiEpBDpe&vIlMP2POC$lZi7Wf+L-c zrkAzmF#~Nc8?8Smmow1Rx=3Eo?`giM+8i}EYxttmeEl2D=2en24$h+F2|2p`7?NZM z=0|$=?ViBE9^Gg{)_WEu3Zny~rGHc=BKD9!Z@&=UbvatSF1<v0Q61O%DCVcg>cP)H zVf+0vzbh`lx-!v&qJyH-ctR}Vs)Y(e^ibt|y>nlPLR8%(jIt09;Bn!=H60KFd55q` z<9O&BVhQ)Pau-}3>IX17bcl#I@UGLK#)W(j24b&Jmo8J6L8Gg5k-5w?R$<R%U1riY z^^DP_*&t}N^pPBFIAa{>7`Ouh_=-%4ysW^}z&&exaS`?n*xyj5_EEF1tceY`9Q1-t z7Na*>uBprm)zCP)TJInWG5^5ZE0u?*d&eH+iCeW2sTqp7umC|#&>BjZur<?mnPUYI zmte=IHDR+1i8zg+fPDy8Bzlh2{Ln@EIuFg=`8=RE6*;66j7DQhp$O2PZ)zlUKHG`> zA2{MIQ1U5ssnd;))@EJtuhsKGcrzf1Yf!N;$p8?H)&T1|z_QO_3H(M=RJmAgG(<FJ zK4Sto-iBTm4diM4HIT1_?|husK*6hIi7V$go1g%c);yE~znzb*YVUys105Il{sZyK zEX4DRKHKdfC2cIyScIWSx5F?ic$uQy4a1`{N}CfW40+KHLtQ(?Iy@rY#sM9tsS)p> zbRK0|!u%607%;*ll8Xt~w%hNzj%&E4KJz>H?tZCC0q+WofZF~yL8^%UBdKFuN4PEv bSP}Hc^IojnPiiafV8Tkg+hs1~{<`@OHyh_E literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py new file mode 100644 index 0000000..2ca9be0 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/linklockfile.py @@ -0,0 +1,73 @@ +from __future__ import absolute_import + +import time +import os + +from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class LinkLockFile(LockBase): + """Lock access to a file using atomic property of link(2). + + >>> lock = LinkLockFile('somefile') + >>> lock = LinkLockFile('somefile', threaded=False) + """ + + def acquire(self, timeout=None): + try: + open(self.unique_name, "wb").close() + except IOError: + raise LockFailed("failed to create %s" % self.unique_name) + + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + # Try and create a hard link to it. + try: + os.link(self.unique_name, self.lock_file) + except OSError: + # Link creation failed. Maybe we've double-locked? + nlinks = os.stat(self.unique_name).st_nlink + if nlinks == 2: + # The original link plus the one I created == 2. We're + # good to go. + return + else: + # Otherwise the lock creation failed. + if timeout is not None and time.time() > end_time: + os.unlink(self.unique_name) + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout is not None and timeout / 10 or 0.1) + else: + # Link creation succeeded. We're good to go. + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not os.path.exists(self.unique_name): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.unique_name) + os.unlink(self.lock_file) + + def is_locked(self): + return os.path.exists(self.lock_file) + + def i_am_locking(self): + return (self.is_locked() and + os.path.exists(self.unique_name) and + os.stat(self.unique_name).st_nlink == 2) + + def break_lock(self): + if os.path.exists(self.lock_file): + os.unlink(self.lock_file) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py new file mode 100644 index 0000000..05a8c96 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/mkdirlockfile.py @@ -0,0 +1,84 @@ +from __future__ import absolute_import, division + +import time +import os +import sys +import errno + +from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class MkdirLockFile(LockBase): + """Lock file by creating a directory.""" + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = MkdirLockFile('somefile') + >>> lock = MkdirLockFile('somefile', threaded=False) + """ + LockBase.__init__(self, path, threaded, timeout) + # Lock file itself is a directory. Place the unique file name into + # it. + self.unique_name = os.path.join(self.lock_file, + "%s.%s%s" % (self.hostname, + self.tname, + self.pid)) + + def acquire(self, timeout=None): + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + if timeout is None: + wait = 0.1 + else: + wait = max(0, timeout / 10) + + while True: + try: + os.mkdir(self.lock_file) + except OSError: + err = sys.exc_info()[1] + if err.errno == errno.EEXIST: + # Already locked. + if os.path.exists(self.unique_name): + # Already locked by me. + return + if timeout is not None and time.time() > end_time: + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + # Someone else has the lock. + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(wait) + else: + # Couldn't create the lock for some other reason + raise LockFailed("failed to create %s" % self.lock_file) + else: + open(self.unique_name, "wb").close() + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not os.path.exists(self.unique_name): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.unique_name) + os.rmdir(self.lock_file) + + def is_locked(self): + return os.path.exists(self.lock_file) + + def i_am_locking(self): + return (self.is_locked() and + os.path.exists(self.unique_name)) + + def break_lock(self): + if os.path.exists(self.lock_file): + for name in os.listdir(self.lock_file): + os.unlink(os.path.join(self.lock_file, name)) + os.rmdir(self.lock_file) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/pidlockfile.py b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/pidlockfile.py new file mode 100644 index 0000000..069e85b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/pidlockfile.py @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- + +# pidlockfile.py +# +# Copyright © 2008–2009 Ben Finney <ben+python@benfinney.id.au> +# +# This is free software: you may copy, modify, and/or distribute this work +# under the terms of the Python Software Foundation License, version 2 or +# later as published by the Python Software Foundation. +# No warranty expressed or implied. See the file LICENSE.PSF-2 for details. + +""" Lockfile behaviour implemented via Unix PID files. + """ + +from __future__ import absolute_import + +import errno +import os +import time + +from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, + LockTimeout) + + +class PIDLockFile(LockBase): + """ Lockfile implemented as a Unix PID file. + + The lock file is a normal file named by the attribute `path`. + A lock's PID file contains a single line of text, containing + the process ID (PID) of the process that acquired the lock. + + >>> lock = PIDLockFile('somefile') + >>> lock = PIDLockFile('somefile') + """ + + def __init__(self, path, threaded=False, timeout=None): + # pid lockfiles don't support threaded operation, so always force + # False as the threaded arg. + LockBase.__init__(self, path, False, timeout) + self.unique_name = self.path + + def read_pid(self): + """ Get the PID from the lock file. + """ + return read_pid_from_pidfile(self.path) + + def is_locked(self): + """ Test if the lock is currently held. + + The lock is held if the PID file for this lock exists. + + """ + return os.path.exists(self.path) + + def i_am_locking(self): + """ Test if the lock is held by the current process. + + Returns ``True`` if the current process ID matches the + number stored in the PID file. + """ + return self.is_locked() and os.getpid() == self.read_pid() + + def acquire(self, timeout=None): + """ Acquire the lock. + + Creates the PID file for this lock, or raises an error if + the lock could not be acquired. + """ + + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + try: + write_pid_to_pidfile(self.path) + except OSError as exc: + if exc.errno == errno.EEXIST: + # The lock creation failed. Maybe sleep a bit. + if time.time() > end_time: + if timeout is not None and timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout is not None and timeout / 10 or 0.1) + else: + raise LockFailed("failed to create %s" % self.path) + else: + return + + def release(self): + """ Release the lock. + + Removes the PID file to release the lock, or raises an + error if the current process does not hold the lock. + + """ + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + if not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me" % self.path) + remove_existing_pidfile(self.path) + + def break_lock(self): + """ Break an existing lock. + + Removes the PID file if it already exists, otherwise does + nothing. + + """ + remove_existing_pidfile(self.path) + + +def read_pid_from_pidfile(pidfile_path): + """ Read the PID recorded in the named PID file. + + Read and return the numeric PID recorded as text in the named + PID file. If the PID file cannot be read, or if the content is + not a valid PID, return ``None``. + + """ + pid = None + try: + pidfile = open(pidfile_path, 'r') + except IOError: + pass + else: + # According to the FHS 2.3 section on PID files in /var/run: + # + # The file must consist of the process identifier in + # ASCII-encoded decimal, followed by a newline character. + # + # Programs that read PID files should be somewhat flexible + # in what they accept; i.e., they should ignore extra + # whitespace, leading zeroes, absence of the trailing + # newline, or additional lines in the PID file. + + line = pidfile.readline().strip() + try: + pid = int(line) + except ValueError: + pass + pidfile.close() + + return pid + + +def write_pid_to_pidfile(pidfile_path): + """ Write the PID in the named PID file. + + Get the numeric process ID (“PID”) of the current process + and write it to the named file as a line of text. + + """ + open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY) + open_mode = 0o644 + pidfile_fd = os.open(pidfile_path, open_flags, open_mode) + pidfile = os.fdopen(pidfile_fd, 'w') + + # According to the FHS 2.3 section on PID files in /var/run: + # + # The file must consist of the process identifier in + # ASCII-encoded decimal, followed by a newline character. For + # example, if crond was process number 25, /var/run/crond.pid + # would contain three characters: two, five, and newline. + + pid = os.getpid() + pidfile.write("%s\n" % pid) + pidfile.close() + + +def remove_existing_pidfile(pidfile_path): + """ Remove the named PID file if it exists. + + Removing a PID file that doesn't already exist puts us in the + desired state, so we ignore the condition if the file does not + exist. + + """ + try: + os.remove(pidfile_path) + except OSError as exc: + if exc.errno == errno.ENOENT: + pass + else: + raise diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py new file mode 100644 index 0000000..f997e24 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/sqlitelockfile.py @@ -0,0 +1,156 @@ +from __future__ import absolute_import, division + +import time +import os + +try: + unicode +except NameError: + unicode = str + +from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked + + +class SQLiteLockFile(LockBase): + "Demonstrate SQL-based locking." + + testdb = None + + def __init__(self, path, threaded=True, timeout=None): + """ + >>> lock = SQLiteLockFile('somefile') + >>> lock = SQLiteLockFile('somefile', threaded=False) + """ + LockBase.__init__(self, path, threaded, timeout) + self.lock_file = unicode(self.lock_file) + self.unique_name = unicode(self.unique_name) + + if SQLiteLockFile.testdb is None: + import tempfile + _fd, testdb = tempfile.mkstemp() + os.close(_fd) + os.unlink(testdb) + del _fd, tempfile + SQLiteLockFile.testdb = testdb + + import sqlite3 + self.connection = sqlite3.connect(SQLiteLockFile.testdb) + + c = self.connection.cursor() + try: + c.execute("create table locks" + "(" + " lock_file varchar(32)," + " unique_name varchar(32)" + ")") + except sqlite3.OperationalError: + pass + else: + self.connection.commit() + import atexit + atexit.register(os.unlink, SQLiteLockFile.testdb) + + def acquire(self, timeout=None): + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + if timeout is None: + wait = 0.1 + elif timeout <= 0: + wait = 0 + else: + wait = timeout / 10 + + cursor = self.connection.cursor() + + while True: + if not self.is_locked(): + # Not locked. Try to lock it. + cursor.execute("insert into locks" + " (lock_file, unique_name)" + " values" + " (?, ?)", + (self.lock_file, self.unique_name)) + self.connection.commit() + + # Check to see if we are the only lock holder. + cursor.execute("select * from locks" + " where unique_name = ?", + (self.unique_name,)) + rows = cursor.fetchall() + if len(rows) > 1: + # Nope. Someone else got there. Remove our lock. + cursor.execute("delete from locks" + " where unique_name = ?", + (self.unique_name,)) + self.connection.commit() + else: + # Yup. We're done, so go home. + return + else: + # Check to see if we are the only lock holder. + cursor.execute("select * from locks" + " where unique_name = ?", + (self.unique_name,)) + rows = cursor.fetchall() + if len(rows) == 1: + # We're the locker, so go home. + return + + # Maybe we should wait a bit longer. + if timeout is not None and time.time() > end_time: + if timeout > 0: + # No more waiting. + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + # Someone else has the lock and we are impatient.. + raise AlreadyLocked("%s is already locked" % self.path) + + # Well, okay. We'll give it a bit longer. + time.sleep(wait) + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + if not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me (by %s)" % + (self.unique_name, self._who_is_locking())) + cursor = self.connection.cursor() + cursor.execute("delete from locks" + " where unique_name = ?", + (self.unique_name,)) + self.connection.commit() + + def _who_is_locking(self): + cursor = self.connection.cursor() + cursor.execute("select unique_name from locks" + " where lock_file = ?", + (self.lock_file,)) + return cursor.fetchone()[0] + + def is_locked(self): + cursor = self.connection.cursor() + cursor.execute("select * from locks" + " where lock_file = ?", + (self.lock_file,)) + rows = cursor.fetchall() + return not not rows + + def i_am_locking(self): + cursor = self.connection.cursor() + cursor.execute("select * from locks" + " where lock_file = ?" + " and unique_name = ?", + (self.lock_file, self.unique_name)) + return not not cursor.fetchall() + + def break_lock(self): + cursor = self.connection.cursor() + cursor.execute("delete from locks" + " where lock_file = ?", + (self.lock_file,)) + self.connection.commit() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py new file mode 100644 index 0000000..23b41f5 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/lockfile/symlinklockfile.py @@ -0,0 +1,70 @@ +from __future__ import absolute_import + +import os +import time + +from . import (LockBase, NotLocked, NotMyLock, LockTimeout, + AlreadyLocked) + + +class SymlinkLockFile(LockBase): + """Lock access to a file using symlink(2).""" + + def __init__(self, path, threaded=True, timeout=None): + # super(SymlinkLockFile).__init(...) + LockBase.__init__(self, path, threaded, timeout) + # split it back! + self.unique_name = os.path.split(self.unique_name)[1] + + def acquire(self, timeout=None): + # Hopefully unnecessary for symlink. + # try: + # open(self.unique_name, "wb").close() + # except IOError: + # raise LockFailed("failed to create %s" % self.unique_name) + timeout = timeout if timeout is not None else self.timeout + end_time = time.time() + if timeout is not None and timeout > 0: + end_time += timeout + + while True: + # Try and create a symbolic link to it. + try: + os.symlink(self.unique_name, self.lock_file) + except OSError: + # Link creation failed. Maybe we've double-locked? + if self.i_am_locking(): + # Linked to out unique name. Proceed. + return + else: + # Otherwise the lock creation failed. + if timeout is not None and time.time() > end_time: + if timeout > 0: + raise LockTimeout("Timeout waiting to acquire" + " lock for %s" % + self.path) + else: + raise AlreadyLocked("%s is already locked" % + self.path) + time.sleep(timeout / 10 if timeout is not None else 0.1) + else: + # Link creation succeeded. We're good to go. + return + + def release(self): + if not self.is_locked(): + raise NotLocked("%s is not locked" % self.path) + elif not self.i_am_locking(): + raise NotMyLock("%s is locked, but not by me" % self.path) + os.unlink(self.lock_file) + + def is_locked(self): + return os.path.islink(self.lock_file) + + def i_am_locking(self): + return (os.path.islink(self.lock_file) + and os.readlink(self.lock_file) == self.unique_name) + + def break_lock(self): + if os.path.islink(self.lock_file): # exists && link + os.unlink(self.lock_file) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py new file mode 100644 index 0000000..2afca5a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__init__.py @@ -0,0 +1,66 @@ +# coding: utf-8 +from pip._vendor.msgpack._version import version +from pip._vendor.msgpack.exceptions import * + +from collections import namedtuple + + +class ExtType(namedtuple('ExtType', 'code data')): + """ExtType represents ext type in msgpack.""" + def __new__(cls, code, data): + if not isinstance(code, int): + raise TypeError("code must be int") + if not isinstance(data, bytes): + raise TypeError("data must be bytes") + if not 0 <= code <= 127: + raise ValueError("code must be 0~127") + return super(ExtType, cls).__new__(cls, code, data) + + +import os +if os.environ.get('MSGPACK_PUREPYTHON'): + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker +else: + try: + from pip._vendor.msgpack._packer import Packer + from pip._vendor.msgpack._unpacker import unpackb, Unpacker + except ImportError: + from pip._vendor.msgpack.fallback import Packer, unpackb, Unpacker + + +def pack(o, stream, **kwargs): + """ + Pack object `o` and write it to `stream` + + See :class:`Packer` for options. + """ + packer = Packer(**kwargs) + stream.write(packer.pack(o)) + + +def packb(o, **kwargs): + """ + Pack object `o` and return packed bytes + + See :class:`Packer` for options. + """ + return Packer(**kwargs).pack(o) + + +def unpack(stream, **kwargs): + """ + Unpack an object from `stream`. + + Raises `ExtraData` when `stream` contains extra bytes. + See :class:`Unpacker` for options. + """ + data = stream.read() + return unpackb(data, **kwargs) + + +# alias for compatibility to simplejson/marshal/pickle. +load = unpack +loads = unpackb + +dump = pack +dumps = packb diff --git a/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d82eb9c518362e168c35e0e8bff66c5d29b9c93 GIT binary patch literal 2026 zcmb7E-ESL35Z}E!pU-FK%MC%aw46`{7^x0aNT3Q36ruuEL)4^SC#3WFb{(ADhr7GZ zhvkAqBJ~COFOa;!Kg7en^3;EUCua6+(<1Z0T01*8yWW}K%y0JQ!h%m=gulM^-7hX7 zf8xh<c%Xa+Q~m*h5k^yz(U4Nqt<>7V)lTiq2^~sq5$3SUDPa{3D|1h*6FaQHiE8SG zE_e5;XCCv;spx>Mmew*q^s{<c&l+KalKh+F0PKFcfOg}do-Y2g|A6H0ID{|l`{FlB z@Hg+4M<ll%64qb~rzBivi);zj6}HS)U~Tedc!Af$RlXd)!dJpIR^2A8=5xSCT2xmL zxRCuK2bI1H!q4N3Gc_EfJi#N=VNVnpfWk>g83`>$L;ES|QD!mw)C--b#35k?u6J~G z<4Els5BTWqi4q7t5M1(H$$%fJK*46v&x1_v4&r3LolHI8T7ikHybnT=F;(=$l1&93 zPv}n+ES9ptauqBVT9`ei4*X@GijSDHPvy<rqC`PS%=wCP$K=F1tB&EWv2|`kjPB-W zIVl(qvY}K#7lTowCW}=(vviLYmx4kJ&wm6lYQA*-y&vAc{$b10eqZ);sp350+J;MX z4S{b6Q3zczS7`r!oDQcZIUH~y5TdR|QO*yesAX$ANu_qsfp#zms6{P`k~Eewihd`5 zeX_2y!TO*-xMrNC>9yo=H{Vl_KR~0I(E-m{A=W1;U5}!E-d9o79vq7WaEFwaiy#Q~ zsb}UItfQq#iQ3a>T<w7hM2I5oM^RR=VTyVqiXIQ+bg~1%vm%KibGKfY1e@?Q1zQum z7}26)1@#Lk5Hz-zbWouVHI`A$<P}kGhRr+Mx3)h2;&!xk@9xIdqn)q5-GuD8Tfh-6 zbaj{`Te{l2XA~~r{@38LmL)F2A})bQED$)*3%a}wQ(gg~NDrv<j6MOnoYAp;W{t@? zJ;&arKnZK~&<|jsv!Lki@k9lkq7%e93l2qJ0Y`wiMbME-@Hp%E=JYn_!3|TW8=W%D zPS7hvPz)3_mTa3t0K&wnE9N5YAPndeT4=YtO}qPtvDlT`#VugSEQMw6E<^lpAP_`F zT%QWGB*;!2h#6bPU|j~qV5QFxCtw70boAgq(Fv}GA`gsb78uh04{(rttbqv#bj-8} zP`nI5SMdIB3wER_kt^N=eFg!;pFvoKk1;tT=j4f{pl5q@3}6h5pAC$X08pE0rFx>s zW~FJD;opt>lFOh23>Wd2K(J15_&v{O$AYBDRSX@4Z<2^h<YmQPEbEkPa|+wCv;$;d zhJH|FEKvy_i}3FZxFvtD!&X_xsz=3D_-ehXUxz+!PkOjLeHP){yw3s?rmxI9!jBSO zQcc&BB87+B@J=94%4fzZq^|P(pf8GC+q+!N_tlHjv<np~i#cnj@X|c5QOVNq^4!f5 zCNymQ>ugX6WnM$W4^wgjSvzSFGhIOmPahj*16@HWU&xwa5WXGS`?!3EKE+H(%vpna eR>NLvc(g&+EDPi+U8EOn&-ZFx!=aAl(7yrtHwaMx literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/_version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c70c95e24795c8eb7f78db68d93bbc18298ede39 GIT binary patch literal 175 zcmZ?b<>g`kf~fgwF(N?vF^B^Lj6jA15EpX*i4=w?h7`tN22CbS=9fS|!%J2W!3HG! zG#PKPm!%dJXXfXvWGDiOgNa|Z`X#vq`URN<x|w;!C5bsXy2<6~d08ceCLlpDjxS5i nOUW<N&n-?bNKDSw2lBz@=oM7n;;_lhPbtkwwF5b%7>F4F%+4zE literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b8e24d48f477b21ad0242c95f025d9374c10e290 GIT binary patch literal 2131 zcmcIl%Wl&^6t!a~anhzqi^Kw<Y8Jdw(Nq+c2&&S85K@YSU=ff;u4j@OT-zPneMH^0 zD_HRbtobEx`3qK@J82$GTd7?z(M;ytnYr(Ky<V$T4UEpO2Va<N7=H*1M-iJf%;Y<k zH-<2Td5S5G6RTqa7lZ|DNfWpLY>OgrQDY0ZB+9^LX-fOV?i4|BL<N+JEaF88xGH9V zXEet$@T{l-*JN40a6p+8bx`WkkrnW$ipB?{IqyNA(J--F!%P}jq|q^j(J2VCV~GOp zT6z6r7`xuL%|lPdsUL;?cN;QR(sNTOT8w>6BpaPEKTJ~T3YJC;7rY(j1_6`9r%YtZ z4|^=r9I<P)n|AJS9=f}d^SsLWZX~jR_OqPtWo~eGQs!Jl9_POeRf3v&`TKGu-Hlgb zKVBxWkhJU_^un*{-ZLWV$@gU_BDJ!c^vH;nkt#_mK2l^l&7^?EF*Uy2H?z1f_6__} z$gAsFw=31_EC||7OA!lY(SkIX&~l(}nP?6c%88*k!q*m8*~-$b?uMJX*OXQPcbY?K zw7*>16@hOI0{_VkGP$W#r26+RM1FiY3_XQ(+8Jc@IBpXjq1vfU=t%gSj^x!fx^NfE zH~^w>Y9K)^VdEcVgMgIs%I0CJT=I}daiBr}#NrjE&hKOM*x<%-0W0zx&&)PL=?oH5 zio7U^2eRHyWYAR<c0~$KXiuS}ob^LL<$QrSQ^XCkWcC+EDzt_dJW4Pc!(`LC&<kNw z9<}?61L=>pn+#<o{e3A=GEjpF*wWIXo2Ht>lW8?j7D=i&zl}2;XT$8zPwJpg+s)#1 zMC!zh;y%Gq7nV-c863<LOH$J@9a|B_!yFB=W)1VIu2Fk`u4lZxkU2N)8C1S!9b?*< zE7OZ?xI;=(4xqjX-^hwNvSOU${U7Hs^Ao0AKS96_c4WxXqgb-2i&BWQR7a0)Bv~9s z3f+=zgX*Ub6Shw^MQ2$!I&D>}4C8{M#^OgMrZ3*4&L~S4M~<)+;Tt((o($jGm#P~? z2ZLtt^8#tw9e$X~o>XINBiIl3C^zhBKb>{up@-P#<<+I7r%xU;`de-OPmkP!2kuXJ zgmAk#LrvuDJEy+}x@RkDoq2T}2t|EL*Mv?f?asV*&OM44URGSW^L+4)d!fHPRMice LehYS^g0=h)FHgrD literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/__pycache__/fallback.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44c4ecd4b8ff7a558134f2d80a817a80c4a93c85 GIT binary patch literal 24503 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 H{_X$2QM#4F literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py new file mode 100644 index 0000000..d28f0de --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/_version.py @@ -0,0 +1 @@ +version = (0, 5, 6) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py new file mode 100644 index 0000000..9766881 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/exceptions.py @@ -0,0 +1,41 @@ +class UnpackException(Exception): + """Deprecated. Use Exception instead to catch all exception during unpacking.""" + + +class BufferFull(UnpackException): + pass + + +class OutOfData(UnpackException): + pass + + +class UnpackValueError(UnpackException, ValueError): + """Deprecated. Use ValueError instead.""" + + +class ExtraData(UnpackValueError): + def __init__(self, unpacked, extra): + self.unpacked = unpacked + self.extra = extra + + def __str__(self): + return "unpack(b) received extra data." + + +class PackException(Exception): + """Deprecated. Use Exception instead to catch all exception during packing.""" + + +class PackValueError(PackException, ValueError): + """PackValueError is raised when type of input data is supported but it's value is unsupported. + + Deprecated. Use ValueError instead. + """ + + +class PackOverflowError(PackValueError, OverflowError): + """PackOverflowError is raised when integer value is out of range of msgpack support [-2**31, 2**32). + + Deprecated. Use ValueError instead. + """ diff --git a/env/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py new file mode 100644 index 0000000..9418421 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/msgpack/fallback.py @@ -0,0 +1,977 @@ +"""Fallback pure Python implementation of msgpack""" + +import sys +import struct +import warnings + +if sys.version_info[0] == 3: + PY3 = True + int_types = int + Unicode = str + xrange = range + def dict_iteritems(d): + return d.items() +else: + PY3 = False + int_types = (int, long) + Unicode = unicode + def dict_iteritems(d): + return d.iteritems() + + +if hasattr(sys, 'pypy_version_info'): + # cStringIO is slow on PyPy, StringIO is faster. However: PyPy's own + # StringBuilder is fastest. + from __pypy__ import newlist_hint + try: + from __pypy__.builders import BytesBuilder as StringBuilder + except ImportError: + from __pypy__.builders import StringBuilder + USING_STRINGBUILDER = True + class StringIO(object): + def __init__(self, s=b''): + if s: + self.builder = StringBuilder(len(s)) + self.builder.append(s) + else: + self.builder = StringBuilder() + def write(self, s): + if isinstance(s, memoryview): + s = s.tobytes() + elif isinstance(s, bytearray): + s = bytes(s) + self.builder.append(s) + def getvalue(self): + return self.builder.build() +else: + USING_STRINGBUILDER = False + from io import BytesIO as StringIO + newlist_hint = lambda size: [] + + +from pip._vendor.msgpack.exceptions import ( + BufferFull, + OutOfData, + UnpackValueError, + PackValueError, + PackOverflowError, + ExtraData) + +from pip._vendor.msgpack import ExtType + + +EX_SKIP = 0 +EX_CONSTRUCT = 1 +EX_READ_ARRAY_HEADER = 2 +EX_READ_MAP_HEADER = 3 + +TYPE_IMMEDIATE = 0 +TYPE_ARRAY = 1 +TYPE_MAP = 2 +TYPE_RAW = 3 +TYPE_BIN = 4 +TYPE_EXT = 5 + +DEFAULT_RECURSE_LIMIT = 511 + + +def _check_type_strict(obj, t, type=type, tuple=tuple): + if type(t) is tuple: + return type(obj) in t + else: + return type(obj) is t + + +def _get_data_from_buffer(obj): + try: + view = memoryview(obj) + except TypeError: + # try to use legacy buffer protocol if 2.7, otherwise re-raise + if not PY3: + view = memoryview(buffer(obj)) + warnings.warn("using old buffer interface to unpack %s; " + "this leads to unpacking errors if slicing is used and " + "will be removed in a future version" % type(obj), + RuntimeWarning) + else: + raise + if view.itemsize != 1: + raise ValueError("cannot unpack from multi-byte object") + return view + + +def unpack(stream, **kwargs): + warnings.warn( + "Direct calling implementation's unpack() is deprecated, Use msgpack.unpack() or unpackb() instead.", + PendingDeprecationWarning) + data = stream.read() + return unpackb(data, **kwargs) + + +def unpackb(packed, **kwargs): + """ + Unpack an object from `packed`. + + Raises `ExtraData` when `packed` contains extra bytes. + See :class:`Unpacker` for options. + """ + unpacker = Unpacker(None, **kwargs) + unpacker.feed(packed) + try: + ret = unpacker._unpack() + except OutOfData: + raise UnpackValueError("Data is not enough.") + if unpacker._got_extradata(): + raise ExtraData(ret, unpacker._get_extradata()) + return ret + + +class Unpacker(object): + """Streaming unpacker. + + arguments: + + :param file_like: + File-like object having `.read(n)` method. + If specified, unpacker reads serialized data from it and :meth:`feed()` is not usable. + + :param int read_size: + Used as `file_like.read(read_size)`. (default: `min(16*1024, max_buffer_size)`) + + :param bool use_list: + If true, unpack msgpack array to Python list. + Otherwise, unpack to Python tuple. (default: True) + + :param bool raw: + If true, unpack msgpack raw to Python bytes (default). + Otherwise, unpack to Python str (or unicode on Python 2) by decoding + with UTF-8 encoding (recommended). + Currently, the default is true, but it will be changed to false in + near future. So you must specify it explicitly for keeping backward + compatibility. + + *encoding* option which is deprecated overrides this option. + + :param callable object_hook: + When specified, it should be callable. + Unpacker calls it with a dict argument after unpacking msgpack map. + (See also simplejson) + + :param callable object_pairs_hook: + When specified, it should be callable. + Unpacker calls it with a list of key-value pairs after unpacking msgpack map. + (See also simplejson) + + :param str encoding: + Encoding used for decoding msgpack raw. + If it is None (default), msgpack raw is deserialized to Python bytes. + + :param str unicode_errors: + (deprecated) Used for decoding msgpack raw with *encoding*. + (default: `'strict'`) + + :param int max_buffer_size: + Limits size of data waiting unpacked. 0 means system's INT_MAX (default). + Raises `BufferFull` exception when it is insufficient. + You should set this parameter when unpacking data from untrusted source. + + :param int max_str_len: + Limits max length of str. (default: 2**31-1) + + :param int max_bin_len: + Limits max length of bin. (default: 2**31-1) + + :param int max_array_len: + Limits max length of array. (default: 2**31-1) + + :param int max_map_len: + Limits max length of map. (default: 2**31-1) + + + example of streaming deserialize from file-like object:: + + unpacker = Unpacker(file_like, raw=False) + for o in unpacker: + process(o) + + example of streaming deserialize from socket:: + + unpacker = Unpacker(raw=False) + while True: + buf = sock.recv(1024**2) + if not buf: + break + unpacker.feed(buf) + for o in unpacker: + process(o) + """ + + def __init__(self, file_like=None, read_size=0, use_list=True, raw=True, + object_hook=None, object_pairs_hook=None, list_hook=None, + encoding=None, unicode_errors=None, max_buffer_size=0, + ext_hook=ExtType, + max_str_len=2147483647, # 2**32-1 + max_bin_len=2147483647, + max_array_len=2147483647, + max_map_len=2147483647, + max_ext_len=2147483647): + + if encoding is not None: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + if file_like is None: + self._feeding = True + else: + if not callable(file_like.read): + raise TypeError("`file_like.read` must be callable") + self.file_like = file_like + self._feeding = False + + #: array of bytes fed. + self._buffer = bytearray() + # Some very old pythons don't support `struct.unpack_from()` with a + # `bytearray`. So we wrap it in a `buffer()` there. + if sys.version_info < (2, 7, 6): + self._buffer_view = buffer(self._buffer) + else: + self._buffer_view = self._buffer + #: Which position we currently reads + self._buff_i = 0 + + # When Unpacker is used as an iterable, between the calls to next(), + # the buffer is not "consumed" completely, for efficiency sake. + # Instead, it is done sloppily. To make sure we raise BufferFull at + # the correct moments, we have to keep track of how sloppy we were. + # Furthermore, when the buffer is incomplete (that is: in the case + # we raise an OutOfData) we need to rollback the buffer to the correct + # state, which _buf_checkpoint records. + self._buf_checkpoint = 0 + + self._max_buffer_size = max_buffer_size or 2**31-1 + if read_size > self._max_buffer_size: + raise ValueError("read_size must be smaller than max_buffer_size") + self._read_size = read_size or min(self._max_buffer_size, 16*1024) + self._raw = bool(raw) + self._encoding = encoding + self._unicode_errors = unicode_errors + self._use_list = use_list + self._list_hook = list_hook + self._object_hook = object_hook + self._object_pairs_hook = object_pairs_hook + self._ext_hook = ext_hook + self._max_str_len = max_str_len + self._max_bin_len = max_bin_len + self._max_array_len = max_array_len + self._max_map_len = max_map_len + self._max_ext_len = max_ext_len + self._stream_offset = 0 + + if list_hook is not None and not callable(list_hook): + raise TypeError('`list_hook` is not callable') + if object_hook is not None and not callable(object_hook): + raise TypeError('`object_hook` is not callable') + if object_pairs_hook is not None and not callable(object_pairs_hook): + raise TypeError('`object_pairs_hook` is not callable') + if object_hook is not None and object_pairs_hook is not None: + raise TypeError("object_pairs_hook and object_hook are mutually " + "exclusive") + if not callable(ext_hook): + raise TypeError("`ext_hook` is not callable") + + def feed(self, next_bytes): + assert self._feeding + view = _get_data_from_buffer(next_bytes) + if (len(self._buffer) - self._buff_i + len(view) > self._max_buffer_size): + raise BufferFull + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + self._buffer += view + + def _consume(self): + """ Gets rid of the used parts of the buffer. """ + self._stream_offset += self._buff_i - self._buf_checkpoint + self._buf_checkpoint = self._buff_i + + def _got_extradata(self): + return self._buff_i < len(self._buffer) + + def _get_extradata(self): + return self._buffer[self._buff_i:] + + def read_bytes(self, n): + return self._read(n) + + def _read(self, n): + # (int) -> bytearray + self._reserve(n) + i = self._buff_i + self._buff_i = i+n + return self._buffer[i:i+n] + + def _reserve(self, n): + remain_bytes = len(self._buffer) - self._buff_i - n + + # Fast path: buffer has n bytes already + if remain_bytes >= 0: + return + + if self._feeding: + self._buff_i = self._buf_checkpoint + raise OutOfData + + # Strip buffer before checkpoint before reading file. + if self._buf_checkpoint > 0: + del self._buffer[:self._buf_checkpoint] + self._buff_i -= self._buf_checkpoint + self._buf_checkpoint = 0 + + # Read from file + remain_bytes = -remain_bytes + while remain_bytes > 0: + to_read_bytes = max(self._read_size, remain_bytes) + read_data = self.file_like.read(to_read_bytes) + if not read_data: + break + assert isinstance(read_data, bytes) + self._buffer += read_data + remain_bytes -= len(read_data) + + if len(self._buffer) < n + self._buff_i: + self._buff_i = 0 # rollback + raise OutOfData + + def _read_header(self, execute=EX_CONSTRUCT): + typ = TYPE_IMMEDIATE + n = 0 + obj = None + self._reserve(1) + b = self._buffer[self._buff_i] + self._buff_i += 1 + if b & 0b10000000 == 0: + obj = b + elif b & 0b11100000 == 0b11100000: + obj = -1 - (b ^ 0xff) + elif b & 0b11100000 == 0b10100000: + n = b & 0b00011111 + typ = TYPE_RAW + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b & 0b11110000 == 0b10010000: + n = b & 0b00001111 + typ = TYPE_ARRAY + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b & 0b11110000 == 0b10000000: + n = b & 0b00001111 + typ = TYPE_MAP + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + elif b == 0xc0: + obj = None + elif b == 0xc2: + obj = False + elif b == 0xc3: + obj = True + elif b == 0xc4: + typ = TYPE_BIN + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc5: + typ = TYPE_BIN + self._reserve(2) + n = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc6: + typ = TYPE_BIN + self._reserve(4) + n = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + if n > self._max_bin_len: + raise UnpackValueError("%s exceeds max_bin_len(%s)" % (n, self._max_bin_len)) + obj = self._read(n) + elif b == 0xc7: # ext 8 + typ = TYPE_EXT + self._reserve(2) + L, n = struct.unpack_from('Bb', self._buffer_view, self._buff_i) + self._buff_i += 2 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc8: # ext 16 + typ = TYPE_EXT + self._reserve(3) + L, n = struct.unpack_from('>Hb', self._buffer_view, self._buff_i) + self._buff_i += 3 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xc9: # ext 32 + typ = TYPE_EXT + self._reserve(5) + L, n = struct.unpack_from('>Ib', self._buffer_view, self._buff_i) + self._buff_i += 5 + if L > self._max_ext_len: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (L, self._max_ext_len)) + obj = self._read(L) + elif b == 0xca: + self._reserve(4) + obj = struct.unpack_from(">f", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcb: + self._reserve(8) + obj = struct.unpack_from(">d", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xcc: + self._reserve(1) + obj = self._buffer[self._buff_i] + self._buff_i += 1 + elif b == 0xcd: + self._reserve(2) + obj = struct.unpack_from(">H", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xce: + self._reserve(4) + obj = struct.unpack_from(">I", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xcf: + self._reserve(8) + obj = struct.unpack_from(">Q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd0: + self._reserve(1) + obj = struct.unpack_from("b", self._buffer_view, self._buff_i)[0] + self._buff_i += 1 + elif b == 0xd1: + self._reserve(2) + obj = struct.unpack_from(">h", self._buffer_view, self._buff_i)[0] + self._buff_i += 2 + elif b == 0xd2: + self._reserve(4) + obj = struct.unpack_from(">i", self._buffer_view, self._buff_i)[0] + self._buff_i += 4 + elif b == 0xd3: + self._reserve(8) + obj = struct.unpack_from(">q", self._buffer_view, self._buff_i)[0] + self._buff_i += 8 + elif b == 0xd4: # fixext 1 + typ = TYPE_EXT + if self._max_ext_len < 1: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (1, self._max_ext_len)) + self._reserve(2) + n, obj = struct.unpack_from("b1s", self._buffer_view, self._buff_i) + self._buff_i += 2 + elif b == 0xd5: # fixext 2 + typ = TYPE_EXT + if self._max_ext_len < 2: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (2, self._max_ext_len)) + self._reserve(3) + n, obj = struct.unpack_from("b2s", self._buffer_view, self._buff_i) + self._buff_i += 3 + elif b == 0xd6: # fixext 4 + typ = TYPE_EXT + if self._max_ext_len < 4: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (4, self._max_ext_len)) + self._reserve(5) + n, obj = struct.unpack_from("b4s", self._buffer_view, self._buff_i) + self._buff_i += 5 + elif b == 0xd7: # fixext 8 + typ = TYPE_EXT + if self._max_ext_len < 8: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (8, self._max_ext_len)) + self._reserve(9) + n, obj = struct.unpack_from("b8s", self._buffer_view, self._buff_i) + self._buff_i += 9 + elif b == 0xd8: # fixext 16 + typ = TYPE_EXT + if self._max_ext_len < 16: + raise UnpackValueError("%s exceeds max_ext_len(%s)" % (16, self._max_ext_len)) + self._reserve(17) + n, obj = struct.unpack_from("b16s", self._buffer_view, self._buff_i) + self._buff_i += 17 + elif b == 0xd9: + typ = TYPE_RAW + self._reserve(1) + n = self._buffer[self._buff_i] + self._buff_i += 1 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xda: + typ = TYPE_RAW + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdb: + typ = TYPE_RAW + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_str_len: + raise UnpackValueError("%s exceeds max_str_len(%s)", n, self._max_str_len) + obj = self._read(n) + elif b == 0xdc: + typ = TYPE_ARRAY + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xdd: + typ = TYPE_ARRAY + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_array_len: + raise UnpackValueError("%s exceeds max_array_len(%s)", n, self._max_array_len) + elif b == 0xde: + self._reserve(2) + n, = struct.unpack_from(">H", self._buffer_view, self._buff_i) + self._buff_i += 2 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + elif b == 0xdf: + self._reserve(4) + n, = struct.unpack_from(">I", self._buffer_view, self._buff_i) + self._buff_i += 4 + if n > self._max_map_len: + raise UnpackValueError("%s exceeds max_map_len(%s)", n, self._max_map_len) + typ = TYPE_MAP + else: + raise UnpackValueError("Unknown header: 0x%x" % b) + return typ, n, obj + + def _unpack(self, execute=EX_CONSTRUCT): + typ, n, obj = self._read_header(execute) + + if execute == EX_READ_ARRAY_HEADER: + if typ != TYPE_ARRAY: + raise UnpackValueError("Expected array") + return n + if execute == EX_READ_MAP_HEADER: + if typ != TYPE_MAP: + raise UnpackValueError("Expected map") + return n + # TODO should we eliminate the recursion? + if typ == TYPE_ARRAY: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call `list_hook` + self._unpack(EX_SKIP) + return + ret = newlist_hint(n) + for i in xrange(n): + ret.append(self._unpack(EX_CONSTRUCT)) + if self._list_hook is not None: + ret = self._list_hook(ret) + # TODO is the interaction between `list_hook` and `use_list` ok? + return ret if self._use_list else tuple(ret) + if typ == TYPE_MAP: + if execute == EX_SKIP: + for i in xrange(n): + # TODO check whether we need to call hooks + self._unpack(EX_SKIP) + self._unpack(EX_SKIP) + return + if self._object_pairs_hook is not None: + ret = self._object_pairs_hook( + (self._unpack(EX_CONSTRUCT), + self._unpack(EX_CONSTRUCT)) + for _ in xrange(n)) + else: + ret = {} + for _ in xrange(n): + key = self._unpack(EX_CONSTRUCT) + ret[key] = self._unpack(EX_CONSTRUCT) + if self._object_hook is not None: + ret = self._object_hook(ret) + return ret + if execute == EX_SKIP: + return + if typ == TYPE_RAW: + if self._encoding is not None: + obj = obj.decode(self._encoding, self._unicode_errors) + elif self._raw: + obj = bytes(obj) + else: + obj = obj.decode('utf_8') + return obj + if typ == TYPE_EXT: + return self._ext_hook(n, bytes(obj)) + if typ == TYPE_BIN: + return bytes(obj) + assert typ == TYPE_IMMEDIATE + return obj + + def __iter__(self): + return self + + def __next__(self): + try: + ret = self._unpack(EX_CONSTRUCT) + self._consume() + return ret + except OutOfData: + self._consume() + raise StopIteration + + next = __next__ + + def skip(self, write_bytes=None): + self._unpack(EX_SKIP) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + + def unpack(self, write_bytes=None): + ret = self._unpack(EX_CONSTRUCT) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_array_header(self, write_bytes=None): + ret = self._unpack(EX_READ_ARRAY_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def read_map_header(self, write_bytes=None): + ret = self._unpack(EX_READ_MAP_HEADER) + if write_bytes is not None: + warnings.warn("`write_bytes` option is deprecated. Use `.tell()` instead.", DeprecationWarning) + write_bytes(self._buffer[self._buf_checkpoint:self._buff_i]) + self._consume() + return ret + + def tell(self): + return self._stream_offset + + +class Packer(object): + """ + MessagePack Packer + + usage: + + packer = Packer() + astream.write(packer.pack(a)) + astream.write(packer.pack(b)) + + Packer's constructor has some keyword arguments: + + :param callable default: + Convert user type to builtin type that Packer supports. + See also simplejson's document. + + :param bool use_single_float: + Use single precision float type for float. (default: False) + + :param bool autoreset: + Reset buffer after each pack and return its content as `bytes`. (default: True). + If set this to false, use `bytes()` to get content and `.reset()` to clear buffer. + + :param bool use_bin_type: + Use bin type introduced in msgpack spec 2.0 for bytes. + It also enables str8 type for unicode. + + :param bool strict_types: + If set to true, types will be checked to be exact. Derived classes + from serializeable types will not be serialized and will be + treated as unsupported type and forwarded to default. + Additionally tuples will not be serialized as lists. + This is useful when trying to implement accurate serialization + for python types. + + :param str encoding: + (deprecated) Convert unicode to bytes with this encoding. (default: 'utf-8') + + :param str unicode_errors: + Error handler for encoding unicode. (default: 'strict') + """ + def __init__(self, default=None, encoding=None, unicode_errors=None, + use_single_float=False, autoreset=True, use_bin_type=False, + strict_types=False): + if encoding is None: + encoding = 'utf_8' + else: + warnings.warn( + "encoding is deprecated, Use raw=False instead.", + PendingDeprecationWarning) + + if unicode_errors is None: + unicode_errors = 'strict' + + self._strict_types = strict_types + self._use_float = use_single_float + self._autoreset = autoreset + self._use_bin_type = use_bin_type + self._encoding = encoding + self._unicode_errors = unicode_errors + self._buffer = StringIO() + if default is not None: + if not callable(default): + raise TypeError("default must be callable") + self._default = default + + def _pack(self, obj, nest_limit=DEFAULT_RECURSE_LIMIT, + check=isinstance, check_type_strict=_check_type_strict): + default_used = False + if self._strict_types: + check = check_type_strict + list_types = list + else: + list_types = (list, tuple) + while True: + if nest_limit < 0: + raise PackValueError("recursion limit exceeded") + if obj is None: + return self._buffer.write(b"\xc0") + if check(obj, bool): + if obj: + return self._buffer.write(b"\xc3") + return self._buffer.write(b"\xc2") + if check(obj, int_types): + if 0 <= obj < 0x80: + return self._buffer.write(struct.pack("B", obj)) + if -0x20 <= obj < 0: + return self._buffer.write(struct.pack("b", obj)) + if 0x80 <= obj <= 0xff: + return self._buffer.write(struct.pack("BB", 0xcc, obj)) + if -0x80 <= obj < 0: + return self._buffer.write(struct.pack(">Bb", 0xd0, obj)) + if 0xff < obj <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xcd, obj)) + if -0x8000 <= obj < -0x80: + return self._buffer.write(struct.pack(">Bh", 0xd1, obj)) + if 0xffff < obj <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xce, obj)) + if -0x80000000 <= obj < -0x8000: + return self._buffer.write(struct.pack(">Bi", 0xd2, obj)) + if 0xffffffff < obj <= 0xffffffffffffffff: + return self._buffer.write(struct.pack(">BQ", 0xcf, obj)) + if -0x8000000000000000 <= obj < -0x80000000: + return self._buffer.write(struct.pack(">Bq", 0xd3, obj)) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = True + continue + raise PackOverflowError("Integer value out of range") + if check(obj, (bytes, bytearray)): + n = len(obj) + if n >= 2**32: + raise PackValueError("%s is too large" % type(obj).__name__) + self._pack_bin_header(n) + return self._buffer.write(obj) + if check(obj, Unicode): + if self._encoding is None: + raise TypeError( + "Can't encode unicode string: " + "no encoding is specified") + obj = obj.encode(self._encoding, self._unicode_errors) + n = len(obj) + if n >= 2**32: + raise PackValueError("String is too large") + self._pack_raw_header(n) + return self._buffer.write(obj) + if check(obj, memoryview): + n = len(obj) * obj.itemsize + if n >= 2**32: + raise PackValueError("Memoryview is too large") + self._pack_bin_header(n) + return self._buffer.write(obj) + if check(obj, float): + if self._use_float: + return self._buffer.write(struct.pack(">Bf", 0xca, obj)) + return self._buffer.write(struct.pack(">Bd", 0xcb, obj)) + if check(obj, ExtType): + code = obj.code + data = obj.data + assert isinstance(code, int) + assert isinstance(data, bytes) + L = len(data) + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(struct.pack(">BB", 0xc7, L)) + elif L <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xc8, L)) + else: + self._buffer.write(struct.pack(">BI", 0xc9, L)) + self._buffer.write(struct.pack("b", code)) + self._buffer.write(data) + return + if check(obj, list_types): + n = len(obj) + self._pack_array_header(n) + for i in xrange(n): + self._pack(obj[i], nest_limit - 1) + return + if check(obj, dict): + return self._pack_map_pairs(len(obj), dict_iteritems(obj), + nest_limit - 1) + if not default_used and self._default is not None: + obj = self._default(obj) + default_used = 1 + continue + raise TypeError("Cannot serialize %r" % (obj, )) + + def pack(self, obj): + try: + self._pack(obj) + except: + self._buffer = StringIO() # force reset + raise + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_pairs(self, pairs): + self._pack_map_pairs(len(pairs), pairs) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_array_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_array_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_map_header(self, n): + if n >= 2**32: + raise PackValueError + self._pack_map_header(n) + ret = self._buffer.getvalue() + if self._autoreset: + self._buffer = StringIO() + elif USING_STRINGBUILDER: + self._buffer = StringIO(ret) + return ret + + def pack_ext_type(self, typecode, data): + if not isinstance(typecode, int): + raise TypeError("typecode must have int type.") + if not 0 <= typecode <= 127: + raise ValueError("typecode should be 0-127") + if not isinstance(data, bytes): + raise TypeError("data must have bytes type") + L = len(data) + if L > 0xffffffff: + raise PackValueError("Too large data") + if L == 1: + self._buffer.write(b'\xd4') + elif L == 2: + self._buffer.write(b'\xd5') + elif L == 4: + self._buffer.write(b'\xd6') + elif L == 8: + self._buffer.write(b'\xd7') + elif L == 16: + self._buffer.write(b'\xd8') + elif L <= 0xff: + self._buffer.write(b'\xc7' + struct.pack('B', L)) + elif L <= 0xffff: + self._buffer.write(b'\xc8' + struct.pack('>H', L)) + else: + self._buffer.write(b'\xc9' + struct.pack('>I', L)) + self._buffer.write(struct.pack('B', typecode)) + self._buffer.write(data) + + def _pack_array_header(self, n): + if n <= 0x0f: + return self._buffer.write(struct.pack('B', 0x90 + n)) + if n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xdc, n)) + if n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xdd, n)) + raise PackValueError("Array is too large") + + def _pack_map_header(self, n): + if n <= 0x0f: + return self._buffer.write(struct.pack('B', 0x80 + n)) + if n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xde, n)) + if n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xdf, n)) + raise PackValueError("Dict is too large") + + def _pack_map_pairs(self, n, pairs, nest_limit=DEFAULT_RECURSE_LIMIT): + self._pack_map_header(n) + for (k, v) in pairs: + self._pack(k, nest_limit - 1) + self._pack(v, nest_limit - 1) + + def _pack_raw_header(self, n): + if n <= 0x1f: + self._buffer.write(struct.pack('B', 0xa0 + n)) + elif self._use_bin_type and n <= 0xff: + self._buffer.write(struct.pack('>BB', 0xd9, n)) + elif n <= 0xffff: + self._buffer.write(struct.pack(">BH", 0xda, n)) + elif n <= 0xffffffff: + self._buffer.write(struct.pack(">BI", 0xdb, n)) + else: + raise PackValueError('Raw is too large') + + def _pack_bin_header(self, n): + if not self._use_bin_type: + return self._pack_raw_header(n) + elif n <= 0xff: + return self._buffer.write(struct.pack('>BB', 0xc4, n)) + elif n <= 0xffff: + return self._buffer.write(struct.pack(">BH", 0xc5, n)) + elif n <= 0xffffffff: + return self._buffer.write(struct.pack(">BI", 0xc6, n)) + else: + raise PackValueError('Bin is too large') + + def bytes(self): + return self._buffer.getvalue() + + def reset(self): + self._buffer = StringIO() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py new file mode 100644 index 0000000..21fc6ce --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__about__.py @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "18.0" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2018 %s" % __author__ diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py new file mode 100644 index 0000000..5ee6220 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__init__.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__about__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d41d76007098dfacbeac71b1c4becae51fdafc9e GIT binary patch literal 676 zcmYL{&1xGl5XX1DcD!EOiQ9&p)j$h|+M9$NLMg>fax5ia=s^_3dPiQX-IY{*xY#e# zbKj<CUwi5+^wg0}h=hL3h|zyEBi#;%S%icBeEsEjD~kRE=W(QH%y8KU1Vj+mQ4`a+ zY0*}b&?Jta1qrmF14qz>6na%k+mO)?^yv`{XcvYwg=5--6Pm$@_Td@tokes2&*#zj z#a~p7#>wuaSXfni$C+rfGH#cGSPLtZ+#PEpq+?4jOBeheV@|l5Gq&q9W_{BXW`j<b zF>l0Scg;;Wi%!N^;oV9ZwDBZw3Q-?oYEg1&gUpbzQt6Em)yjo1U6kL7O2}$^ey0p4 z-icZ`!7W)TLmoCLC&?j*+wIGhbK1Vm^GdjtUrbBY<a(ov{7I&Lc{9D(j_;K$Y9Mpx zmrF+q2}H<HCitQzrIOBwg?Gx>?FjavGrJF+3bj4Io!=A8{sC22oP0c7{tfwjsFYk` zg0s8FD#+Ev<@E${LtfcW<6&sS(mQXkT!T*>nIxc%2z@JR?1|}wt)qZ$KzMo63kbi% z^aBQnUy&IFJK*0eca6@q&=Vo8L!C+aqmp0U_v^5^Uu?}KDD%{g91|{-$5v1EW|zKe Z6!@CI50|m0h|?sCv!os4Y~c)y{{!}u$T<K2 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4e5207bfd411a7227df1e5cf7d3f38edc5feefee GIT binary patch literal 514 zcmYk2O-{rx429EnroU4V5@$fn0%pS!0pb8`U=<-*r70y)rzK4W&1qP3rEXbq1y<NI z0ud>n;>7lQ@pW0|f|h(gx(`AjJ~{YZDIKn8k9PzmRL}_wWPqUzF_KXrRH&kEhI2W` zSjL#h1XGz}CNs=sj)g36As3W4Q*#xoM5QWIxhmRJmTGY;mgN_97RzYbuO7y}^R5An zLvP)bD!taD?#;9}SZy3UdQ&@!zXGmEryQX2?y0u`QwdP_!^Z0N$x)aAG+615js-xc z>&A@DE*L#xWjDJdr(MVQ34phHm#}Uus{+`9bSw|YE*K>vX7E^S#z+V^%RTn;=$*IJ z%+e5rjTkcmd#N6JPquc&T=K8Ow*OY?PlWAM9hv_S_JFe)-<K<g!)nmOi8iC7_mldq xHP7z#j4!tv){RlUT@6+JQnlK&D*$aYNuLgzDLuzt`L4NOTO)tuFg%X);0HuahZX<; literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70de80132cb912ea9aa0976bf7fa7a32d94c1c8a GIT binary patch literal 966 zcmah{&1+OK5YN}{zOLKt!BX(!uwDx9&|OfErHBgNiXaF+3L$;Twy(agCfSxP_0&T9 zU#Lg_rCdGrU-0Biwp}Y89GJ<>B>By6CV9QO+9x2{*Uh~>PRLIT?u3E!3e<fBqlu;^ zsc1$kma&RwoMMiZA`?a&bu@WIH2=)9?lKY(^-RycHOZ7_D|OfOan&8&y(HNK%|4K{ zcLUfY<zY?jyQZ9ZBa5nStPhDUP6}5vbr`m`sJ)!d>fA%TdxOMofGx=>-Uh*-3)%y9 zn_%9ND{@7rOjFG+6V0ya1^>c4`9{x~=2{fwyMXeYvq^sh^2QqF%}9;*l{2HfRL+e~ z3x5ci%6JtM<9IR$@TFi`6!#d6AsN*qWA_VZTyrQR&YmHf{DZY!Hn}R@&Ul&1MT8;* zSJa1~ZUE+*p3`e`&My#(?*0J0!1K}tQLD;?zCSFSMB*+`owCqb_yVCVPUP3l#8>U4 zE!wT3c3zd`R(^U=ANk{#n2ah<OsyL`X;uDN9TfG!MCMJ^DnD-Lp(kZ+PNjT`lyLfl zo~8foXncEX7x*UN16e6UU&^Y{vl9J*l*cnwE_Uo1;6}bFv)H#?y-V03cwuEZt0xdf z9tpKLrm*G>{u*WHGQQO<Ob~wFnh2co1zZHiJO5USMTUR3wT_kI%k(z5-GC?^U<=ck zpIK<Z;xsJ&1B<5ucXJm8C&uE>l|?;m0)PMMIhq%+>1`N*f$>UY=0ZQdRm?>6$m*Vn YoRaOu#CEWR!_+!U_>c~Tpb6{p-^t|g)&Kwi literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/_structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bd929b470ad01b63ba2c3792f9ab9a3153b8d96f GIT binary patch literal 2818 zcmcIm&2G~`5Z<*D$4S#B{eiY1RpNp$QW_)>5>f?KK_D)<(36F<GTu$<;yCGgQ`D-r z^u$YW=9PTq#4B)OW)qjBvT^w7MmuBg?Cv)^JM%dQ%gZ$a&HZx!{pT_v-|!`EC3x6} z9=`&?38x|HQ<wG)*XWzBNy!_+4Q^f%Zi>>_bjzYVCT<x<OS}xDWj$&M3q~z&y(3QL zJM2UpGii7q;z2l4f(8BIK&r&%!D$c&gD6=U${<p#JBoY-?>??bn*k5|(Bnf8g1D3u z*Wi>Jm&7%>$xEOCn_HmEyuxkJ7O(Oe=n7xrb<j3n<}0A9yuq8GYkZZjfnMV4;NeDM zzm2*<6sR+w0thzL*k3}AF({nEOrs+qVB{-tXi|zr*p(K%YVqTst@^|EFc`LiC{|t= zw){`M=vbXR!9m^GsfhSMwuheo(dz|Kugzj5N4^?K5$_Jq5}Pq8hLW)=!s5vZJzq_o z+fA)=UYamTds&AEMHIatV>(7}X~!{=(vcS*B_-U}p|S#Ve)%kIctud0!x(Om1v;_% z+8vmJIx94<^~R2&L6Y)79SM0I%VI24j5TJE8Z*a3+n?dcW!NeUMKHFOhXS@alxrcp zfDj(jv5|(b21$xn8u=or!qU)-W5%Wj&2vDUFm@})0kma1umUR-Ngb$@sSC1+r(6Y5 zfEvNkwsKI>Hiw#ZiHEb7n0K}wT+`hg6tw*(6!3Q^4+YPH{$oQucNR5`8%>%W(eqSr zD$*p&seuY(k?1jY54K86pqZ|Ly3@vvQ^#V7ygr~OHOBe_J__-<&e+Mw3nvzd#VfIx zBwnY)WS5wWavjA63d{_-iQ<YtCQn$Anq#n1V_an$wmJXPb{|Yv4NGz#`VDfVybb&3 zhkQzp=hapkwMimnQjU($L-bd33O(PxeocQvbrQd7atTECCF?6`6`(H2b%kZ3ul~^t z*k;BN7oxjjC`_=&MNn8UI@&N1_3t@vA;Qr~{j>o1X1Gq5(z62Sg$Qr%tCdA~x?uMT zpcZ1iVko4A7e!EuQJ*G>oI*h2IhcXj%E-->@g#mu<Ti>sDE^t;kVhUs&m%Xqcbp3H xYj=eIjNo4nCalDamH1aIu?8QGg|GAxH7{kcXkzb8`1v`miIG@0%;t^-{U?*;?x_F( literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..df19a280c31bfebd4d834e484f1d39cd1d0b3ba5 GIT binary patch literal 8817 zcmcIp&2t+^cAuUZ00R&NDUuQ?*^)=pCu9kdZCU=JXi+w0DV9K5)XLt89b|-VQlNkt zsAnKc5U^D-y}6{eQd_l0SB1KylB&%mmsI6n$TgM2TyxSTRXK*2<o9|8LlBa7SFQ?B z{oVcgz1Oebd;R9>_;^9X&-uHP-yXI#?LVn8_~lW#f)rdaG>vPVHMJIVSW9>Gmf;wT z`t+vhn5xV;8C7PTtSWO(4yDnwT6rhmDmaDKm^0QYIz_e4ME|%m-YPkz)`T<Bnsg>r ze+K>goGH|^JlC9V%{VivZZ-F}4mbx|v(7Bqd0yaSyvWBlGS1u=8ZYtukLVQ#w+!bH z+7rBhc0sk@Kzovpp*^PBZ=$`APoX^}4rBfiw5RzD+B4z^+Haw~pC3T`fNI-l&+<96 z=T!TsnBoVw81h3~?5c+Hjih`tDGw**k)(VpDea^@nw0ZNc`PZ9C*_HxJeicIlJay? zmXq=fmCigr#^?DF{uV!k|Jy%honvBt`#3+#&;6)9V~jAYD16T+>n<eaJ4yL&Qofgz z7nAaRDxDMJ1Rz{W`aV#7C&fwZ@L{^cB>xCIO!AM_=qYguqo1UsQ+z?~e_4&57W3j1 z;Fd*6l*P$eO_XP~E#{mNXRvB<Xw|1%Z2RqJnsXNWUrFlc#Ke~7RKyvqJ}W9%eU4TG z-g!|G=f$`<O}$%eR$J6S`<R+joYkBQe2HKEQFGqmYy5M*{3CPT<=1F8{sra2+<Xt| zBGUUvmykX{`jB7$$#Op8H~61n?Z=Q9&H03X$#0^yz;E#?%FBF(ucBP!U-5C2pF(18 z^CBP@m4sd4`kGe0^PKKg*@!0Gdx78Vgre4HwS5^z7H>Ri1P$MdN^RNj!rFSrtA}V; z%Vtzsb!8xyAJ;{jx}u_L-xfiq83xf<5Msr~TId2!K5i^~9P0{>kp7Ci<x3G|zL0*W z9p$e1@_SeEsQ6XK4+URSYs)Ok-E4$Hy3OZ|Fl13N22=~5v_(+Xqx@Q1)Eny!A*0C~ z-Xpi!;JZEJNzW};KEQ<OUwB-sH$1^V^IL6KHUc0$mv%0Dj~deVTEYvfZc9Yj!7?mz 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 J!?LW|{{xgZz9|3z literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/requirements.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc3086071d4e218f07923cbc99fc02ecf752f260 GIT binary patch literal 3833 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1f4740bc62f731ae8a0fd8ad387f2fe89d42c727 GIT binary patch literal 19744 zcmeHPTZ|mXb?w(Yc6N5TTrR04DN#*Q4-OwInpSK}CMk-NXvvXRvdBpCiqc?qx_5V$ z^H^5*lHAeI4on879b0h_CouviA(8y#&p?pC0rHWLeB>j)36Rcb5Ci(nPXGaVoO7$Y z=gnO^vI7K}*{<nFb=AGMZrwU{>(*YJnkpFhEdB9QSKAH4_!nLzpDa!;;0S(-#4|jz zZZym#vtcb+4SUHpdC#glOOE_zmNN32UCPRDZYk&4o>R{^CYB}|g{1=W+g_$V*(fd* z8&gYDjp?On)A*9%Wxd>8!^`=*?$}E+xXybMxSsF}zO%mDpS@$@{vO;fc$2t4>F>ey z9IlJr6t1WIIb84croCNvjir6KKjZDj{oQi^5kGf--kW`3F75aBcyq{cz}xHX!|y@l ze8iha&Uq>EQO~+;l=goNUX79+?W!yXt@>u@muroUmI|Z1SG!RQYOQ88y`gH&u)MO_ ztcJK={Mh6xR#Xf^JXkG<TN{25P2a4AYvqO?R;u+%5TMB1+rE+lre60~E7h&!GP6-p zfnR0C$%iFgz!A(K@r@<ZGnOpRT(X5oJDPc|d81OVd6zf*YHg+FtM;n}7oQiKZcRUN zgXEEWvl6%~t<9!)(%lR|f*Y*0HtU|N{1sohVat8<l{ejIpFO=GMJ$$_C|@o&D-FL~ zjtb>+qvdVZd0s4+uWwfB@snJ+?6s=p@}C)sL`w3>i_e6Ojb}D$8>ec`Agt8ur>Zws zo9p5AXL(bO@(sV~wbU~kmFl(1D&+M{N@=jLv85(a*e<eeA<5fv-6tCd_b)KRuOmrh z<J;?wXL{CM<BqwMkt-;lTxI1d<7MS4Cs#QyFIRb7O?VStL9PmZVSUn@Os`nxZg0w) zzH6e?qP#il?eb>idde$8VfI8*7b}6EHbj+8#}9vbyo4hl&7O(uR{JB7G8^kHKipK! zzzx@Y7pjBy*ie4pH^U0m%5AOSNiA^GqTPD!n(wxj*Zpd^;9kMAw5Yg6m;Js%ZXh=c z@q5asg@IpR(M?Sv7Ny}zX5{dGw<*<bkQ||rL0P%{2$^7m7@79oK7JSC9NY4JDJ3@H zyW*}@f;AV4yy-(hp^D?#O<zvvReM0pAi2<67FjMIO6hgl`v&RNS*pSg^6__6LtRhn z>=L}(YSsNpvnyrjuX}UNhm4gA4w|h{<Q?8@^~jv<mKLVlFK{c$cYXG!p|-Guw<yzM zse>$L%Vqz1x%@=RV5U7c$RIOp%id;6(JzcWO5<THs(s*M1cOajn-dRXkQugBxYZ#B z2O0{!?UeG-o`H|%z#m!?%_}Vf)784^d+zd<Xk}VdYO97?%^azblc*%A<4g}r`}^Ch zC)c(O=cUA4_QPOM`#xQ!5>=EwI?z&TKlpjB%hO`j#sxq89o3`WN-2NY4}I0BH6i$# zwot1zj0<ip^cya0UbO`)h{vAGQMA_7reVDBZQW%YzAtnQ&>H3A5`zn%O<S@d%aCN* zmXF^}`M6TKM%@v@Rb?5<1A|K<c++!NYIX1_7QW#IEpSl@-Bz={73aCRR;#Y1h0!8x z!+4)=LM*j#NDpIC<Uxf{G*TQ{P1&VX7(-S>XDFGA{F_!q<Wy5krjbN;Ww{zn10sd0 zQVjue)>@vL<Kw+dI9#ZCW}Hd#Y^c_Tufi=MC&~tX2>R5c%t&M1(_VrmIQpnrBrGpr z$$4u!H=V^HU&kzF98+>s@i6^R^)BED?juRSLCpYga*0Oonn0@p1%Ors1OTnd@DH>) z=@o$s^D^KYOA|8C8%qU1fLYw1^otrn0t!swTu>y=r*SSg66d@8UF$R6exgcVc?Z0M zcyqUR*n8A_40X?XN4!Jc<2c(RK<;QXSAMNYVCi8XNC*1J==LQd2Ocls2-sd7W8JuK zcFYInZM$O!heF`O`!=udnBO!z_I<~*9+>wt4-7fC_4$g`G0NEv)0}4jh&YSw`4~iY zq2lxI(;uF`{dAOPTUElAigGtJW-aBTY+3oM{w=m$MOD`Xm_=EP+l@*XWmZ*db0f+S z0^_I5t_r}|W7kSf+(-FHYe5EYqM#H$YRrK_yw<FR<?>r(nTltaMbj~-?V>sBv>zKK zF`y9rPC6=ZRL|fLxt+!d<>ndJCe%L2%fuC=)U-V7w&~e&4YU_#I%qh^($*5%bJFeM z;M|9&53AdXLvMT6SqSRbho8ZX56|2#oiAn8Dcn~jCNzxE1coRA|8iM6Ph>+hrP!X@ zEOnS|0>E;)jJGx0_CC|G9W#sXShn>$Dcdx=WL?;%>^yUwteYRP(XGXH7Ic63ncJX5 zNIi)xrIACIbmuxAYint?9~~oj0f?gs;M_8l>hBQz!jf2#L-?g0QZIXatEb*^4L$<K z<?)(u{<^N%49z>1I=waBG45N^Wz2Vs>lYj&w67J^NfV=#X@t&Y<6WaU142bD?pVPE z-h<RK9dkW%jq^f~o{b8a|8ZK=ton+RWAzy(oUlaGi>>gr#zx(50Kfa5=1;fwD3qfu zBwmyWo?#YD%bdnHPffSl2gitd2-y8%7^e1<Vf8uk*Uzc?Jnu>KJ%l~l{@Xt@djjjI zz5MW(RZDvkC{mG<uG=y98!&im8R&GeTx~TliT2A-ZcemUG3yRPB`S_7Y+}uVr2kp1 zjlu3WRmMwc&U>gY(fcE#8>2USA7)Ff^#M&ZlrXebEU4AK5O(^Gc^ei+OW4s8o<K&$ zrc~@OF_G#i-WV_vyTGZhsy-&s;!5~U<OwJxLzJie#AsUkUmD+6#YRH3B34CP0^9JA zuKFZ$d>@Avl{LmlCF0*{y)@eoua~0vK~KG-O;aqRzG_ogN}-Wm-4Lc&?=gmu=KO~} zwYejO+%r)0sY7aw*|xMWWeh`owZ{F3>N3#YGLrnLTXkQ-HttL3kb;f-DEvXJSEc}~ zM3D{-7ffGH0(Z;h`)Lhk`|wESdUN-|<CKW!QAWqY0Gn5^w(G`iK#drtK;73Z^;E|S zo}v!~_if~G9^gKHGjT7z1bahCtFuU=santj9@H24fZ8U#qNFjd62|16{%#`N{|Ryj zMI?rmH?vM5Q!t%z=phkB${IT(`*9UVKx5zmZLJ!&fvto|pooqI^kCP_+nHNm?wBtd z?_a!~1#3np3uKl9V`e9}Vs<hgnd(R<2LUWW086-UBX#aO%x4<ck9an4T=s1YMAwhJ z1I!lO?KtZ0t=W!)G7BhEKfCdcRvTyWl8EU_DI=275c)hw)UYF4+1P-Ct(4c((Z|vU zxviRC_k1tfExy1W=?0N??WPD8u1&fky~Ml>sw0v5U*ZUe+YMkc$C`5rX2F_vvKYgP zj$;-wd7O<I!Qx4UB^XL(78qvc1|}EkIh3tVGkKQDh-rn^2T_!KI<ZLAL#xpdzI%=d zi5)-5IEtr>I06?*-g2zMRDLRN<2#A3ozD~<ey5$hUD%_Tn@W*>ayYwyBe;PinQ+ik z>pS-|p5@z*!0r8r0atbwNA9BWz`_(mCLx@FaPsk^EG8Rz@==H<ACvLqqZm&<ref#y zbnLv|rKcQAm~6n59Ef&lk8(PLsQfbwT{^Km_QIQI6C-^7*tv6^!{<6@&vnit?VK-_ z(tKBg<LNoyi4Exa^d=pK?|pFci&ulv`^Vj*?&TVwke-`k(q3_o)WxxVq&uTHDf3{u zAmhUN%3^u?bCe!XI@79{Ov8=2z8QpWWx2J9w7EqW!0Ji&rtiv(!Szv?zB#ry|5nxC z2*s_4S$60L@HhLQ#tr;N?Nqf@hliCu$3{h6gYPcb+@P2L<k<2mZnfS5{9APiG@33> z!FtRT92S~vzsX#1Thy9kOM);OS}Z8D)o6euDXSJfO&P{Tf=*P#Iaqgw-)*V3^8p&G z?I3v~%7~9Gnt;0vzClbRqg{0$6AySBn(>X<RpnPO;qJXRk!FgDy^l-Twsr1Y+d7Qn zEROT%J~7XJVxAv8_;f*z031LaLY!WZWA}g@y1<fQX#~Czi}r8qO&Zg{q?ql;2XuR3 z00X5)+s2D2_@bMF;|mNjCVB~mH>HMn{D|P3YjHLj!uO;W@WOz-i>6axDRTXHQpWMz zFx!VlP^B@bWZe-_G0yHIO3@aLBxW`xCT-|XdI&l)mY_8Ij)+Pj1kGzQ(vBr+J|!yE zCarS+(L>s?v7`;Wv?BsD33%EOfd^9pdv#pXh%q;9&l6*59DZ*{WTqHzM`U&zHx-H9 zL*4ksO|$QaC`@ZPv)iG@?Hwt*Y!6*e?nr8jrQHK#JSJu0OycTNWGO$&aRyhb<K*pE z-n#h4<yWG@YhPM?<E>X-dhzlr>S^`~fdv$%dV|TEOuov5ej;_5$rUDDEGTE<Nqhwl z{t<^B<frIWnYS%Wy7iaCybSpq_HD)7>8yeMomPd`CD7LHzIhL`&u<wkrYt$;Q)_2; z{dS2l;xbkIT1VUw!8AeeJ-}d?CoFBFMXbe3Fp8f;PMHM`bvmrhSu0J=7}<$(Hx*%? zH_4_DQ)vO+n(Y##dVRBoiEuoMBn`N5w%)2%>cRPi_)R!sCS(B{3tB;x;a$#-mq^2V zOej0(iQJGn=f{<eg?+uiX_)&m>I1x2#gTqExxIiR_z9Aq4<Hd7{V2bLhyV?b;9H%< zITvE-XD#Afe6%>9!nv&T<9r(DiI;X4&J!=~49@p^2jtz|-a+qC_-JSSJ>Fy9A-Ol_ z&#mwE9#5`37fp0Hn&^V74A!U9;k_SRef?Z#0AJzyTo1+?i>r>k@O)Zk7ZqIra;kao zDb>O)H^Fd#30$5M`~uwJ2i3}kkHu6tQ}q(V&04)aqA;(;r3(KRT=ogv(s(LfB~GBn zR%;XME?AmHY(Tt@-vuGPv;p+7Dp~dfXw#Diu9?LV1p@wn+JKHQ2)SOe>NA2ipgcme z3OKF04Xm*eYOSaimV@HO?v#Bl5P7wr+S*i=RlmC&)}?G2uo0N5zKQvcOW|P&ZcCQ< z`lU6@)v*`OqP@<QT%g-GxKN`7q*td$G{q1ny%;(n=skcn;AMP{y6?o;b`Z#(M7xYY ztV87|WwI=d8zEn=9Lcg0aBe7q1F|KcMnfms)6Z)cO0vLCUp3=3@mRCfED63Dr;bnu z56!JSX?ig_ePy$@qY1{v!dQ!7pBRi$EFRa$z|L9)kqda_`72lhgi0eS!o`yMh?2Tp zBF4*XXuRq-Wi^fqZvBjt0Nu!#1)-U{pP>d9M)g7-wO3yjhKLx|;x}Fx$_A;vcly+G z@1HnadZD*cf1}m22ADk2S@F)*1$|mNjz>okcp&T5qe@R+?fE^*<%_ZJFynit%2yZO zAEuVij#WC#ooYu_JC*vz8ZO{f?Vvy&H){UPejVZ){5-5gVWm6A)GxShX}ErHo;>aO z1wSp!3&#n8Iq~ADSYjQDT=RE~?{z?SN0s7RnwDW6K+KSIkGfxjNsO%+VyIk%3iK&@ z1-g2J0U)CBiGGhLCv3rQ%wQ2{x-6MdyBo5~jY2!pYZ_Qo*0)<5j0EZp5lMsr)`m)t z*^l`HLH(R|weF};yNwjDo_Mcvsx2Cu$}zoDIu0d1s<|CWN54f$sJ^;z^|%<pRCvJ_ z7W!{-)qG)Fz36YN{u)Nf<0xXJxT20}Sy+>``FK?m3M42AeLHm7pAfWzfE};4is&c| z92EW#S83nFFty56p3!#Y>-|OroDbO*ls<~8VYT}uS(Xz*WULP8K^UUM0$1D<GW`1$ zj}26DkN3AgtZzx<_Wb@|vpYSk$>}f24h>eD_QMw*(z&5;v_+$OcYpKkqyxPOa3^7C zDfkLB(9i(10>9ZZ`U8SmRuG7U-ZZ-BjKd9HYat1f!|a43_nN=u0;Y1jl`2Mb!#)!` z3?Z7Z!YDyX(p0j)VaQsk-5ODv;4ng_)Sw3=JN97>>wCMmfH~<Y0$?h2j1UYZi@{<r zY(oYcR9_$M5v~S6Hvxl*Vq_!;HZg{iogwPS73Z~@Plqvb#aQDn{I8jo;~+6LoI~_O zpGUCp|Hk7}0WpJ;{q&4S*NpVJp$pxSR$aneUww(mt4v;F@?|E!iX@t-sO1_W$JACS z-?qLEA9KIISuuP=eFaI|#$+t@Y|#zFmARL21awIv9Khh}`hCR3d-h#~a=@cvKEUA_ zp7R?Pg9I2Q<z+r^;Mc&43|8I5?_#xHm+PEd+p-9mUyRI!)bRtihB$rbSqd1?KxeXt zHP)ih+9&65EEnnKvlk<W05h^-dEu-nAVx%m0YevYW!~y>Nr@{Zf3{v}EPIvn-%ng= zaC1MC`WNWn)~@8PM7s{0<lT?|3!k>NaGV}`N)Q1m&U&lXjGTH6v`jDnFckOBL<mHQ zRS>w>rc=*Quu(@FaA7r$%<6icqpUWUgLLm1LD)CR!YoQLCLMUw5Upett%8%cW)QRV zP?pkWwefQ5x8J};$I^mUZ-%mVO#d1}C$PHgS!`5XTcM4{PFET{1EE`Jc0NU32D%|S z<f?TW;a$ynl!9kik+#-z!CJRWDuS#G*oze8$Nve5BG4_5^;2m)@y0<Io6GfDRbhLK zq0S(Q?7H7%a9br^D2*~QDh+w=1|%q+%Ri*VxTtB^1*>4sWQv&?X9gZfETLNM`4KXc zndfM6O`{m<B3XH0i8hLVmoCz6sd*Eb{w7gD!)iY|qVCa)2W&Fwg<N2VUlUDs$Gny< z9k7#bTl-g$>2G^#KQf~B)Vr-6_I)xKO+&gmup=7iI{v#J8lD_M!#4i^lnlD2wIHBr z)GV~J#5-8)X7B~XK$z+aj4@k>sF;tx*DUn~=F!`F7B5|a)JVAEf__w72A)Vd?6&fx zo%(z7LY*)ic(hF?TQuiPCo{5TQ`wG|Djm6f>^M7T2Ta-$Yq>On;iZ0t9o@^O8Snuc z8sk>Q<#e@)WLv)J^#51#Eq$t&Z-gcY_m6MWs-p!!lTY&RAYAl8EDD|_Yl)UN2I%=W zeYG8xQFnnS9sC?DEhNi{qq<(2F&&bqYpK3bcM(p4un+{b&hSiP7EM?^+B&RFT+6CO z{KCem3$UpeA|IGMO9n?;QFh#QM=g5jI9?WmS#GhE(E~Dv6)pf{faWl)Z!R2HG|^Ws zA^t=nUKt*yt}|gAk|=H>j3;?x)G{w)c5>ui1`ae+7STC*dlnHSSjVv1d%F#WktkM) zpl<=1%Q7$F2!7tMs>f65TZ^TA1M5@j*GT%?Ox|JgE|ae@=`KaFgD3{7ZnGY>#Vju~ zA=~N*6RxiGBt!*@ald=0$H#G!|6p*9iYrxlyLhm8R0pIK_ZJ_>^}M{-KJ>w{*z0u+ zKreCJmEwC(q#DF=HiJV%N1_naWZrr{fi?&^Iti^X5iJXFL+GT=bQoTau<{20QwUO; z!8OKOeU5-78hvX~Eu$<Tkc_~JXo}%Qm~iP;K6MNaqpW``#K;<D#qSlU7x;#w<Bqb} z__kRObwt-QcrYj&4!%#b#l*M)X3QYU2&pw~%D|lJ1{tJE2!lVx$tu1U!qLDCU`31; zWv5^Vu{c1BU<&LdPk<!vf~oWg-suRg^c(^Y&(Nq+zk`v_0lFM~VgY9YX|4i@cuqG5 z(W%ZmZ``rwP`i}UpEu6YeXE<7w6Etn)<>WtKDT+k!Z6s}V%o;gA&H(9;L6d2t@|KZ zkB)M+Ks;So-CM!KK}oOT-sdQ3{2J{;y(niGgzm6T^$nEukorEK)F&~giV7N;rxC+O z9Z~B{t}&@IAz@J#>r#NXk=>}=iZazTY!<@4Rj2N+U@wBIt*(Vpffv|_0GJz1$}N2{ z$Z&}A&X52u?jjW1K42b@gLw8SOH!w3D(0&)OY*UCasfy1T_ows=An3>2__xfa*F*X zdY?%q-e;1HL%niws8>D?^_qx7z2fyt*>94pUQYQ_>(f}j#J**&aeDLKew4fmYn0q! zVj>L8jdz&r79?>vDy9|`o5XauT{_B9yj+!)E~0RvH_oD8BUJ4HLKy{bn|Cl}x^+=P z8=t@JY|WyRaJ+DImq8r8>!4#Gj{aR8M=#Ga$@8z_`MWsYF@VNxY^uP<6WM-}kGG$s zssqsr{1<h76c?*d*!SlcB~7(efcgCWZR<Ls7o_o^NhgpGYuMJp>BtNQTJ)2`S<Zks zc{=|V8<sU>jdrP5Ch3lmUZqan`ouh0now=LhHV=@w5;NJVrM1TU*ZF>e6Ct;A6gh< zXH0+<tU$*QXY@9g0&mII>>v)z)T^V>MEYQWYzcXMgY?R%XwOMZrDe_{w0qtzI6b2x z+BBtqNRHC1979rYFmlHWni367O9$(L-9Y2_y3C*L72Gk|1;Z^Q=V84C0+djh9^B60 zEQ#;>Ebn#)IvL}h#XXNKW^rQ3{+1!OM(k)wM=W+xJ?YmIez0g!U#XMAhGJjr6A61M zO-8T}2^4D@^Fu*(5^@VHg!g316x04~WK-W^(og#*6K7ZbrhjWgoo^;e<rwX!du5Ys zhVId+<Q-t58VbekDTEnfgUI)B0X^O`T#*F4Hj*k3YBo2jij>F1+Do%@<O6pIK2A5> zs9#|f52=p(Z8mzU>w+(>W&`_dC{G?z-w$y@Y05sEIUW0l8TYi@<CcdbAp%@N3%10< zkQVQ#xk$yc%GhkRj{g;bi1BwZVc^+>KEtzY^KATdLfwd;=5dBM<mn+f!&|_%-%ao4 z!<+}su?;TX8FJ|*9eDs-u*{|8UP&@`AzX8>DC|DxX3a~8j}b?4vJ%olJcPpXd9Z+y zNTPG7wdx)d*#+}kJfmc#8$^Y-xs&}BrCRB9fI6pshe^LOabrE|#NK%d{tz;74-mhO zl{IIrIh^q*!X;oKdVNR-<mD9fppb5xT*AeOHhD_!!O^8ohHMMSiFUrHt)34t2k6RG z_lw*h=SNYz%zU&AM6n*S6X+3S{|=edz)dqbEsVDJ^fm|j&d~OzRL?#op5lPZ|0z$L z8UA30JPmDCXIn|%8P!*5s2<W+sW$LEmCJv`+F8;F^B@^^Y#t)+nN|<0llw6lI$VCx zQ|X|Q&^h{QO&f0kWJ0ZmCaS>!8ei^T70eBzrA;{$4}o;FYy6N)9%92e#fJ?q5*(}> zgBG0gD~vwlEV%jsp8t8m1Z?+-KK<*NX^ytvGS*Swfd`sfV~jUx_*2%w<~3w$o8`un zu3wK<wWqGWPE1Bq<$x3EXWlII7YTcY)mL!Z7$i$O40pU)NOn>DRa&sw-rpy;v3r9! z6=S`@>qtU`JaW>KY=paqG2q+AJxr)z|DS+*INvt!nZcQR7$ejfx`@K;w~TLLaw8*s z9yxNUdSDYwpMDS@e3ms4J|^IC9W}E2?^&^)5FuD-HZ~DsV41mBU2s0Iqew6dwdNlZ z?h#~ptdIL->(D5biARkI6rjC&6ut&Z;@`8eKB;@&$PG<>^av@W_^(NdAVkc4>Ez4i zF=}KjhRXN%%7nBO_;W6pLaCqNLiRHCY}kT}^7&gXM2(*K{yt9s*WpOgP9o3z9vn;8 zAJtQS?uEjUxrLz{dEdO9#gLK>GhtR5*b8%=EQXg{6L)Xt@GKW%qn8S=zlyz3dG!(Y zLVeV6f**D=_b1|=P_JTFRC<nDoZ!cujQVj*BhE26VFn<84K5qqj-`T@r;NfJM<a*- zqeTx|1A?c_wbx;AbCkr}M|r(H3E=ES<`i9EXB-&2Wh>D?u@#QvAsnsnUS%PDY}UrV zB*6Y5v`fKqZ0zZ!H_I$ychn5MTK&V_$h}argMO&fte>d4XB*V-^OEDL{EG!e45t2o z$;(W-PNp4fej=9n3R$6M<*mZr{Dj0oKawxti&*I5ZrS+sn4q50WBh+mE1USYMfe9S z3hx<;9bB=etH+sKWg>HRI?pg(=_M?^i8#lHPcfk;Drp|+62HgGNhDG3#fvX}1#xCk zR{x(I`411W>q=%_5?-ulV(;*s51G(6B(rl3&1QJnP1tdw{8{~9tj?3tfF#UeSD<{c eP&H@IWapoo`Gzqu^K5<szuz$S6uAHE;C}<Aw9ShE literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..977a2716b5bb4026ade717ed7a7c13a847c5682e GIT binary patch literal 1412 zcmbVMPj6#25V!sQ<~7MKy9Eiv;eilK==QZp9IFZ~T;R~lq6LLrJ-x<m;`IGn+ezDy zURch21(G9t5I%&Da9W8^&=WImS}5X#lbL7FjK?$c8~aJGmk=1kpFe#5I3(l`T-*!~ zCZ7T6uYhsFX-O(Nq!k;o${TtVWvujvKKHm^230r=t7sTeBK%d%gEbv?c*vt4$uQwD z@4$D9v!`T`yas<{;Mse{v2Mzl5xK0|Mj0D(IhR^Cwe7b`)+Rrh)guGzqt_I-Fx&sK zo)@L$&xCSz(Ppv;zuV2T7ds=g!+~EP=yM=_ADAI4%IT7<*@~?Rgu#xk=q^O@Fdr3l zQ_B(fU5H$Xu{gJ$o*mnuY|exlQ0v!4C4M2Q2Y#*&_Dt38wX)rnwKhdr?vBpJ_0+ul z6oroRxu|)g_S#}}T8w2q-kTX&>a4x6Z`?Ty{q`|J28=Lu5BO~gC_{8y3V*`nqHD;K zyrP%n8&Yrk#L&}3r4(|dAb(1}C1Y|4DNY%ur=EJUq$`iJm5-7&T~n|Ei3wIABF2MN zbd3+_<1fH3*m%y0OglV2?Wmue2OsP@h$Gl_Hg@QXOaWK0`qfz_?wn+E4w-H_-EU5} z<#b!Ox~|jx?sQ$J>t5?PoVA2F0G{6Bha`pZ^+f6v{&S%&QY|Z47AiGOx&c1Rb8S?f zKTeNlCY=;IZEBGMdZrX9mnSDeiFzco^K~Z8BsCL}o)s6VMDv=LLOYQXr6@FP72`_O zCUYAUw$Z}>e*f~lMfB10Y=5xxfhCq^cR<36qLJPLwj?k5mlS}aujn%X<|X6UZS)BG z$b(R!iCMO9>ACBsYlbaw)j1f8TAa7)a0h)M`aW4ay3;RE1Z?~4plqOB^<j3q=jeY$ zq#nR21EwCrM{Og+7XLda^(HJo0lEn%&e}#BsK+A8xR~R_-vK`8sR(z%8$xU#+GaGd zVbQj54{UhSsH!lQDWR~Rtv_vKZKF-at=B4Hee`QR@QK$Bl7l)$n{;i^7Ru;<#b&qv zt2CI2{umeu8ST<O3z_dF^nveFpECHp6D0Iql-v+g?}PQAYm*$_8#7ZP&lOf*A+8D^ z5%o5*6d5MyQnk^jsajbI)j<*7T<7Q?QMy_pwl+Sf8a^w<A$rqTgl!hH`(EP3!C%4V BSA_ro literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/packaging/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..07ccea0e5a883ad074a41765e58f424b1a6ebc4e GIT binary patch literal 11930 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py new file mode 100644 index 0000000..210bb80 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/_compat.py @@ -0,0 +1,30 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, + + +def with_metaclass(meta, *bases): + """ + Create a base class with a metaclass. + """ + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py new file mode 100644 index 0000000..e9fc4a0 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/_structures.py @@ -0,0 +1,70 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + + +NegativeInfinity = NegativeInfinity() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py new file mode 100644 index 0000000..e5834ce --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/markers.py @@ -0,0 +1,301 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from pip._vendor.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from pip._vendor.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from pip._vendor.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +class Variable(Node): + + def serialize(self): + return str(self) + + +class Value(Node): + + def serialize(self): + return '"{0}"'.format(self) + + +class Op(Node): + + def serialize(self): + return str(self) + + +VARIABLE = ( + L("implementation_version") | + L("platform_python_implementation") | + L("implementation_name") | + L("python_full_version") | + L("platform_release") | + L("platform_version") | + L("platform_machine") | + L("platform_system") | + L("python_version") | + L("sys_platform") | + L("os_name") | + L("os.name") | # PEP-345 + L("sys.platform") | # PEP-345 + L("platform.version") | # PEP-345 + L("platform.machine") | # PEP-345 + L("platform.python_implementation") | # PEP-345 + L("python_implementation") | # undocumented setuptools legacy + L("extra") +) +ALIASES = { + 'os.name': 'os_name', + 'sys.platform': 'sys_platform', + 'platform.version': 'platform_version', + 'platform.machine': 'platform_machine', + 'platform.python_implementation': 'platform_python_implementation', + 'python_implementation': 'platform_python_implementation' +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # where the single item is itself it's own list. In that case we want skip + # the rest of this function so that we don't get extraneous () on the + # outside. + if (isinstance(marker, list) and len(marker) == 1 and + isinstance(marker[0], (list, tuple))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "sys_platform": sys.platform, + } + + +class Marker(object): + + def __init__(self, marker): + try: + self._markers = _coerce_parse_result(MARKER.parseString(marker)) + except ParseException as e: + err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( + marker, marker[e.loc:e.loc + 8]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py new file mode 100644 index 0000000..d40bd8c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/requirements.py @@ -0,0 +1,130 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from pip._vendor.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from pip._vendor.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from pip._vendor.pyparsing import Literal as L # noqa +from pip._vendor.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) +VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) + +VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY +VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), + joinString=",", adjacent=False)("_raw_spec") +_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') + +VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") +VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) + +MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") +MARKER_EXPR.setParseAction( + lambda s, l, t: Marker(s[t._original_start:t._original_end]) +) +MARKER_SEPARATOR = SEMICOLON +MARKER = MARKER_SEPARATOR + MARKER_EXPR + +VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) +URL_AND_MARKER = URL + Optional(MARKER) + +NAMED_REQUIREMENT = \ + NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd +# pyparsing isn't thread safe during initialization, so we do it eagerly, see +# issue #104 +REQUIREMENT.parseString("x[]") + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + req = REQUIREMENT.parseString(requirement_string) + except ParseException as e: + raise InvalidRequirement("Parse error at \"{0!r}\": {1}".format( + requirement_string[e.loc:e.loc + 8], e.msg + )) + + self.name = req.name + if req.url: + parsed_url = urlparse.urlparse(req.url) + if not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc): + raise InvalidRequirement("Invalid URL: {0}".format(req.url)) + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..4c79899 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/specifiers.py @@ -0,0 +1,774 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=None): + match = self._regex.search(spec) + if not match: + raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) + + self._spec = ( + match.group("operator").strip(), + match.group("version").strip(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format( + self.__class__.__name__, + str(self), + pre, + ) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Determine if prereleases are to be allowed or not. + if prereleases is None: + prereleases = self.prereleases + + # Normalize item to a Version or LegacyVersion, this allows us to have + # a shortcut for ``"2.0" in Specifier(">=2") + item = self._coerce_version(item) + + # Determine if we should be supporting prereleases in this specifier + # or not, if we do not support prereleases than we can short circuit + # logic if this version is a prereleases. + if item.is_prerelease and not prereleases: + return False + + # Actually do the comparison to determine if this item is contained + # within this Specifier or not. + return self._get_operator(self.operator)(item, self.version) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # If our version is a prerelease, and we were not set to allow + # prereleases, then we'll store it for later incase nothing + # else matches this specifier. + if (parsed_version.is_prerelease and not + (prereleases or self.prereleases)): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the beginning. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # Compatible releases have an equivalent combination of >= and ==. That + # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to + # implement this in terms of the other specifiers instead of + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not + x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return (self._get_operator(">=")(prospective, spec) and + self._get_operator("==")(prospective, prefix)) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # We need special logic to handle prefix matching + if spec.endswith(".*"): + # In the case of prefix matching we want to ignore local segment. + prospective = Version(prospective.public) + # Split the spec out by dots, and pretend that there is an implicit + # dot in between a release segment and a pre-release segment. + spec = _version_split(spec[:-2]) # Remove the trailing .* + + # Split the prospective version out by dots, and pretend that there + # is an implicit dot in between a release segment and a pre-release + # segment. + prospective = _version_split(str(prospective)) + + # Shorten the prospective version to be the same length as the spec + # so that we can determine if the specifier is a prefix of the + # prospective version or not. + prospective = prospective[:len(spec)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = Version(spec) + + # If the specifier does not have a local segment, then we want to + # act as if the prospective version also does not have a local + # segment. + if not spec.local: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is less than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is greater than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # Ensure that we do not allow a local version of the version mentioned + # in the specifier, which is technically greater than, to match. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) + + # Get the rest of our versions + left_split.append(left[len(left_split[0]):]) + right_split.append(right[len(right_split[0]):]) + + # Insert our padding + left_split.insert( + 1, + ["0"] * max(0, len(right_split[0]) - len(left_split[0])), + ) + right_split.insert( + 1, + ["0"] * max(0, len(left_split[0]) - len(right_split[0])), + ) + + return ( + list(itertools.chain(*left_split)), + list(itertools.chain(*right_split)), + ) + + +class SpecifierSet(BaseSpecifier): + + def __init__(self, specifiers="", prereleases=None): + # Split on , to break each indidivual specifier into it's own item, and + # strip each item to remove leading/trailing whitespace. + specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + + # Parsed each individual specifier, attempting first to make it a + # Specifier and falling back to a LegacySpecifier. + parsed = set() + for specifier in specifiers: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # given version is contained within all of them. + # Note: This use of all() here means that an empty set of specifiers + # will always return True, this is an explicit design decision. + return all( + s.contains(item, prereleases=prereleases) + for s in self._specs + ) + + def filter(self, iterable, prereleases=None): + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # which will filter out any pre-releases, unless there are no final + # releases, and which will filter out LegacyVersion in general. + else: + filtered = [] + found_prereleases = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py new file mode 100644 index 0000000..4b94a82 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/utils.py @@ -0,0 +1,63 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + +from .version import InvalidVersion, Version + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() + + +def canonicalize_version(version): + """ + This is very similar to Version.__str__, but has one subtle differences + with the way it handles the release segment. + """ + + try: + version = Version(version) + except InvalidVersion: + # Legacy versions cannot be normalized + return version + + parts = [] + + # Epoch + if version.epoch != 0: + parts.append("{0}!".format(version.epoch)) + + # Release segment + # NB: This strips trailing '.0's to normalize + parts.append( + re.sub( + r'(\.0)+$', + '', + ".".join(str(x) for x in version.release) + ) + ) + + # Pre-release + if version.pre is not None: + parts.append("".join(str(x) for x in version.pre)) + + # Post-release + if version.post is not None: + parts.append(".post{0}".format(version.post)) + + # Development release + if version.dev is not None: + parts.append(".dev{0}".format(version.dev)) + + # Local version segment + if version.local is not None: + parts.append("+{0}".format(version.local)) + + return "".join(parts) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/packaging/version.py b/env/lib/python3.7/site-packages/pip/_vendor/packaging/version.py new file mode 100644 index 0000000..6ed5cbb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/packaging/version.py @@ -0,0 +1,441 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(version): + """ + Parse the given version string and return either a :class:`Version` object + or a :class:`LegacyVersion` object depending on if the given version is + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def base_version(self): + return self._version + + @property + def epoch(self): + return -1 + + @property + def release(self): + return None + + @property + def pre(self): + return None + + @property + def post(self): + return None + + @property + def dev(self): + return None + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + @property + def is_postrelease(self): + return False + + @property + def is_devrelease(self): + return False + + +_legacy_version_component_re = re.compile( + r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, +) + +_legacy_version_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch + # greater than or equal to 0. This will effectively put the LegacyVersion, + # which uses the defacto standard originally implemented by setuptools, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + return epoch, parts + + +# Deliberately not anchored to the start and end of the string, to make it +# easier for 3rd party code to reuse +VERSION_PATTERN = r""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _regex = re.compile( + r"^\s*" + VERSION_PATTERN + r"\s*$", + re.VERBOSE | re.IGNORECASE, + ) + + def __init__(self, version): + # Validate the version and parse it into pieces + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + self._version = _Version( + epoch=int(match.group("epoch")) if match.group("epoch") else 0, + release=tuple(int(i) for i in match.group("release").split(".")), + pre=_parse_letter_version( + match.group("pre_l"), + match.group("pre_n"), + ), + post=_parse_letter_version( + match.group("post_l"), + match.group("post_n1") or match.group("post_n2"), + ), + dev=_parse_letter_version( + match.group("dev_l"), + match.group("dev_n"), + ), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + # Pre-release + if self.pre is not None: + parts.append("".join(str(x) for x in self.pre)) + + # Post-release + if self.post is not None: + parts.append(".post{0}".format(self.post)) + + # Development release + if self.dev is not None: + parts.append(".dev{0}".format(self.dev)) + + # Local version segment + if self.local is not None: + parts.append("+{0}".format(self.local)) + + return "".join(parts) + + @property + def epoch(self): + return self._version.epoch + + @property + def release(self): + return self._version.release + + @property + def pre(self): + return self._version.pre + + @property + def post(self): + return self._version.post[1] if self._version.post else None + + @property + def dev(self): + return self._version.dev[1] if self._version.dev else None + + @property + def local(self): + if self._version.local: + return ".".join(str(x) for x in self._version.local) + else: + return None + + @property + def public(self): + return str(self).split("+", 1)[0] + + @property + def base_version(self): + parts = [] + + # Epoch + if self.epoch != 0: + parts.append("{0}!".format(self.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self.release)) + + return "".join(parts) + + @property + def is_prerelease(self): + return self.dev is not None or self.pre is not None + + @property + def is_postrelease(self): + return self.post is not None + + @property + def is_devrelease(self): + return self.dev is not None + + +def _parse_letter_version(letter, number): + if letter: + # We consider there to be an implicit 0 in a pre-release if there is + # not a numeral associated with it. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_separators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_separators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # When we compare a release version, we want to compare it with all of the + # trailing zeros removed. So we'll use a reverse the list, drop all the now + # leading zeros until we come to something non zero, then take the rest + # re-reverse it back into the correct order and make it a tuple and use + # that for our sorting key. + release = tuple( + reversed(list( + itertools.dropwhile( + lambda x: x == 0, + reversed(release), + ) + )) + ) + + # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # if there is not a pre or a post segment. If we have one of those then + # the normal sorting rules will handle this case correctly. + if pre is None and post is None and dev is not None: + pre = -Infinity + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - Numeric segments sort numerically + # - Shorter versions sort before longer versions when the prefixes + # match exactly + local = tuple( + (i, "") if isinstance(i, int) else (-Infinity, i) + for i in local + ) + + return epoch, release, pre, post, dev, local diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py new file mode 100644 index 0000000..8beedea --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__init__.py @@ -0,0 +1,4 @@ +"""Wrappers to build Python packages using PEP 517 hooks +""" + +__version__ = '0.2' diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd73fb1167afadf361e748a6ee850343ae5326d6 GIT binary patch literal 237 zcmZ?b<>g`kf~fgwF+o83F^B^Lj6jA15Et_Ri4=w?h7`sq#uTPt22JKFv+$zCf`Zhd zVug}?g{0EVoD_wC%94!yJcWY9<m|-s)MACw;>^5sg#gz81ye(Fg^c|C>|(AeW&=GV zKTW1v?D6p_`N{F|x47fu%YepY=I6!7uVg4<23iFse%a`k<QC``WESXV<`tJD=H%!m zm#61tl@ywQ1i=`nGcP5-NWUPp0BD7Ne0*kJW=VX!UP0w84x8Nkl+v73J0_3^Km-dD E02N0;egFUf literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/_in_process.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..123da33e6ba1b8ae9a9833ecd483504e01ed4494 GIT binary patch literal 5302 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/check.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f4fa36f65a5e6eed18ea64a4609b2857956c9632 GIT binary patch literal 4701 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 T_pW!tyV#s1ylsK*xt{qSy>{h# literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/colorlog.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f973471f7480b7debc1650ed790b4b01c7e184f4 GIT binary patch literal 2866 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d665bacb67b6a16454426a3cf7fbeb70749bca1 GIT binary patch literal 975 zcmaJ<&x_MQ6rNvg)7mcepx{Mv5Fub&TvuFV5mAsuq5i0%6d|OYw3}|4#7VlLOZKE! z-J?hK=)W{qPx~);^1aFKTBPfP_g>!2WZw6EZyvQ;4FWd&cJqDC2>FG@nL$k+f~UI> zBpDJ(B@5}0n#_jGXEQG8H6r<bMQuqTE1$?v$f~SCu0(BVovzf&70Cv~X&mnCdXWr$ zTlt<0qNxp)ovR?j@27+3eLINkH?N;`wr|;SWWQKudywv!W1HO*z(V>b9O4)Oq6zRi z_%rad3n3$g0V(-seth+aXLQC2Qt$~Y*cVF4TcGojydv))10>PcG(W5?vPoy#q1y7J zag4|uu0@>qkruNwhA0>F#1WduqnQ?om+k55e(tGhs_En>QBCOl`+hH*C%q&{Izg0X zUKn=9`81kkAGUDOxO?D7GFH9BPww8n*Bi%kxT~8ibpuuKU2IlED#(k_HdPyt#}q3t zWQ}YegQqtj09!K}!?t-uGy0ts^amaM%Tb+kRCu++RRxl&LeL_NJ?SuoH>*n+kWLv| zc%Y8sGT3nUFSg52t)Iju?39!E$d0eCPC+us16r`J7fgfYBZKe^?+Q?b$~Zz<kV>%l zfY%{5sv){ltWCOJLK}{h5(3PN<YRr!)M!;P)rSB6BbdV0SHREPJ5^nCT^WyEx73`c x%TzZHe3b@q<Ob0sHki$yEApE`m>F0*^H?rI{{g;*6kmm)7PZ(0vqYn6i9ZH6!5aVo literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/envbuild.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fd358d367dd0dd5027ecd774d765df7421c9204e GIT binary patch literal 4132 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 F{{SUFStbAg literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pep517/__pycache__/wrappers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eb60294683942ab0a9bcd12a8edbb393eac6c407 GIT binary patch literal 4699 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py b/env/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py new file mode 100644 index 0000000..baa14d3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pep517/_in_process.py @@ -0,0 +1,182 @@ +"""This is invoked in a subprocess to call the build backend hooks. + +It expects: +- Command line args: hook_name, control_dir +- Environment variable: PEP517_BUILD_BACKEND=entry.point:spec +- control_dir/input.json: + - {"kwargs": {...}} + +Results: +- control_dir/output.json + - {"return_val": ...} +""" +from glob import glob +from importlib import import_module +import os +from os.path import join as pjoin +import re +import shutil +import sys + +# This is run as a script, not a module, so it can't do a relative import +import compat + +def _build_backend(): + """Find and load the build backend""" + ep = os.environ['PEP517_BUILD_BACKEND'] + mod_path, _, obj_path = ep.partition(':') + obj = import_module(mod_path) + if obj_path: + for path_part in obj_path.split('.'): + obj = getattr(obj, path_part) + return obj + +def get_requires_for_build_wheel(config_settings): + """Invoke the optional get_requires_for_build_wheel hook + + Returns [] if the hook is not defined. + """ + backend = _build_backend() + try: + hook = backend.get_requires_for_build_wheel + except AttributeError: + return [] + else: + return hook(config_settings) + +def prepare_metadata_for_build_wheel(metadata_directory, config_settings): + """Invoke optional prepare_metadata_for_build_wheel + + Implements a fallback by building a wheel if the hook isn't defined. + """ + backend = _build_backend() + try: + hook = backend.prepare_metadata_for_build_wheel + except AttributeError: + return _get_wheel_metadata_from_wheel(backend, metadata_directory, + config_settings) + else: + return hook(metadata_directory, config_settings) + +WHEEL_BUILT_MARKER = 'PEP517_ALREADY_BUILT_WHEEL' + +def _dist_info_files(whl_zip): + """Identify the .dist-info folder inside a wheel ZipFile.""" + res = [] + for path in whl_zip.namelist(): + m = re.match(r'[^/\\]+-[^/\\]+\.dist-info/', path) + if m: + res.append(path) + if res: + return res + raise Exception("No .dist-info folder found in wheel") + +def _get_wheel_metadata_from_wheel(backend, metadata_directory, config_settings): + """Build a wheel and extract the metadata from it. + + Fallback for when the build backend does not define the 'get_wheel_metadata' + hook. + """ + from zipfile import ZipFile + whl_basename = backend.build_wheel(metadata_directory, config_settings) + with open(os.path.join(metadata_directory, WHEEL_BUILT_MARKER), 'wb'): + pass # Touch marker file + + whl_file = os.path.join(metadata_directory, whl_basename) + with ZipFile(whl_file) as zipf: + dist_info = _dist_info_files(zipf) + zipf.extractall(path=metadata_directory, members=dist_info) + return dist_info[0].split('/')[0] + +def _find_already_built_wheel(metadata_directory): + """Check for a wheel already built during the get_wheel_metadata hook. + """ + if not metadata_directory: + return None + metadata_parent = os.path.dirname(metadata_directory) + if not os.path.isfile(pjoin(metadata_parent, WHEEL_BUILT_MARKER)): + return None + + whl_files = glob(os.path.join(metadata_parent, '*.whl')) + if not whl_files: + print('Found wheel built marker, but no .whl files') + return None + if len(whl_files) > 1: + print('Found multiple .whl files; unspecified behaviour. ' + 'Will call build_wheel.') + return None + + # Exactly one .whl file + return whl_files[0] + +def build_wheel(wheel_directory, config_settings, metadata_directory=None): + """Invoke the mandatory build_wheel hook. + + If a wheel was already built in the prepare_metadata_for_build_wheel fallback, this + will copy it rather than rebuilding the wheel. + """ + prebuilt_whl = _find_already_built_wheel(metadata_directory) + if prebuilt_whl: + shutil.copy2(prebuilt_whl, wheel_directory) + return os.path.basename(prebuilt_whl) + + return _build_backend().build_wheel(wheel_directory, config_settings, + metadata_directory) + + +def get_requires_for_build_sdist(config_settings): + """Invoke the optional get_requires_for_build_wheel hook + + Returns [] if the hook is not defined. + """ + backend = _build_backend() + try: + hook = backend.get_requires_for_build_sdist + except AttributeError: + return [] + else: + return hook(config_settings) + +class _DummyException(Exception): + """Nothing should ever raise this exception""" + +class GotUnsupportedOperation(Exception): + """For internal use when backend raises UnsupportedOperation""" + +def build_sdist(sdist_directory, config_settings): + """Invoke the mandatory build_sdist hook.""" + backend = _build_backend() + try: + return backend.build_sdist(sdist_directory, config_settings) + except getattr(backend, 'UnsupportedOperation', _DummyException): + raise GotUnsupportedOperation + +HOOK_NAMES = { + 'get_requires_for_build_wheel', + 'prepare_metadata_for_build_wheel', + 'build_wheel', + 'get_requires_for_build_sdist', + 'build_sdist', +} + +def main(): + if len(sys.argv) < 3: + sys.exit("Needs args: hook_name, control_dir") + hook_name = sys.argv[1] + control_dir = sys.argv[2] + if hook_name not in HOOK_NAMES: + sys.exit("Unknown hook: %s" % hook_name) + hook = globals()[hook_name] + + hook_input = compat.read_json(pjoin(control_dir, 'input.json')) + + json_out = {'unsupported': False, 'return_val': None} + try: + json_out['return_val'] = hook(**hook_input['kwargs']) + except GotUnsupportedOperation: + json_out['unsupported'] = True + + compat.write_json(json_out, pjoin(control_dir, 'output.json'), indent=2) + +if __name__ == '__main__': + main() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/check.py b/env/lib/python3.7/site-packages/pip/_vendor/pep517/check.py new file mode 100644 index 0000000..c65d51c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pep517/check.py @@ -0,0 +1,194 @@ +"""Check a project and backend by attempting to build using PEP 517 hooks. +""" +import argparse +import logging +import os +from os.path import isfile, join as pjoin +from pip._vendor.pytoml import TomlError, load as toml_load +import shutil +from subprocess import CalledProcessError +import sys +import tarfile +from tempfile import mkdtemp +import zipfile + +from .colorlog import enable_colourful_output +from .envbuild import BuildEnvironment +from .wrappers import Pep517HookCaller + +log = logging.getLogger(__name__) + +def check_build_sdist(hooks): + with BuildEnvironment() as env: + try: + env.pip_install(hooks.build_sys_requires) + log.info('Installed static build dependencies') + except CalledProcessError: + log.error('Failed to install static build dependencies') + return False + + try: + reqs = hooks.get_requires_for_build_sdist({}) + log.info('Got build requires: %s', reqs) + except: + log.error('Failure in get_requires_for_build_sdist', exc_info=True) + return False + + try: + env.pip_install(reqs) + log.info('Installed dynamic build dependencies') + except CalledProcessError: + log.error('Failed to install dynamic build dependencies') + return False + + td = mkdtemp() + log.info('Trying to build sdist in %s', td) + try: + try: + filename = hooks.build_sdist(td, {}) + log.info('build_sdist returned %r', filename) + except: + log.info('Failure in build_sdist', exc_info=True) + return False + + if not filename.endswith('.tar.gz'): + log.error("Filename %s doesn't have .tar.gz extension", filename) + return False + + path = pjoin(td, filename) + if isfile(path): + log.info("Output file %s exists", path) + else: + log.error("Output file %s does not exist", path) + return False + + if tarfile.is_tarfile(path): + log.info("Output file is a tar file") + else: + log.error("Output file is not a tar file") + return False + + finally: + shutil.rmtree(td) + + return True + +def check_build_wheel(hooks): + with BuildEnvironment() as env: + try: + env.pip_install(hooks.build_sys_requires) + log.info('Installed static build dependencies') + except CalledProcessError: + log.error('Failed to install static build dependencies') + return False + + try: + reqs = hooks.get_requires_for_build_wheel({}) + log.info('Got build requires: %s', reqs) + except: + log.error('Failure in get_requires_for_build_sdist', exc_info=True) + return False + + try: + env.pip_install(reqs) + log.info('Installed dynamic build dependencies') + except CalledProcessError: + log.error('Failed to install dynamic build dependencies') + return False + + td = mkdtemp() + log.info('Trying to build wheel in %s', td) + try: + try: + filename = hooks.build_wheel(td, {}) + log.info('build_wheel returned %r', filename) + except: + log.info('Failure in build_wheel', exc_info=True) + return False + + if not filename.endswith('.whl'): + log.error("Filename %s doesn't have .whl extension", filename) + return False + + path = pjoin(td, filename) + if isfile(path): + log.info("Output file %s exists", path) + else: + log.error("Output file %s does not exist", path) + return False + + if zipfile.is_zipfile(path): + log.info("Output file is a zip file") + else: + log.error("Output file is not a zip file") + return False + + finally: + shutil.rmtree(td) + + return True + + +def check(source_dir): + pyproject = pjoin(source_dir, 'pyproject.toml') + if isfile(pyproject): + log.info('Found pyproject.toml') + else: + log.error('Missing pyproject.toml') + return False + + try: + with open(pyproject) as f: + pyproject_data = toml_load(f) + # Ensure the mandatory data can be loaded + buildsys = pyproject_data['build-system'] + requires = buildsys['requires'] + backend = buildsys['build-backend'] + log.info('Loaded pyproject.toml') + except (TomlError, KeyError): + log.error("Invalid pyproject.toml", exc_info=True) + return False + + hooks = Pep517HookCaller(source_dir, backend) + + sdist_ok = check_build_sdist(hooks) + wheel_ok = check_build_wheel(hooks) + + if not sdist_ok: + log.warning('Sdist checks failed; scroll up to see') + if not wheel_ok: + log.warning('Wheel checks failed') + + return sdist_ok + + +def main(argv=None): + ap = argparse.ArgumentParser() + ap.add_argument('source_dir', + help="A directory containing pyproject.toml") + args = ap.parse_args(argv) + + enable_colourful_output() + + ok = check(args.source_dir) + + if ok: + print(ansi('Checks passed', 'green')) + else: + print(ansi('Checks failed', 'red')) + sys.exit(1) + +ansi_codes = { + 'reset': '\x1b[0m', + 'bold': '\x1b[1m', + 'red': '\x1b[31m', + 'green': '\x1b[32m', +} +def ansi(s, attr): + if os.name != 'nt' and sys.stdout.isatty(): + return ansi_codes[attr] + str(s) + ansi_codes['reset'] + else: + return str(s) + +if __name__ == '__main__': + main() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py b/env/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py new file mode 100644 index 0000000..26cf748 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pep517/colorlog.py @@ -0,0 +1,110 @@ +"""Nicer log formatting with colours. + +Code copied from Tornado, Apache licensed. +""" +# Copyright 2012 Facebook +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging +import sys + +try: + import curses +except ImportError: + curses = None + +def _stderr_supports_color(): + color = False + if curses and hasattr(sys.stderr, 'isatty') and sys.stderr.isatty(): + try: + curses.setupterm() + if curses.tigetnum("colors") > 0: + color = True + except Exception: + pass + return color + +class LogFormatter(logging.Formatter): + """Log formatter with colour support + """ + DEFAULT_COLORS = { + logging.INFO: 2, # Green + logging.WARNING: 3, # Yellow + logging.ERROR: 1, # Red + logging.CRITICAL: 1, + } + + def __init__(self, color=True, datefmt=None): + r""" + :arg bool color: Enables color support. + :arg string fmt: Log message format. + It will be applied to the attributes dict of log records. The + text between ``%(color)s`` and ``%(end_color)s`` will be colored + depending on the level if color support is on. + :arg dict colors: color mappings from logging level to terminal color + code + :arg string datefmt: Datetime format. + Used for formatting ``(asctime)`` placeholder in ``prefix_fmt``. + .. versionchanged:: 3.2 + Added ``fmt`` and ``datefmt`` arguments. + """ + logging.Formatter.__init__(self, datefmt=datefmt) + self._colors = {} + if color and _stderr_supports_color(): + # The curses module has some str/bytes confusion in + # python3. Until version 3.2.3, most methods return + # bytes, but only accept strings. In addition, we want to + # output these strings with the logging module, which + # works with unicode strings. The explicit calls to + # unicode() below are harmless in python2 but will do the + # right conversion in python 3. + fg_color = (curses.tigetstr("setaf") or + curses.tigetstr("setf") or "") + if (3, 0) < sys.version_info < (3, 2, 3): + fg_color = str(fg_color, "ascii") + + for levelno, code in self.DEFAULT_COLORS.items(): + self._colors[levelno] = str(curses.tparm(fg_color, code), "ascii") + self._normal = str(curses.tigetstr("sgr0"), "ascii") + + scr = curses.initscr() + self.termwidth = scr.getmaxyx()[1] + curses.endwin() + else: + self._normal = '' + # Default width is usually 80, but too wide is worse than too narrow + self.termwidth = 70 + + def formatMessage(self, record): + l = len(record.message) + right_text = '{initial}-{name}'.format(initial=record.levelname[0], + name=record.name) + if l + len(right_text) < self.termwidth: + space = ' ' * (self.termwidth - (l + len(right_text))) + else: + space = ' ' + + if record.levelno in self._colors: + start_color = self._colors[record.levelno] + end_color = self._normal + else: + start_color = end_color = '' + + return record.message + space + start_color + right_text + end_color + +def enable_colourful_output(level=logging.INFO): + handler = logging.StreamHandler() + handler.setFormatter(LogFormatter()) + logging.root.addHandler(handler) + logging.root.setLevel(level) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py b/env/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py new file mode 100644 index 0000000..01c66fc --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pep517/compat.py @@ -0,0 +1,23 @@ +"""Handle reading and writing JSON in UTF-8, on Python 3 and 2.""" +import json +import sys + +if sys.version_info[0] >= 3: + # Python 3 + def write_json(obj, path, **kwargs): + with open(path, 'w', encoding='utf-8') as f: + json.dump(obj, f, **kwargs) + + def read_json(path): + with open(path, 'r', encoding='utf-8') as f: + return json.load(f) + +else: + # Python 2 + def write_json(obj, path, **kwargs): + with open(path, 'wb') as f: + json.dump(obj, f, encoding='utf-8', **kwargs) + + def read_json(path): + with open(path, 'rb') as f: + return json.load(f) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py b/env/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py new file mode 100644 index 0000000..c264f46 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pep517/envbuild.py @@ -0,0 +1,150 @@ +"""Build wheels/sdists by installing build deps to a temporary environment. +""" + +import os +import logging +from pip._vendor import pytoml +import shutil +from subprocess import check_call +import sys +from sysconfig import get_paths +from tempfile import mkdtemp + +from .wrappers import Pep517HookCaller + +log = logging.getLogger(__name__) + +def _load_pyproject(source_dir): + with open(os.path.join(source_dir, 'pyproject.toml')) as f: + pyproject_data = pytoml.load(f) + buildsys = pyproject_data['build-system'] + return buildsys['requires'], buildsys['build-backend'] + + +class BuildEnvironment(object): + """Context manager to install build deps in a simple temporary environment + + Based on code I wrote for pip, which is MIT licensed. + """ + # Copyright (c) 2008-2016 The pip developers (see AUTHORS.txt file) + # + # Permission is hereby granted, free of charge, to any person obtaining + # a copy of this software and associated documentation files (the + # "Software"), to deal in the Software without restriction, including + # without limitation the rights to use, copy, modify, merge, publish, + # distribute, sublicense, and/or sell copies of the Software, and to + # permit persons to whom the Software is furnished to do so, subject to + # the following conditions: + # + # The above copyright notice and this permission notice shall be + # included in all copies or substantial portions of the Software. + # + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + path = None + + def __init__(self, cleanup=True): + self._cleanup = cleanup + + def __enter__(self): + self.path = mkdtemp(prefix='pep517-build-env-') + log.info('Temporary build environment: %s', self.path) + + self.save_path = os.environ.get('PATH', None) + self.save_pythonpath = os.environ.get('PYTHONPATH', None) + + install_scheme = 'nt' if (os.name == 'nt') else 'posix_prefix' + install_dirs = get_paths(install_scheme, vars={ + 'base': self.path, + 'platbase': self.path, + }) + + scripts = install_dirs['scripts'] + if self.save_path: + os.environ['PATH'] = scripts + os.pathsep + self.save_path + else: + os.environ['PATH'] = scripts + os.pathsep + os.defpath + + if install_dirs['purelib'] == install_dirs['platlib']: + lib_dirs = install_dirs['purelib'] + else: + lib_dirs = install_dirs['purelib'] + os.pathsep + \ + install_dirs['platlib'] + if self.save_pythonpath: + os.environ['PYTHONPATH'] = lib_dirs + os.pathsep + \ + self.save_pythonpath + else: + os.environ['PYTHONPATH'] = lib_dirs + + return self + + def pip_install(self, reqs): + """Install dependencies into this env by calling pip in a subprocess""" + if not reqs: + return + log.info('Calling pip to install %s', reqs) + check_call([sys.executable, '-m', 'pip', 'install', '--ignore-installed', + '--prefix', self.path] + list(reqs)) + + def __exit__(self, exc_type, exc_val, exc_tb): + if self._cleanup and (self.path is not None) and os.path.isdir(self.path): + shutil.rmtree(self.path) + + if self.save_path is None: + os.environ.pop('PATH', None) + else: + os.environ['PATH'] = self.save_path + + if self.save_pythonpath is None: + os.environ.pop('PYTHONPATH', None) + else: + os.environ['PYTHONPATH'] = self.save_pythonpath + +def build_wheel(source_dir, wheel_dir, config_settings=None): + """Build a wheel from a source directory using PEP 517 hooks. + + :param str source_dir: Source directory containing pyproject.toml + :param str wheel_dir: Target directory to create wheel in + :param dict config_settings: Options to pass to build backend + + This is a blocking function which will run pip in a subprocess to install + build requirements. + """ + if config_settings is None: + config_settings = {} + requires, backend = _load_pyproject(source_dir) + hooks = Pep517HookCaller(source_dir, backend) + + with BuildEnvironment() as env: + env.pip_install(requires) + reqs = hooks.get_requires_for_build_wheel(config_settings) + env.pip_install(reqs) + return hooks.build_wheel(wheel_dir, config_settings) + + +def build_sdist(source_dir, sdist_dir, config_settings=None): + """Build an sdist from a source directory using PEP 517 hooks. + + :param str source_dir: Source directory containing pyproject.toml + :param str sdist_dir: Target directory to place sdist in + :param dict config_settings: Options to pass to build backend + + This is a blocking function which will run pip in a subprocess to install + build requirements. + """ + if config_settings is None: + config_settings = {} + requires, backend = _load_pyproject(source_dir) + hooks = Pep517HookCaller(source_dir, backend) + + with BuildEnvironment() as env: + env.pip_install(requires) + reqs = hooks.get_requires_for_build_sdist(config_settings) + env.pip_install(reqs) + return hooks.build_sdist(sdist_dir, config_settings) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py b/env/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py new file mode 100644 index 0000000..28260f3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pep517/wrappers.py @@ -0,0 +1,134 @@ +from contextlib import contextmanager +import os +from os.path import dirname, abspath, join as pjoin +import shutil +from subprocess import check_call +import sys +from tempfile import mkdtemp + +from . import compat + +_in_proc_script = pjoin(dirname(abspath(__file__)), '_in_process.py') + +@contextmanager +def tempdir(): + td = mkdtemp() + try: + yield td + finally: + shutil.rmtree(td) + +class UnsupportedOperation(Exception): + """May be raised by build_sdist if the backend indicates that it can't.""" + +class Pep517HookCaller(object): + """A wrapper around a source directory to be built with a PEP 517 backend. + + source_dir : The path to the source directory, containing pyproject.toml. + backend : The build backend spec, as per PEP 517, from pyproject.toml. + """ + def __init__(self, source_dir, build_backend): + self.source_dir = abspath(source_dir) + self.build_backend = build_backend + + def get_requires_for_build_wheel(self, config_settings=None): + """Identify packages required for building a wheel + + Returns a list of dependency specifications, e.g.: + ["wheel >= 0.25", "setuptools"] + + This does not include requirements specified in pyproject.toml. + It returns the result of calling the equivalently named hook in a + subprocess. + """ + return self._call_hook('get_requires_for_build_wheel', { + 'config_settings': config_settings + }) + + def prepare_metadata_for_build_wheel(self, metadata_directory, config_settings=None): + """Prepare a *.dist-info folder with metadata for this project. + + Returns the name of the newly created folder. + + If the build backend defines a hook with this name, it will be called + in a subprocess. If not, the backend will be asked to build a wheel, + and the dist-info extracted from that. + """ + return self._call_hook('prepare_metadata_for_build_wheel', { + 'metadata_directory': abspath(metadata_directory), + 'config_settings': config_settings, + }) + + def build_wheel(self, wheel_directory, config_settings=None, metadata_directory=None): + """Build a wheel from this project. + + Returns the name of the newly created file. + + In general, this will call the 'build_wheel' hook in the backend. + However, if that was previously called by + 'prepare_metadata_for_build_wheel', and the same metadata_directory is + used, the previously built wheel will be copied to wheel_directory. + """ + if metadata_directory is not None: + metadata_directory = abspath(metadata_directory) + return self._call_hook('build_wheel', { + 'wheel_directory': abspath(wheel_directory), + 'config_settings': config_settings, + 'metadata_directory': metadata_directory, + }) + + def get_requires_for_build_sdist(self, config_settings=None): + """Identify packages required for building a wheel + + Returns a list of dependency specifications, e.g.: + ["setuptools >= 26"] + + This does not include requirements specified in pyproject.toml. + It returns the result of calling the equivalently named hook in a + subprocess. + """ + return self._call_hook('get_requires_for_build_sdist', { + 'config_settings': config_settings + }) + + def build_sdist(self, sdist_directory, config_settings=None): + """Build an sdist from this project. + + Returns the name of the newly created file. + + This calls the 'build_sdist' backend hook in a subprocess. + """ + return self._call_hook('build_sdist', { + 'sdist_directory': abspath(sdist_directory), + 'config_settings': config_settings, + }) + + + def _call_hook(self, hook_name, kwargs): + env = os.environ.copy() + + # On Python 2, pytoml returns Unicode values (which is correct) but the + # environment passed to check_call needs to contain string values. We + # convert here by encoding using ASCII (the backend can only contain + # letters, digits and _, . and : characters, and will be used as a + # Python identifier, so non-ASCII content is wrong on Python 2 in + # any case). + if sys.version_info[0] == 2: + build_backend = self.build_backend.encode('ASCII') + else: + build_backend = self.build_backend + + env['PEP517_BUILD_BACKEND'] = build_backend + with tempdir() as td: + compat.write_json({'kwargs': kwargs}, pjoin(td, 'input.json'), + indent=2) + + # Run the hook in a subprocess + check_call([sys.executable, _in_proc_script, hook_name, td], + cwd=self.source_dir, env=env) + + data = compat.read_json(pjoin(td, 'output.json')) + if data.get('unsupported'): + raise UnsupportedOperation + return data['return_val'] + diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py new file mode 100644 index 0000000..0b432f6 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__init__.py @@ -0,0 +1,3149 @@ +# coding: utf-8 +""" +Package resource API +-------------------- + +A resource is a logical file contained within a package, or a logical +subdirectory thereof. The package resource API expects resource names +to have their path parts separated with ``/``, *not* whatever the local +path separator is. Do not use os.path operations to manipulate resource +names being passed into the API. + +The package resource API is designed to work with normal filesystem packages, +.egg files, and unpacked .egg files. It can also work in a limited way with +.zip files and with custom PEP 302 loaders that support the ``get_data()`` +method. +""" + +from __future__ import absolute_import + +import sys +import os +import io +import time +import re +import types +import zipfile +import zipimport +import warnings +import stat +import functools +import pkgutil +import operator +import platform +import collections +import plistlib +import email.parser +import errno +import tempfile +import textwrap +import itertools +import inspect +from pkgutil import get_importer + +try: + import _imp +except ImportError: + # Python 3.2 compatibility + import imp as _imp + +try: + FileExistsError +except NameError: + FileExistsError = OSError + +from pip._vendor import six +from pip._vendor.six.moves import urllib, map, filter + +# capture these to bypass sandboxing +from os import utime +try: + from os import mkdir, rename, unlink + WRITE_SUPPORT = True +except ImportError: + # no write support, probably under GAE + WRITE_SUPPORT = False + +from os import open as os_open +from os.path import isdir, split + +try: + import importlib.machinery as importlib_machinery + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +except ImportError: + importlib_machinery = None + +from . import py31compat +from pip._vendor import appdirs +from pip._vendor import packaging +__import__('pip._vendor.packaging.version') +__import__('pip._vendor.packaging.specifiers') +__import__('pip._vendor.packaging.requirements') +__import__('pip._vendor.packaging.markers') + + +__metaclass__ = type + + +if (3, 0) < sys.version_info < (3, 4): + raise RuntimeError("Python 3.4 or later is required") + +if six.PY2: + # Those builtin exceptions are only defined in Python 3 + PermissionError = None + NotADirectoryError = None + +# declare some globals that will be defined later to +# satisfy the linters. +require = None +working_set = None +add_activation_listener = None +resources_stream = None +cleanup_resources = None +resource_dir = None +resource_stream = None +set_extraction_path = None +resource_isdir = None +resource_string = None +iter_entry_points = None +resource_listdir = None +resource_filename = None +resource_exists = None +_distribution_finders = None +_namespace_handlers = None +_namespace_packages = None + + +class PEP440Warning(RuntimeWarning): + """ + Used when there is an issue with a version or specifier not complying with + PEP 440. + """ + + +def parse_version(v): + try: + return packaging.version.Version(v) + except packaging.version.InvalidVersion: + return packaging.version.LegacyVersion(v) + + +_state_vars = {} + + +def _declare_state(vartype, **kw): + globals().update(kw) + _state_vars.update(dict.fromkeys(kw, vartype)) + + +def __getstate__(): + state = {} + g = globals() + for k, v in _state_vars.items(): + state[k] = g['_sget_' + v](g[k]) + return state + + +def __setstate__(state): + g = globals() + for k, v in state.items(): + g['_sset_' + _state_vars[k]](k, g[k], v) + return state + + +def _sget_dict(val): + return val.copy() + + +def _sset_dict(key, ob, state): + ob.clear() + ob.update(state) + + +def _sget_object(val): + return val.__getstate__() + + +def _sset_object(key, ob, state): + ob.__setstate__(state) + + +_sget_none = _sset_none = lambda *args: None + + +def get_supported_platform(): + """Return this platform's maximum compatible version. + + distutils.util.get_platform() normally reports the minimum version + of Mac OS X that would be required to *use* extensions produced by + distutils. But what we want when checking compatibility is to know the + version of Mac OS X that we are *running*. To allow usage of packages that + explicitly require a newer version of Mac OS X, we must also know the + current version of the OS. + + If this condition occurs for any other platform with a version in its + platform strings, this function should be extended accordingly. + """ + plat = get_build_platform() + m = macosVersionString.match(plat) + if m is not None and sys.platform == "darwin": + try: + plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) + except ValueError: + # not Mac OS X + pass + return plat + + +__all__ = [ + # Basic resource access and distribution/entry point discovery + 'require', 'run_script', 'get_provider', 'get_distribution', + 'load_entry_point', 'get_entry_map', 'get_entry_info', + 'iter_entry_points', + 'resource_string', 'resource_stream', 'resource_filename', + 'resource_listdir', 'resource_exists', 'resource_isdir', + + # Environmental control + 'declare_namespace', 'working_set', 'add_activation_listener', + 'find_distributions', 'set_extraction_path', 'cleanup_resources', + 'get_default_cache', + + # Primary implementation classes + 'Environment', 'WorkingSet', 'ResourceManager', + 'Distribution', 'Requirement', 'EntryPoint', + + # Exceptions + 'ResolutionError', 'VersionConflict', 'DistributionNotFound', + 'UnknownExtra', 'ExtractionError', + + # Warnings + 'PEP440Warning', + + # Parsing functions and string utilities + 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', + 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', + 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', + + # filesystem utilities + 'ensure_directory', 'normalize_path', + + # Distribution "precedence" constants + 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', + + # "Provider" interfaces, implementations, and registration/lookup APIs + 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', + 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', + 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', + 'register_finder', 'register_namespace_handler', 'register_loader_type', + 'fixup_namespace_packages', 'get_importer', + + # Deprecated/backward compatibility only + 'run_main', 'AvailableDistributions', +] + + +class ResolutionError(Exception): + """Abstract base for dependency resolution errors""" + + def __repr__(self): + return self.__class__.__name__ + repr(self.args) + + +class VersionConflict(ResolutionError): + """ + An already-installed version conflicts with the requested version. + + Should be initialized with the installed Distribution and the requested + Requirement. + """ + + _template = "{self.dist} is installed but {self.req} is required" + + @property + def dist(self): + return self.args[0] + + @property + def req(self): + return self.args[1] + + def report(self): + return self._template.format(**locals()) + + def with_context(self, required_by): + """ + If required_by is non-empty, return a version of self that is a + ContextualVersionConflict. + """ + if not required_by: + return self + args = self.args + (required_by,) + return ContextualVersionConflict(*args) + + +class ContextualVersionConflict(VersionConflict): + """ + A VersionConflict that accepts a third parameter, the set of the + requirements that required the installed Distribution. + """ + + _template = VersionConflict._template + ' by {self.required_by}' + + @property + def required_by(self): + return self.args[2] + + +class DistributionNotFound(ResolutionError): + """A requested distribution was not found""" + + _template = ("The '{self.req}' distribution was not found " + "and is required by {self.requirers_str}") + + @property + def req(self): + return self.args[0] + + @property + def requirers(self): + return self.args[1] + + @property + def requirers_str(self): + if not self.requirers: + return 'the application' + return ', '.join(self.requirers) + + def report(self): + return self._template.format(**locals()) + + def __str__(self): + return self.report() + + +class UnknownExtra(ResolutionError): + """Distribution doesn't have an "extra feature" of the given name""" + + +_provider_factories = {} + +PY_MAJOR = sys.version[:3] +EGG_DIST = 3 +BINARY_DIST = 2 +SOURCE_DIST = 1 +CHECKOUT_DIST = 0 +DEVELOP_DIST = -1 + + +def register_loader_type(loader_type, provider_factory): + """Register `provider_factory` to make providers for `loader_type` + + `loader_type` is the type or class of a PEP 302 ``module.__loader__``, + and `provider_factory` is a function that, passed a *module* object, + returns an ``IResourceProvider`` for that module. + """ + _provider_factories[loader_type] = provider_factory + + +def get_provider(moduleOrReq): + """Return an IResourceProvider for the named module or requirement""" + if isinstance(moduleOrReq, Requirement): + return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] + try: + module = sys.modules[moduleOrReq] + except KeyError: + __import__(moduleOrReq) + module = sys.modules[moduleOrReq] + loader = getattr(module, '__loader__', None) + return _find_adapter(_provider_factories, loader)(module) + + +def _macosx_vers(_cache=[]): + if not _cache: + version = platform.mac_ver()[0] + # fallback for MacPorts + if version == '': + plist = '/System/Library/CoreServices/SystemVersion.plist' + if os.path.exists(plist): + if hasattr(plistlib, 'readPlist'): + plist_content = plistlib.readPlist(plist) + if 'ProductVersion' in plist_content: + version = plist_content['ProductVersion'] + + _cache.append(version.split('.')) + return _cache[0] + + +def _macosx_arch(machine): + return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) + + +def get_build_platform(): + """Return this platform's string for platform-specific distributions + + XXX Currently this is the same as ``distutils.util.get_platform()``, but it + needs some hacks for Linux and Mac OS X. + """ + from sysconfig import get_platform + + plat = get_platform() + if sys.platform == "darwin" and not plat.startswith('macosx-'): + try: + version = _macosx_vers() + machine = os.uname()[4].replace(" ", "_") + return "macosx-%d.%d-%s" % ( + int(version[0]), int(version[1]), + _macosx_arch(machine), + ) + except ValueError: + # if someone is running a non-Mac darwin system, this will fall + # through to the default implementation + pass + return plat + + +macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") +darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") +# XXX backward compat +get_platform = get_build_platform + + +def compatible_platforms(provided, required): + """Can code for the `provided` platform run on the `required` platform? + + Returns true if either platform is ``None``, or the platforms are equal. + + XXX Needs compatibility checks for Linux and other unixy OSes. + """ + if provided is None or required is None or provided == required: + # easy case + return True + + # Mac OS X special cases + reqMac = macosVersionString.match(required) + if reqMac: + provMac = macosVersionString.match(provided) + + # is this a Mac package? + if not provMac: + # this is backwards compatibility for packages built before + # setuptools 0.6. All packages built after this point will + # use the new macosx designation. + provDarwin = darwinVersionString.match(provided) + if provDarwin: + dversion = int(provDarwin.group(1)) + macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) + if dversion == 7 and macosversion >= "10.3" or \ + dversion == 8 and macosversion >= "10.4": + return True + # egg isn't macosx or legacy darwin + return False + + # are they the same major version and machine type? + if provMac.group(1) != reqMac.group(1) or \ + provMac.group(3) != reqMac.group(3): + return False + + # is the required OS major update >= the provided one? + if int(provMac.group(2)) > int(reqMac.group(2)): + return False + + return True + + # XXX Linux and other platforms' special cases should go here + return False + + +def run_script(dist_spec, script_name): + """Locate distribution `dist_spec` and run its `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + require(dist_spec)[0].run_script(script_name, ns) + + +# backward compatibility +run_main = run_script + + +def get_distribution(dist): + """Return a current distribution object for a Requirement or string""" + if isinstance(dist, six.string_types): + dist = Requirement.parse(dist) + if isinstance(dist, Requirement): + dist = get_provider(dist) + if not isinstance(dist, Distribution): + raise TypeError("Expected string, Requirement, or Distribution", dist) + return dist + + +def load_entry_point(dist, group, name): + """Return `name` entry point of `group` for `dist` or raise ImportError""" + return get_distribution(dist).load_entry_point(group, name) + + +def get_entry_map(dist, group=None): + """Return the entry point map for `group`, or the full entry map""" + return get_distribution(dist).get_entry_map(group) + + +def get_entry_info(dist, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return get_distribution(dist).get_entry_info(group, name) + + +class IMetadataProvider: + def has_metadata(name): + """Does the package's distribution contain the named metadata?""" + + def get_metadata(name): + """The named metadata resource as a string""" + + def get_metadata_lines(name): + """Yield named metadata resource as list of non-blank non-comment lines + + Leading and trailing whitespace is stripped from each line, and lines + with ``#`` as the first non-blank character are omitted.""" + + def metadata_isdir(name): + """Is the named metadata a directory? (like ``os.path.isdir()``)""" + + def metadata_listdir(name): + """List of metadata names in the directory (like ``os.listdir()``)""" + + def run_script(script_name, namespace): + """Execute the named script in the supplied namespace dictionary""" + + +class IResourceProvider(IMetadataProvider): + """An object that provides access to package resources""" + + def get_resource_filename(manager, resource_name): + """Return a true filesystem path for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_stream(manager, resource_name): + """Return a readable file-like object for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_string(manager, resource_name): + """Return a string containing the contents of `resource_name` + + `manager` must be an ``IResourceManager``""" + + def has_resource(resource_name): + """Does the package contain the named resource?""" + + def resource_isdir(resource_name): + """Is the named resource a directory? (like ``os.path.isdir()``)""" + + def resource_listdir(resource_name): + """List of resource names in the directory (like ``os.listdir()``)""" + + +class WorkingSet: + """A collection of active distributions on sys.path (or a similar list)""" + + def __init__(self, entries=None): + """Create working set from list of path entries (default=sys.path)""" + self.entries = [] + self.entry_keys = {} + self.by_key = {} + self.callbacks = [] + + if entries is None: + entries = sys.path + + for entry in entries: + self.add_entry(entry) + + @classmethod + def _build_master(cls): + """ + Prepare the master working set. + """ + ws = cls() + try: + from __main__ import __requires__ + except ImportError: + # The main program does not list any requirements + return ws + + # ensure the requirements are met + try: + ws.require(__requires__) + except VersionConflict: + return cls._build_from_requirements(__requires__) + + return ws + + @classmethod + def _build_from_requirements(cls, req_spec): + """ + Build a working set from a requirement spec. Rewrites sys.path. + """ + # try it without defaults already on sys.path + # by starting with an empty path + ws = cls([]) + reqs = parse_requirements(req_spec) + dists = ws.resolve(reqs, Environment()) + for dist in dists: + ws.add(dist) + + # add any missing entries from sys.path + for entry in sys.path: + if entry not in ws.entries: + ws.add_entry(entry) + + # then copy back to sys.path + sys.path[:] = ws.entries + return ws + + def add_entry(self, entry): + """Add a path item to ``.entries``, finding any distributions on it + + ``find_distributions(entry, True)`` is used to find distributions + corresponding to the path entry, and they are added. `entry` is + always appended to ``.entries``, even if it is already present. + (This is because ``sys.path`` can contain the same value more than + once, and the ``.entries`` of the ``sys.path`` WorkingSet should always + equal ``sys.path``.) + """ + self.entry_keys.setdefault(entry, []) + self.entries.append(entry) + for dist in find_distributions(entry, True): + self.add(dist, entry, False) + + def __contains__(self, dist): + """True if `dist` is the active distribution for its project""" + return self.by_key.get(dist.key) == dist + + def find(self, req): + """Find a distribution matching requirement `req` + + If there is an active distribution for the requested project, this + returns it as long as it meets the version requirement specified by + `req`. But, if there is an active distribution for the project and it + does *not* meet the `req` requirement, ``VersionConflict`` is raised. + If there is no active distribution for the requested project, ``None`` + is returned. + """ + dist = self.by_key.get(req.key) + if dist is not None and dist not in req: + # XXX add more info + raise VersionConflict(dist, req) + return dist + + def iter_entry_points(self, group, name=None): + """Yield entry point objects from `group` matching `name` + + If `name` is None, yields all entry points in `group` from all + distributions in the working set, otherwise only ones matching + both `group` and `name` are yielded (in distribution order). + """ + return ( + entry + for dist in self + for entry in dist.get_entry_map(group).values() + if name is None or name == entry.name + ) + + def run_script(self, requires, script_name): + """Locate distribution for `requires` and run `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + self.require(requires)[0].run_script(script_name, ns) + + def __iter__(self): + """Yield distributions for non-duplicate projects in the working set + + The yield order is the order in which the items' path entries were + added to the working set. + """ + seen = {} + for item in self.entries: + if item not in self.entry_keys: + # workaround a cache issue + continue + + for key in self.entry_keys[item]: + if key not in seen: + seen[key] = 1 + yield self.by_key[key] + + def add(self, dist, entry=None, insert=True, replace=False): + """Add `dist` to working set, associated with `entry` + + If `entry` is unspecified, it defaults to the ``.location`` of `dist`. + On exit from this routine, `entry` is added to the end of the working + set's ``.entries`` (if it wasn't already present). + + `dist` is only added to the working set if it's for a project that + doesn't already have a distribution in the set, unless `replace=True`. + If it's added, any callbacks registered with the ``subscribe()`` method + will be called. + """ + if insert: + dist.insert_on(self.entries, entry, replace=replace) + + if entry is None: + entry = dist.location + keys = self.entry_keys.setdefault(entry, []) + keys2 = self.entry_keys.setdefault(dist.location, []) + if not replace and dist.key in self.by_key: + # ignore hidden distros + return + + self.by_key[dist.key] = dist + if dist.key not in keys: + keys.append(dist.key) + if dist.key not in keys2: + keys2.append(dist.key) + self._added_new(dist) + + def resolve(self, requirements, env=None, installer=None, + replace_conflicting=False, extras=None): + """List all distributions needed to (recursively) meet `requirements` + + `requirements` must be a sequence of ``Requirement`` objects. `env`, + if supplied, should be an ``Environment`` instance. If + not supplied, it defaults to all distributions available within any + entry or distribution in the working set. `installer`, if supplied, + will be invoked with each requirement that cannot be met by an + already-installed distribution; it should return a ``Distribution`` or + ``None``. + + Unless `replace_conflicting=True`, raises a VersionConflict exception + if + any requirements are found on the path that have the correct name but + the wrong version. Otherwise, if an `installer` is supplied it will be + invoked to obtain the correct version of the requirement and activate + it. + + `extras` is a list of the extras to be used with these requirements. + This is important because extra requirements may look like `my_req; + extra = "my_extra"`, which would otherwise be interpreted as a purely + optional requirement. Instead, we want to be able to assert that these + requirements are truly required. + """ + + # set up the stack + requirements = list(requirements)[::-1] + # set of processed requirements + processed = {} + # key -> dist + best = {} + to_activate = [] + + req_extras = _ReqExtras() + + # Mapping of requirement to set of distributions that required it; + # useful for reporting info about conflicts. + required_by = collections.defaultdict(set) + + while requirements: + # process dependencies breadth-first + req = requirements.pop(0) + if req in processed: + # Ignore cyclic or redundant dependencies + continue + + if not req_extras.markers_pass(req, extras): + continue + + dist = best.get(req.key) + if dist is None: + # Find the best distribution and add it to the map + dist = self.by_key.get(req.key) + if dist is None or (dist not in req and replace_conflicting): + ws = self + if env is None: + if dist is None: + env = Environment(self.entries) + else: + # Use an empty environment and workingset to avoid + # any further conflicts with the conflicting + # distribution + env = Environment([]) + ws = WorkingSet([]) + dist = best[req.key] = env.best_match( + req, ws, installer, + replace_conflicting=replace_conflicting + ) + if dist is None: + requirers = required_by.get(req, None) + raise DistributionNotFound(req, requirers) + to_activate.append(dist) + if dist not in req: + # Oops, the "best" so far conflicts with a dependency + dependent_req = required_by[req] + raise VersionConflict(dist, req).with_context(dependent_req) + + # push the new requirements onto the stack + new_requirements = dist.requires(req.extras)[::-1] + requirements.extend(new_requirements) + + # Register the new requirements needed by req + for new_requirement in new_requirements: + required_by[new_requirement].add(req.project_name) + req_extras[new_requirement] = req.extras + + processed[req] = True + + # return list of distros to activate + return to_activate + + def find_plugins( + self, plugin_env, full_env=None, installer=None, fallback=True): + """Find all activatable distributions in `plugin_env` + + Example usage:: + + distributions, errors = working_set.find_plugins( + Environment(plugin_dirlist) + ) + # add plugins+libs to sys.path + map(working_set.add, distributions) + # display errors + print('Could not load', errors) + + The `plugin_env` should be an ``Environment`` instance that contains + only distributions that are in the project's "plugin directory" or + directories. The `full_env`, if supplied, should be an ``Environment`` + contains all currently-available distributions. If `full_env` is not + supplied, one is created automatically from the ``WorkingSet`` this + method is called on, which will typically mean that every directory on + ``sys.path`` will be scanned for distributions. + + `installer` is a standard installer callback as used by the + ``resolve()`` method. The `fallback` flag indicates whether we should + attempt to resolve older versions of a plugin if the newest version + cannot be resolved. + + This method returns a 2-tuple: (`distributions`, `error_info`), where + `distributions` is a list of the distributions found in `plugin_env` + that were loadable, along with any other distributions that are needed + to resolve their dependencies. `error_info` is a dictionary mapping + unloadable plugin distributions to an exception instance describing the + error that occurred. Usually this will be a ``DistributionNotFound`` or + ``VersionConflict`` instance. + """ + + plugin_projects = list(plugin_env) + # scan project names in alphabetic order + plugin_projects.sort() + + error_info = {} + distributions = {} + + if full_env is None: + env = Environment(self.entries) + env += plugin_env + else: + env = full_env + plugin_env + + shadow_set = self.__class__([]) + # put all our entries in shadow_set + list(map(shadow_set.add, self)) + + for project_name in plugin_projects: + + for dist in plugin_env[project_name]: + + req = [dist.as_requirement()] + + try: + resolvees = shadow_set.resolve(req, env, installer) + + except ResolutionError as v: + # save error info + error_info[dist] = v + if fallback: + # try the next older version of project + continue + else: + # give up on this project, keep going + break + + else: + list(map(shadow_set.add, resolvees)) + distributions.update(dict.fromkeys(resolvees)) + + # success, no need to try any more versions of this project + break + + distributions = list(distributions) + distributions.sort() + + return distributions, error_info + + def require(self, *requirements): + """Ensure that distributions matching `requirements` are activated + + `requirements` must be a string or a (possibly-nested) sequence + thereof, specifying the distributions and versions required. The + return value is a sequence of the distributions that needed to be + activated to fulfill the requirements; all relevant distributions are + included, even if they were already activated in this working set. + """ + needed = self.resolve(parse_requirements(requirements)) + + for dist in needed: + self.add(dist) + + return needed + + def subscribe(self, callback, existing=True): + """Invoke `callback` for all distributions + + If `existing=True` (default), + call on all existing ones, as well. + """ + if callback in self.callbacks: + return + self.callbacks.append(callback) + if not existing: + return + for dist in self: + callback(dist) + + def _added_new(self, dist): + for callback in self.callbacks: + callback(dist) + + def __getstate__(self): + return ( + self.entries[:], self.entry_keys.copy(), self.by_key.copy(), + self.callbacks[:] + ) + + def __setstate__(self, e_k_b_c): + entries, keys, by_key, callbacks = e_k_b_c + self.entries = entries[:] + self.entry_keys = keys.copy() + self.by_key = by_key.copy() + self.callbacks = callbacks[:] + + +class _ReqExtras(dict): + """ + Map each requirement to the extras that demanded it. + """ + + def markers_pass(self, req, extras=None): + """ + Evaluate markers for req against each extra that + demanded it. + + Return False if the req has a marker and fails + evaluation. Otherwise, return True. + """ + extra_evals = ( + req.marker.evaluate({'extra': extra}) + for extra in self.get(req, ()) + (extras or (None,)) + ) + return not req.marker or any(extra_evals) + + +class Environment: + """Searchable snapshot of distributions on a search path""" + + def __init__( + self, search_path=None, platform=get_supported_platform(), + python=PY_MAJOR): + """Snapshot distributions available on a search path + + Any distributions found on `search_path` are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. + + `platform` is an optional string specifying the name of the platform + that platform-specific distributions must be compatible with. If + unspecified, it defaults to the current platform. `python` is an + optional string naming the desired version of Python (e.g. ``'3.6'``); + it defaults to the current version. + + You may explicitly set `platform` (and/or `python`) to ``None`` if you + wish to map *all* distributions, not just those compatible with the + running platform or Python version. + """ + self._distmap = {} + self.platform = platform + self.python = python + self.scan(search_path) + + def can_add(self, dist): + """Is distribution `dist` acceptable for this environment? + + The distribution must match the platform and python version + requirements specified when this environment was created, or False + is returned. + """ + py_compat = ( + self.python is None + or dist.py_version is None + or dist.py_version == self.python + ) + return py_compat and compatible_platforms(dist.platform, self.platform) + + def remove(self, dist): + """Remove `dist` from the environment""" + self._distmap[dist.key].remove(dist) + + def scan(self, search_path=None): + """Scan `search_path` for distributions usable in this environment + + Any distributions found are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. Only distributions conforming to + the platform/python version defined at initialization are added. + """ + if search_path is None: + search_path = sys.path + + for item in search_path: + for dist in find_distributions(item): + self.add(dist) + + def __getitem__(self, project_name): + """Return a newest-to-oldest list of distributions for `project_name` + + Uses case-insensitive `project_name` comparison, assuming all the + project's distributions use their project's name converted to all + lowercase as their key. + + """ + distribution_key = project_name.lower() + return self._distmap.get(distribution_key, []) + + def add(self, dist): + """Add `dist` if we ``can_add()`` it and it has not already been added + """ + if self.can_add(dist) and dist.has_version(): + dists = self._distmap.setdefault(dist.key, []) + if dist not in dists: + dists.append(dist) + dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) + + def best_match( + self, req, working_set, installer=None, replace_conflicting=False): + """Find distribution best matching `req` and usable on `working_set` + + This calls the ``find(req)`` method of the `working_set` to see if a + suitable distribution is already active. (This may raise + ``VersionConflict`` if an unsuitable version of the project is already + active in the specified `working_set`.) If a suitable distribution + isn't active, this method returns the newest distribution in the + environment that meets the ``Requirement`` in `req`. If no suitable + distribution is found, and `installer` is supplied, then the result of + calling the environment's ``obtain(req, installer)`` method will be + returned. + """ + try: + dist = working_set.find(req) + except VersionConflict: + if not replace_conflicting: + raise + dist = None + if dist is not None: + return dist + for dist in self[req.key]: + if dist in req: + return dist + # try to download/install + return self.obtain(req, installer) + + def obtain(self, requirement, installer=None): + """Obtain a distribution matching `requirement` (e.g. via download) + + Obtain a distro that matches requirement (e.g. via download). In the + base ``Environment`` class, this routine just returns + ``installer(requirement)``, unless `installer` is None, in which case + None is returned instead. This method is a hook that allows subclasses + to attempt other ways of obtaining a distribution before falling back + to the `installer` argument.""" + if installer is not None: + return installer(requirement) + + def __iter__(self): + """Yield the unique project names of the available distributions""" + for key in self._distmap.keys(): + if self[key]: + yield key + + def __iadd__(self, other): + """In-place addition of a distribution or environment""" + if isinstance(other, Distribution): + self.add(other) + elif isinstance(other, Environment): + for project in other: + for dist in other[project]: + self.add(dist) + else: + raise TypeError("Can't add %r to environment" % (other,)) + return self + + def __add__(self, other): + """Add an environment or distribution to an environment""" + new = self.__class__([], platform=None, python=None) + for env in self, other: + new += env + return new + + +# XXX backward compatibility +AvailableDistributions = Environment + + +class ExtractionError(RuntimeError): + """An error occurred extracting a resource + + The following attributes are available from instances of this exception: + + manager + The resource manager that raised this exception + + cache_path + The base directory for resource extraction + + original_error + The exception instance that caused extraction to fail + """ + + +class ResourceManager: + """Manage resource extraction and packages""" + extraction_path = None + + def __init__(self): + self.cached_files = {} + + def resource_exists(self, package_or_requirement, resource_name): + """Does the named resource exist?""" + return get_provider(package_or_requirement).has_resource(resource_name) + + def resource_isdir(self, package_or_requirement, resource_name): + """Is the named resource an existing directory?""" + return get_provider(package_or_requirement).resource_isdir( + resource_name + ) + + def resource_filename(self, package_or_requirement, resource_name): + """Return a true filesystem path for specified resource""" + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name + ) + + def resource_stream(self, package_or_requirement, resource_name): + """Return a readable file-like object for specified resource""" + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name + ) + + def resource_string(self, package_or_requirement, resource_name): + """Return specified resource as a string""" + return get_provider(package_or_requirement).get_resource_string( + self, resource_name + ) + + def resource_listdir(self, package_or_requirement, resource_name): + """List the contents of the named resource directory""" + return get_provider(package_or_requirement).resource_listdir( + resource_name + ) + + def extraction_error(self): + """Give an error message for problems extracting file(s)""" + + old_exc = sys.exc_info()[1] + cache_path = self.extraction_path or get_default_cache() + + tmpl = textwrap.dedent(""" + Can't extract file(s) to egg cache + + The following error occurred while trying to extract file(s) + to the Python egg cache: + + {old_exc} + + The Python egg cache directory is currently set to: + + {cache_path} + + Perhaps your account does not have write access to this directory? + You can change the cache directory by setting the PYTHON_EGG_CACHE + environment variable to point to an accessible directory. + """).lstrip() + err = ExtractionError(tmpl.format(**locals())) + err.manager = self + err.cache_path = cache_path + err.original_error = old_exc + raise err + + def get_cache_path(self, archive_name, names=()): + """Return absolute location in cache for `archive_name` and `names` + + The parent directory of the resulting path will be created if it does + not already exist. `archive_name` should be the base filename of the + enclosing egg (which may not be the name of the enclosing zipfile!), + including its ".egg" extension. `names`, if provided, should be a + sequence of path name parts "under" the egg's extraction location. + + This method should only be called by resource providers that need to + obtain an extraction location, and only for names they intend to + extract, as it tracks the generated names for possible cleanup later. + """ + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name + '-tmp', *names) + try: + _bypass_ensure_directory(target_path) + except Exception: + self.extraction_error() + + self._warn_unsafe_extraction_path(extract_path) + + self.cached_files[target_path] = 1 + return target_path + + @staticmethod + def _warn_unsafe_extraction_path(path): + """ + If the default extraction path is overridden and set to an insecure + location, such as /tmp, it opens up an opportunity for an attacker to + replace an extracted file with an unauthorized payload. Warn the user + if a known insecure location is used. + + See Distribute #375 for more details. + """ + if os.name == 'nt' and not path.startswith(os.environ['windir']): + # On Windows, permissions are generally restrictive by default + # and temp directories are not writable by other users, so + # bypass the warning. + return + mode = os.stat(path).st_mode + if mode & stat.S_IWOTH or mode & stat.S_IWGRP: + msg = ( + "%s is writable by group/others and vulnerable to attack " + "when " + "used with get_resource_filename. Consider a more secure " + "location (set with .set_extraction_path or the " + "PYTHON_EGG_CACHE environment variable)." % path + ) + warnings.warn(msg, UserWarning) + + def postprocess(self, tempname, filename): + """Perform any platform-specific postprocessing of `tempname` + + This is where Mac header rewrites should be done; other platforms don't + have anything special they should do. + + Resource providers should call this method ONLY after successfully + extracting a compressed resource. They must NOT call it on resources + that are already in the filesystem. + + `tempname` is the current (temporary) name of the file, and `filename` + is the name it will be renamed to by the caller after this routine + returns. + """ + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 + os.chmod(tempname, mode) + + def set_extraction_path(self, path): + """Set the base path where resources will be extracted to, if needed. + + If you do not call this routine before any extractions take place, the + path defaults to the return value of ``get_default_cache()``. (Which + is based on the ``PYTHON_EGG_CACHE`` environment variable, with various + platform-specific fallbacks. See that routine's documentation for more + details.) + + Resources are extracted to subdirectories of this path based upon + information given by the ``IResourceProvider``. You may set this to a + temporary directory, but then you must call ``cleanup_resources()`` to + delete the extracted files when done. There is no guarantee that + ``cleanup_resources()`` will be able to remove all extracted files. + + (Note: you may not change the extraction path for a given resource + manager once resources have been extracted, unless you first call + ``cleanup_resources()``.) + """ + if self.cached_files: + raise ValueError( + "Can't change extraction path, files already extracted" + ) + + self.extraction_path = path + + def cleanup_resources(self, force=False): + """ + Delete all extracted resource files and directories, returning a list + of the file and directory names that could not be successfully removed. + This function does not have any concurrency protection, so it should + generally only be called when the extraction path is a temporary + directory exclusive to a single process. This method is not + automatically called; you must call it explicitly or register it as an + ``atexit`` function if you wish to ensure cleanup of a temporary + directory used for extractions. + """ + # XXX + + +def get_default_cache(): + """ + Return the ``PYTHON_EGG_CACHE`` environment variable + or a platform-relevant user cache dir for an app + named "Python-Eggs". + """ + return ( + os.environ.get('PYTHON_EGG_CACHE') + or appdirs.user_cache_dir(appname='Python-Eggs') + ) + + +def safe_name(name): + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + +def safe_version(version): + """ + Convert an arbitrary string to a standard version string + """ + try: + # normalize the version + return str(packaging.version.Version(version)) + except packaging.version.InvalidVersion: + version = version.replace(' ', '.') + return re.sub('[^A-Za-z0-9.]+', '-', version) + + +def safe_extra(extra): + """Convert an arbitrary string to a standard 'extra' name + + Any runs of non-alphanumeric characters are replaced with a single '_', + and the result is always lowercased. + """ + return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() + + +def to_filename(name): + """Convert a project or version name to its filename-escaped form + + Any '-' characters are currently replaced with '_'. + """ + return name.replace('-', '_') + + +def invalid_marker(text): + """ + Validate text as a PEP 508 environment marker; return an exception + if invalid or False otherwise. + """ + try: + evaluate_marker(text) + except SyntaxError as e: + e.filename = None + e.lineno = None + return e + return False + + +def evaluate_marker(text, extra=None): + """ + Evaluate a PEP 508 environment marker. + Return a boolean indicating the marker result in this environment. + Raise SyntaxError if marker is invalid. + + This implementation uses the 'pyparsing' module. + """ + try: + marker = packaging.markers.Marker(text) + return marker.evaluate() + except packaging.markers.InvalidMarker as e: + raise SyntaxError(e) + + +class NullProvider: + """Try to implement resources and metadata for arbitrary PEP 302 loaders""" + + egg_name = None + egg_info = None + loader = None + + def __init__(self, module): + self.loader = getattr(module, '__loader__', None) + self.module_path = os.path.dirname(getattr(module, '__file__', '')) + + def get_resource_filename(self, manager, resource_name): + return self._fn(self.module_path, resource_name) + + def get_resource_stream(self, manager, resource_name): + return io.BytesIO(self.get_resource_string(manager, resource_name)) + + def get_resource_string(self, manager, resource_name): + return self._get(self._fn(self.module_path, resource_name)) + + def has_resource(self, resource_name): + return self._has(self._fn(self.module_path, resource_name)) + + def has_metadata(self, name): + return self.egg_info and self._has(self._fn(self.egg_info, name)) + + def get_metadata(self, name): + if not self.egg_info: + return "" + value = self._get(self._fn(self.egg_info, name)) + return value.decode('utf-8') if six.PY3 else value + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + def resource_isdir(self, resource_name): + return self._isdir(self._fn(self.module_path, resource_name)) + + def metadata_isdir(self, name): + return self.egg_info and self._isdir(self._fn(self.egg_info, name)) + + def resource_listdir(self, resource_name): + return self._listdir(self._fn(self.module_path, resource_name)) + + def metadata_listdir(self, name): + if self.egg_info: + return self._listdir(self._fn(self.egg_info, name)) + return [] + + def run_script(self, script_name, namespace): + script = 'scripts/' + script_name + if not self.has_metadata(script): + raise ResolutionError( + "Script {script!r} not found in metadata at {self.egg_info!r}" + .format(**locals()), + ) + script_text = self.get_metadata(script).replace('\r\n', '\n') + script_text = script_text.replace('\r', '\n') + script_filename = self._fn(self.egg_info, script) + namespace['__file__'] = script_filename + if os.path.exists(script_filename): + source = open(script_filename).read() + code = compile(source, script_filename, 'exec') + exec(code, namespace, namespace) + else: + from linecache import cache + cache[script_filename] = ( + len(script_text), 0, script_text.split('\n'), script_filename + ) + script_code = compile(script_text, script_filename, 'exec') + exec(script_code, namespace, namespace) + + def _has(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _isdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _listdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _fn(self, base, resource_name): + if resource_name: + return os.path.join(base, *resource_name.split('/')) + return base + + def _get(self, path): + if hasattr(self.loader, 'get_data'): + return self.loader.get_data(path) + raise NotImplementedError( + "Can't perform this operation for loaders without 'get_data()'" + ) + + +register_loader_type(object, NullProvider) + + +class EggProvider(NullProvider): + """Provider based on a virtual filesystem""" + + def __init__(self, module): + NullProvider.__init__(self, module) + self._setup_prefix() + + def _setup_prefix(self): + # we assume here that our metadata may be nested inside a "basket" + # of multiple eggs; that's why we use module_path instead of .archive + path = self.module_path + old = None + while path != old: + if _is_egg_path(path): + self.egg_name = os.path.basename(path) + self.egg_info = os.path.join(path, 'EGG-INFO') + self.egg_root = path + break + old = path + path, base = os.path.split(path) + + +class DefaultProvider(EggProvider): + """Provides access to package resources in the filesystem""" + + def _has(self, path): + return os.path.exists(path) + + def _isdir(self, path): + return os.path.isdir(path) + + def _listdir(self, path): + return os.listdir(path) + + def get_resource_stream(self, manager, resource_name): + return open(self._fn(self.module_path, resource_name), 'rb') + + def _get(self, path): + with open(path, 'rb') as stream: + return stream.read() + + @classmethod + def _register(cls): + loader_names = 'SourceFileLoader', 'SourcelessFileLoader', + for name in loader_names: + loader_cls = getattr(importlib_machinery, name, type(None)) + register_loader_type(loader_cls, cls) + + +DefaultProvider._register() + + +class EmptyProvider(NullProvider): + """Provider that returns nothing for all requests""" + + module_path = None + + _isdir = _has = lambda self, path: False + + def _get(self, path): + return '' + + def _listdir(self, path): + return [] + + def __init__(self): + pass + + +empty_provider = EmptyProvider() + + +class ZipManifests(dict): + """ + zip manifest builder + """ + + @classmethod + def build(cls, path): + """ + Build a dictionary similar to the zipimport directory + caches, except instead of tuples, store ZipInfo objects. + + Use a platform-specific path separator (os.sep) for the path keys + for compatibility with pypy on Windows. + """ + with zipfile.ZipFile(path) as zfile: + items = ( + ( + name.replace('/', os.sep), + zfile.getinfo(name), + ) + for name in zfile.namelist() + ) + return dict(items) + + load = build + + +class MemoizedZipManifests(ZipManifests): + """ + Memoized zipfile manifests. + """ + manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') + + def load(self, path): + """ + Load a manifest at path or return a suitable manifest already loaded. + """ + path = os.path.normpath(path) + mtime = os.stat(path).st_mtime + + if path not in self or self[path].mtime != mtime: + manifest = self.build(path) + self[path] = self.manifest_mod(manifest, mtime) + + return self[path].manifest + + +class ZipProvider(EggProvider): + """Resource support for zips and eggs""" + + eagers = None + _zip_manifests = MemoizedZipManifests() + + def __init__(self, module): + EggProvider.__init__(self, module) + self.zip_pre = self.loader.archive + os.sep + + def _zipinfo_name(self, fspath): + # Convert a virtual filename (full path to file) into a zipfile subpath + # usable with the zipimport directory cache for our target archive + fspath = fspath.rstrip(os.sep) + if fspath == self.loader.archive: + return '' + if fspath.startswith(self.zip_pre): + return fspath[len(self.zip_pre):] + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.zip_pre) + ) + + def _parts(self, zip_path): + # Convert a zipfile subpath into an egg-relative path part list. + # pseudo-fs path + fspath = self.zip_pre + zip_path + if fspath.startswith(self.egg_root + os.sep): + return fspath[len(self.egg_root) + 1:].split(os.sep) + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.egg_root) + ) + + @property + def zipinfo(self): + return self._zip_manifests.load(self.loader.archive) + + def get_resource_filename(self, manager, resource_name): + if not self.egg_name: + raise NotImplementedError( + "resource_filename() only supported for .egg, not .zip" + ) + # no need to lock for extraction, since we use temp names + zip_path = self._resource_to_zip(resource_name) + eagers = self._get_eager_resources() + if '/'.join(self._parts(zip_path)) in eagers: + for name in eagers: + self._extract_resource(manager, self._eager_to_zip(name)) + return self._extract_resource(manager, zip_path) + + @staticmethod + def _get_date_and_size(zip_stat): + size = zip_stat.file_size + # ymdhms+wday, yday, dst + date_time = zip_stat.date_time + (0, 0, -1) + # 1980 offset already done + timestamp = time.mktime(date_time) + return timestamp, size + + def _extract_resource(self, manager, zip_path): + + if zip_path in self._index(): + for name in self._index()[zip_path]: + last = self._extract_resource( + manager, os.path.join(zip_path, name) + ) + # return the extracted directory name + return os.path.dirname(last) + + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + + if not WRITE_SUPPORT: + raise IOError('"os.rename" and "os.unlink" are not supported ' + 'on this platform') + try: + + real_path = manager.get_cache_path( + self.egg_name, self._parts(zip_path) + ) + + if self._is_current(real_path, zip_path): + return real_path + + outf, tmpnam = _mkstemp( + ".$extract", + dir=os.path.dirname(real_path), + ) + os.write(outf, self.loader.get_data(zip_path)) + os.close(outf) + utime(tmpnam, (timestamp, timestamp)) + manager.postprocess(tmpnam, real_path) + + try: + rename(tmpnam, real_path) + + except os.error: + if os.path.isfile(real_path): + if self._is_current(real_path, zip_path): + # the file became current since it was checked above, + # so proceed. + return real_path + # Windows, del old file and retry + elif os.name == 'nt': + unlink(real_path) + rename(tmpnam, real_path) + return real_path + raise + + except os.error: + # report a user-friendly error + manager.extraction_error() + + return real_path + + def _is_current(self, file_path, zip_path): + """ + Return True if the file_path is current for this zip_path + """ + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + if not os.path.isfile(file_path): + return False + stat = os.stat(file_path) + if stat.st_size != size or stat.st_mtime != timestamp: + return False + # check that the contents match + zip_contents = self.loader.get_data(zip_path) + with open(file_path, 'rb') as f: + file_contents = f.read() + return zip_contents == file_contents + + def _get_eager_resources(self): + if self.eagers is None: + eagers = [] + for name in ('native_libs.txt', 'eager_resources.txt'): + if self.has_metadata(name): + eagers.extend(self.get_metadata_lines(name)) + self.eagers = eagers + return self.eagers + + def _index(self): + try: + return self._dirindex + except AttributeError: + ind = {} + for path in self.zipinfo: + parts = path.split(os.sep) + while parts: + parent = os.sep.join(parts[:-1]) + if parent in ind: + ind[parent].append(parts[-1]) + break + else: + ind[parent] = [parts.pop()] + self._dirindex = ind + return ind + + def _has(self, fspath): + zip_path = self._zipinfo_name(fspath) + return zip_path in self.zipinfo or zip_path in self._index() + + def _isdir(self, fspath): + return self._zipinfo_name(fspath) in self._index() + + def _listdir(self, fspath): + return list(self._index().get(self._zipinfo_name(fspath), ())) + + def _eager_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.egg_root, resource_name)) + + def _resource_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.module_path, resource_name)) + + +register_loader_type(zipimport.zipimporter, ZipProvider) + + +class FileMetadata(EmptyProvider): + """Metadata handler for standalone PKG-INFO files + + Usage:: + + metadata = FileMetadata("/path/to/PKG-INFO") + + This provider rejects all data and metadata requests except for PKG-INFO, + which is treated as existing, and will be the contents of the file at + the provided location. + """ + + def __init__(self, path): + self.path = path + + def has_metadata(self, name): + return name == 'PKG-INFO' and os.path.isfile(self.path) + + def get_metadata(self, name): + if name != 'PKG-INFO': + raise KeyError("No metadata except PKG-INFO is available") + + with io.open(self.path, encoding='utf-8', errors="replace") as f: + metadata = f.read() + self._warn_on_replacement(metadata) + return metadata + + def _warn_on_replacement(self, metadata): + # Python 2.7 compat for: replacement_char = '�' + replacement_char = b'\xef\xbf\xbd'.decode('utf-8') + if replacement_char in metadata: + tmpl = "{self.path} could not be properly decoded in UTF-8" + msg = tmpl.format(**locals()) + warnings.warn(msg) + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + +class PathMetadata(DefaultProvider): + """Metadata provider for egg directories + + Usage:: + + # Development eggs: + + egg_info = "/path/to/PackageName.egg-info" + base_dir = os.path.dirname(egg_info) + metadata = PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + dist = Distribution(basedir, project_name=dist_name, metadata=metadata) + + # Unpacked egg directories: + + egg_path = "/path/to/PackageName-ver-pyver-etc.egg" + metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) + dist = Distribution.from_filename(egg_path, metadata=metadata) + """ + + def __init__(self, path, egg_info): + self.module_path = path + self.egg_info = egg_info + + +class EggMetadata(ZipProvider): + """Metadata provider for .egg files""" + + def __init__(self, importer): + """Create a metadata provider from a zipimporter""" + + self.zip_pre = importer.archive + os.sep + self.loader = importer + if importer.prefix: + self.module_path = os.path.join(importer.archive, importer.prefix) + else: + self.module_path = importer.archive + self._setup_prefix() + + +_declare_state('dict', _distribution_finders={}) + + +def register_finder(importer_type, distribution_finder): + """Register `distribution_finder` to find distributions in sys.path items + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `distribution_finder` is a callable that, passed a path + item and the importer instance, yields ``Distribution`` instances found on + that path item. See ``pkg_resources.find_on_path`` for an example.""" + _distribution_finders[importer_type] = distribution_finder + + +def find_distributions(path_item, only=False): + """Yield distributions accessible via `path_item`""" + importer = get_importer(path_item) + finder = _find_adapter(_distribution_finders, importer) + return finder(importer, path_item, only) + + +def find_eggs_in_zip(importer, path_item, only=False): + """ + Find eggs in zip files; possibly multiple nested eggs. + """ + if importer.archive.endswith('.whl'): + # wheels are not supported with this finder + # they don't have PKG-INFO metadata, and won't ever contain eggs + return + metadata = EggMetadata(importer) + if metadata.has_metadata('PKG-INFO'): + yield Distribution.from_filename(path_item, metadata=metadata) + if only: + # don't yield nested distros + return + for subitem in metadata.resource_listdir('/'): + if _is_egg_path(subitem): + subpath = os.path.join(path_item, subitem) + dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) + for dist in dists: + yield dist + elif subitem.lower().endswith('.dist-info'): + subpath = os.path.join(path_item, subitem) + submeta = EggMetadata(zipimport.zipimporter(subpath)) + submeta.egg_info = subpath + yield Distribution.from_location(path_item, subitem, submeta) + + +register_finder(zipimport.zipimporter, find_eggs_in_zip) + + +def find_nothing(importer, path_item, only=False): + return () + + +register_finder(object, find_nothing) + + +def _by_version_descending(names): + """ + Given a list of filenames, return them in descending order + by version number. + + >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' + >>> _by_version_descending(names) + ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] + """ + def _by_version(name): + """ + Parse each component of the filename + """ + name, ext = os.path.splitext(name) + parts = itertools.chain(name.split('-'), [ext]) + return [packaging.version.parse(part) for part in parts] + + return sorted(names, key=_by_version, reverse=True) + + +def find_on_path(importer, path_item, only=False): + """Yield distributions accessible on a sys.path directory""" + path_item = _normalize_cached(path_item) + + if _is_unpacked_egg(path_item): + yield Distribution.from_filename( + path_item, metadata=PathMetadata( + path_item, os.path.join(path_item, 'EGG-INFO') + ) + ) + return + + entries = safe_listdir(path_item) + + # for performance, before sorting by version, + # screen entries for only those that will yield + # distributions + filtered = ( + entry + for entry in entries + if dist_factory(path_item, entry, only) + ) + + # scan for .egg and .egg-info in directory + path_item_entries = _by_version_descending(filtered) + for entry in path_item_entries: + fullpath = os.path.join(path_item, entry) + factory = dist_factory(path_item, entry, only) + for dist in factory(fullpath): + yield dist + + +def dist_factory(path_item, entry, only): + """ + Return a dist_factory for a path_item and entry + """ + lower = entry.lower() + is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) + return ( + distributions_from_metadata + if is_meta else + find_distributions + if not only and _is_egg_path(entry) else + resolve_egg_link + if not only and lower.endswith('.egg-link') else + NoDists() + ) + + +class NoDists: + """ + >>> bool(NoDists()) + False + + >>> list(NoDists()('anything')) + [] + """ + def __bool__(self): + return False + if six.PY2: + __nonzero__ = __bool__ + + def __call__(self, fullpath): + return iter(()) + + +def safe_listdir(path): + """ + Attempt to list contents of path, but suppress some exceptions. + """ + try: + return os.listdir(path) + except (PermissionError, NotADirectoryError): + pass + except OSError as e: + # Ignore the directory if does not exist, not a directory or + # permission denied + ignorable = ( + e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) + # Python 2 on Windows needs to be handled this way :( + or getattr(e, "winerror", None) == 267 + ) + if not ignorable: + raise + return () + + +def distributions_from_metadata(path): + root = os.path.dirname(path) + if os.path.isdir(path): + if len(os.listdir(path)) == 0: + # empty metadata dir; skip + return + metadata = PathMetadata(root, path) + else: + metadata = FileMetadata(path) + entry = os.path.basename(path) + yield Distribution.from_location( + root, entry, metadata, precedence=DEVELOP_DIST, + ) + + +def non_empty_lines(path): + """ + Yield non-empty lines from file at path + """ + with open(path) as f: + for line in f: + line = line.strip() + if line: + yield line + + +def resolve_egg_link(path): + """ + Given a path to an .egg-link, resolve distributions + present in the referenced path. + """ + referenced_paths = non_empty_lines(path) + resolved_paths = ( + os.path.join(os.path.dirname(path), ref) + for ref in referenced_paths + ) + dist_groups = map(find_distributions, resolved_paths) + return next(dist_groups, ()) + + +register_finder(pkgutil.ImpImporter, find_on_path) + +if hasattr(importlib_machinery, 'FileFinder'): + register_finder(importlib_machinery.FileFinder, find_on_path) + +_declare_state('dict', _namespace_handlers={}) +_declare_state('dict', _namespace_packages={}) + + +def register_namespace_handler(importer_type, namespace_handler): + """Register `namespace_handler` to declare namespace packages + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `namespace_handler` is a callable like this:: + + def namespace_handler(importer, path_entry, moduleName, module): + # return a path_entry to use for child packages + + Namespace handlers are only called if the importer object has already + agreed that it can handle the relevant path item, and they should only + return a subpath if the module __path__ does not already contain an + equivalent subpath. For an example namespace handler, see + ``pkg_resources.file_ns_handler``. + """ + _namespace_handlers[importer_type] = namespace_handler + + +def _handle_ns(packageName, path_item): + """Ensure that named package includes a subpath of path_item (if needed)""" + + importer = get_importer(path_item) + if importer is None: + return None + + # capture warnings due to #1111 + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + loader = importer.find_module(packageName) + + if loader is None: + return None + module = sys.modules.get(packageName) + if module is None: + module = sys.modules[packageName] = types.ModuleType(packageName) + module.__path__ = [] + _set_parent_ns(packageName) + elif not hasattr(module, '__path__'): + raise TypeError("Not a package:", packageName) + handler = _find_adapter(_namespace_handlers, importer) + subpath = handler(importer, path_item, packageName, module) + if subpath is not None: + path = module.__path__ + path.append(subpath) + loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath + + +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path = [_normalize_cached(p) for p in sys.path] + + def safe_sys_path_index(entry): + """ + Workaround for #520 and #513. + """ + try: + return sys_path.index(entry) + except ValueError: + return float('inf') + + def position_in_sys_path(path): + """ + Return the ordinal of the path based on its position in sys.path + """ + path_parts = path.split(os.sep) + module_parts = package_name.count('.') + 1 + parts = path_parts[:-module_parts] + return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) + + new_path = sorted(orig_path, key=position_in_sys_path) + new_path = [_normalize_cached(p) for p in new_path] + + if isinstance(module.__path__, list): + module.__path__[:] = new_path + else: + module.__path__ = new_path + + +def declare_namespace(packageName): + """Declare that package 'packageName' is a namespace package""" + + _imp.acquire_lock() + try: + if packageName in _namespace_packages: + return + + path = sys.path + parent, _, _ = packageName.rpartition('.') + + if parent: + declare_namespace(parent) + if parent not in _namespace_packages: + __import__(parent) + try: + path = sys.modules[parent].__path__ + except AttributeError: + raise TypeError("Not a package:", parent) + + # Track what packages are namespaces, so when new path items are added, + # they can be updated + _namespace_packages.setdefault(parent or None, []).append(packageName) + _namespace_packages.setdefault(packageName, []) + + for path_item in path: + # Ensure all the parent's path items are reflected in the child, + # if they apply + _handle_ns(packageName, path_item) + + finally: + _imp.release_lock() + + +def fixup_namespace_packages(path_item, parent=None): + """Ensure that previously-declared namespace packages include path_item""" + _imp.acquire_lock() + try: + for package in _namespace_packages.get(parent, ()): + subpath = _handle_ns(package, path_item) + if subpath: + fixup_namespace_packages(subpath, package) + finally: + _imp.release_lock() + + +def file_ns_handler(importer, path_item, packageName, module): + """Compute an ns-package subpath for a filesystem or zipfile importer""" + + subpath = os.path.join(path_item, packageName.split('.')[-1]) + normalized = _normalize_cached(subpath) + for item in module.__path__: + if _normalize_cached(item) == normalized: + break + else: + # Only return the path if it's not already there + return subpath + + +register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) +register_namespace_handler(zipimport.zipimporter, file_ns_handler) + +if hasattr(importlib_machinery, 'FileFinder'): + register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) + + +def null_ns_handler(importer, path_item, packageName, module): + return None + + +register_namespace_handler(object, null_ns_handler) + + +def normalize_path(filename): + """Normalize a file/dir name for comparison purposes""" + return os.path.normcase(os.path.realpath(filename)) + + +def _normalize_cached(filename, _cache={}): + try: + return _cache[filename] + except KeyError: + _cache[filename] = result = normalize_path(filename) + return result + + +def _is_egg_path(path): + """ + Determine if given path appears to be an egg. + """ + return path.lower().endswith('.egg') + + +def _is_unpacked_egg(path): + """ + Determine if given path appears to be an unpacked egg. + """ + return ( + _is_egg_path(path) and + os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) + ) + + +def _set_parent_ns(packageName): + parts = packageName.split('.') + name = parts.pop() + if parts: + parent = '.'.join(parts) + setattr(sys.modules[parent], name, sys.modules[packageName]) + + +def yield_lines(strs): + """Yield non-empty/non-comment lines of a string or sequence""" + if isinstance(strs, six.string_types): + for s in strs.splitlines(): + s = s.strip() + # skip blank lines/comments + if s and not s.startswith('#'): + yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s + + +MODULE = re.compile(r"\w+(\.\w+)*$").match +EGG_NAME = re.compile( + r""" + (?P<name>[^-]+) ( + -(?P<ver>[^-]+) ( + -py(?P<pyver>[^-]+) ( + -(?P<plat>.+) + )? + )? + )? + """, + re.VERBOSE | re.IGNORECASE, +).match + + +class EntryPoint: + """Object representing an advertised importable object""" + + def __init__(self, name, module_name, attrs=(), extras=(), dist=None): + if not MODULE(module_name): + raise ValueError("Invalid module name", module_name) + self.name = name + self.module_name = module_name + self.attrs = tuple(attrs) + self.extras = tuple(extras) + self.dist = dist + + def __str__(self): + s = "%s = %s" % (self.name, self.module_name) + if self.attrs: + s += ':' + '.'.join(self.attrs) + if self.extras: + s += ' [%s]' % ','.join(self.extras) + return s + + def __repr__(self): + return "EntryPoint.parse(%r)" % str(self) + + def load(self, require=True, *args, **kwargs): + """ + Require packages for this EntryPoint, then resolve it. + """ + if not require or args or kwargs: + warnings.warn( + "Parameters to load are deprecated. Call .resolve and " + ".require separately.", + DeprecationWarning, + stacklevel=2, + ) + if require: + self.require(*args, **kwargs) + return self.resolve() + + def resolve(self): + """ + Resolve the entry point from its module and attrs. + """ + module = __import__(self.module_name, fromlist=['__name__'], level=0) + try: + return functools.reduce(getattr, self.attrs, module) + except AttributeError as exc: + raise ImportError(str(exc)) + + def require(self, env=None, installer=None): + if self.extras and not self.dist: + raise UnknownExtra("Can't require() without a distribution", self) + + # Get the requirements for this entry point with all its extras and + # then resolve them. We have to pass `extras` along when resolving so + # that the working set knows what extras we want. Otherwise, for + # dist-info distributions, the working set will assume that the + # requirements for that extra are purely optional and skip over them. + reqs = self.dist.requires(self.extras) + items = working_set.resolve(reqs, env, installer, extras=self.extras) + list(map(working_set.add, items)) + + pattern = re.compile( + r'\s*' + r'(?P<name>.+?)\s*' + r'=\s*' + r'(?P<module>[\w.]+)\s*' + r'(:\s*(?P<attr>[\w.]+))?\s*' + r'(?P<extras>\[.*\])?\s*$' + ) + + @classmethod + def parse(cls, src, dist=None): + """Parse a single entry point from string `src` + + Entry point syntax follows the form:: + + name = some.module:some.attr [extra1, extra2] + + The entry name and module name are required, but the ``:attrs`` and + ``[extras]`` parts are optional + """ + m = cls.pattern.match(src) + if not m: + msg = "EntryPoint must be in 'name=module:attrs [extras]' format" + raise ValueError(msg, src) + res = m.groupdict() + extras = cls._parse_extras(res['extras']) + attrs = res['attr'].split('.') if res['attr'] else () + return cls(res['name'], res['module'], attrs, extras, dist) + + @classmethod + def _parse_extras(cls, extras_spec): + if not extras_spec: + return () + req = Requirement.parse('x' + extras_spec) + if req.specs: + raise ValueError() + return req.extras + + @classmethod + def parse_group(cls, group, lines, dist=None): + """Parse an entry point group""" + if not MODULE(group): + raise ValueError("Invalid group name", group) + this = {} + for line in yield_lines(lines): + ep = cls.parse(line, dist) + if ep.name in this: + raise ValueError("Duplicate entry point", group, ep.name) + this[ep.name] = ep + return this + + @classmethod + def parse_map(cls, data, dist=None): + """Parse a map of entry point groups""" + if isinstance(data, dict): + data = data.items() + else: + data = split_sections(data) + maps = {} + for group, lines in data: + if group is None: + if not lines: + continue + raise ValueError("Entry points must be listed in groups") + group = group.strip() + if group in maps: + raise ValueError("Duplicate group name", group) + maps[group] = cls.parse_group(group, lines, dist) + return maps + + +def _remove_md5_fragment(location): + if not location: + return '' + parsed = urllib.parse.urlparse(location) + if parsed[-1].startswith('md5='): + return urllib.parse.urlunparse(parsed[:-1] + ('',)) + return location + + +def _version_from_file(lines): + """ + Given an iterable of lines from a Metadata file, return + the value of the Version field, if present, or None otherwise. + """ + def is_version_line(line): + return line.lower().startswith('version:') + version_lines = filter(is_version_line, lines) + line = next(iter(version_lines), '') + _, _, value = line.partition(':') + return safe_version(value.strip()) or None + + +class Distribution: + """Wrap an actual or potential sys.path entry w/metadata""" + PKG_INFO = 'PKG-INFO' + + def __init__( + self, location=None, metadata=None, project_name=None, + version=None, py_version=PY_MAJOR, platform=None, + precedence=EGG_DIST): + self.project_name = safe_name(project_name or 'Unknown') + if version is not None: + self._version = safe_version(version) + self.py_version = py_version + self.platform = platform + self.location = location + self.precedence = precedence + self._provider = metadata or empty_provider + + @classmethod + def from_location(cls, location, basename, metadata=None, **kw): + project_name, version, py_version, platform = [None] * 4 + basename, ext = os.path.splitext(basename) + if ext.lower() in _distributionImpl: + cls = _distributionImpl[ext.lower()] + + match = EGG_NAME(basename) + if match: + project_name, version, py_version, platform = match.group( + 'name', 'ver', 'pyver', 'plat' + ) + return cls( + location, metadata, project_name=project_name, version=version, + py_version=py_version, platform=platform, **kw + )._reload_version() + + def _reload_version(self): + return self + + @property + def hashcmp(self): + return ( + self.parsed_version, + self.precedence, + self.key, + _remove_md5_fragment(self.location), + self.py_version or '', + self.platform or '', + ) + + def __hash__(self): + return hash(self.hashcmp) + + def __lt__(self, other): + return self.hashcmp < other.hashcmp + + def __le__(self, other): + return self.hashcmp <= other.hashcmp + + def __gt__(self, other): + return self.hashcmp > other.hashcmp + + def __ge__(self, other): + return self.hashcmp >= other.hashcmp + + def __eq__(self, other): + if not isinstance(other, self.__class__): + # It's not a Distribution, so they are not equal + return False + return self.hashcmp == other.hashcmp + + def __ne__(self, other): + return not self == other + + # These properties have to be lazy so that we don't have to load any + # metadata until/unless it's actually needed. (i.e., some distributions + # may not know their name or version without loading PKG-INFO) + + @property + def key(self): + try: + return self._key + except AttributeError: + self._key = key = self.project_name.lower() + return key + + @property + def parsed_version(self): + if not hasattr(self, "_parsed_version"): + self._parsed_version = parse_version(self.version) + + return self._parsed_version + + def _warn_legacy_version(self): + LV = packaging.version.LegacyVersion + is_legacy = isinstance(self._parsed_version, LV) + if not is_legacy: + return + + # While an empty version is technically a legacy version and + # is not a valid PEP 440 version, it's also unlikely to + # actually come from someone and instead it is more likely that + # it comes from setuptools attempting to parse a filename and + # including it in the list. So for that we'll gate this warning + # on if the version is anything at all or not. + if not self.version: + return + + tmpl = textwrap.dedent(""" + '{project_name} ({version})' is being parsed as a legacy, + non PEP 440, + version. You may find odd behavior and sort order. + In particular it will be sorted as less than 0.0. It + is recommended to migrate to PEP 440 compatible + versions. + """).strip().replace('\n', ' ') + + warnings.warn(tmpl.format(**vars(self)), PEP440Warning) + + @property + def version(self): + try: + return self._version + except AttributeError: + version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if version is None: + tmpl = "Missing 'Version:' header and/or %s file" + raise ValueError(tmpl % self.PKG_INFO, self) + return version + + @property + def _dep_map(self): + """ + A map of extra to its list of (direct) requirements + for this distribution, including the null extra. + """ + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._filter_extras(self._build_dep_map()) + return self.__dep_map + + @staticmethod + def _filter_extras(dm): + """ + Given a mapping of extras to dependencies, strip off + environment markers and filter out any dependencies + not matching the markers. + """ + for extra in list(filter(None, dm)): + new_extra = extra + reqs = dm.pop(extra) + new_extra, _, marker = extra.partition(':') + fails_marker = marker and ( + invalid_marker(marker) + or not evaluate_marker(marker) + ) + if fails_marker: + reqs = [] + new_extra = safe_extra(new_extra) or None + + dm.setdefault(new_extra, []).extend(reqs) + return dm + + def _build_dep_map(self): + dm = {} + for name in 'requires.txt', 'depends.txt': + for extra, reqs in split_sections(self._get_metadata(name)): + dm.setdefault(extra, []).extend(parse_requirements(reqs)) + return dm + + def requires(self, extras=()): + """List of Requirements needed for this distro if `extras` are used""" + dm = self._dep_map + deps = [] + deps.extend(dm.get(None, ())) + for ext in extras: + try: + deps.extend(dm[safe_extra(ext)]) + except KeyError: + raise UnknownExtra( + "%s has no such extra feature %r" % (self, ext) + ) + return deps + + def _get_metadata(self, name): + if self.has_metadata(name): + for line in self.get_metadata_lines(name): + yield line + + def activate(self, path=None, replace=False): + """Ensure distribution is importable on `path` (default=sys.path)""" + if path is None: + path = sys.path + self.insert_on(path, replace=replace) + if path is sys.path: + fixup_namespace_packages(self.location) + for pkg in self._get_metadata('namespace_packages.txt'): + if pkg in sys.modules: + declare_namespace(pkg) + + def egg_name(self): + """Return what this distribution's standard .egg filename should be""" + filename = "%s-%s-py%s" % ( + to_filename(self.project_name), to_filename(self.version), + self.py_version or PY_MAJOR + ) + + if self.platform: + filename += '-' + self.platform + return filename + + def __repr__(self): + if self.location: + return "%s (%s)" % (self, self.location) + else: + return str(self) + + def __str__(self): + try: + version = getattr(self, 'version', None) + except ValueError: + version = None + version = version or "[unknown version]" + return "%s %s" % (self.project_name, version) + + def __getattr__(self, attr): + """Delegate all unrecognized public attributes to .metadata provider""" + if attr.startswith('_'): + raise AttributeError(attr) + return getattr(self._provider, attr) + + def __dir__(self): + return list( + set(super(Distribution, self).__dir__()) + | set( + attr for attr in self._provider.__dir__() + if not attr.startswith('_') + ) + ) + + if not hasattr(object, '__dir__'): + # python 2.7 not supported + del __dir__ + + @classmethod + def from_filename(cls, filename, metadata=None, **kw): + return cls.from_location( + _normalize_cached(filename), os.path.basename(filename), metadata, + **kw + ) + + def as_requirement(self): + """Return a ``Requirement`` that matches this distribution exactly""" + if isinstance(self.parsed_version, packaging.version.Version): + spec = "%s==%s" % (self.project_name, self.parsed_version) + else: + spec = "%s===%s" % (self.project_name, self.parsed_version) + + return Requirement.parse(spec) + + def load_entry_point(self, group, name): + """Return the `name` entry point of `group` or raise ImportError""" + ep = self.get_entry_info(group, name) + if ep is None: + raise ImportError("Entry point %r not found" % ((group, name),)) + return ep.load() + + def get_entry_map(self, group=None): + """Return the entry point map for `group`, or the full entry map""" + try: + ep_map = self._ep_map + except AttributeError: + ep_map = self._ep_map = EntryPoint.parse_map( + self._get_metadata('entry_points.txt'), self + ) + if group is not None: + return ep_map.get(group, {}) + return ep_map + + def get_entry_info(self, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return self.get_entry_map(group).get(name) + + def insert_on(self, path, loc=None, replace=False): + """Ensure self.location is on path + + If replace=False (default): + - If location is already in path anywhere, do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent. + - Else: add to the end of path. + If replace=True: + - If location is already on path anywhere (not eggs) + or higher priority than its parent (eggs) + do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent, + removing any lower-priority entries. + - Else: add it to the front of path. + """ + + loc = loc or self.location + if not loc: + return + + nloc = _normalize_cached(loc) + bdir = os.path.dirname(nloc) + npath = [(p and _normalize_cached(p) or p) for p in path] + + for p, item in enumerate(npath): + if item == nloc: + if replace: + break + else: + # don't modify path (even removing duplicates) if + # found and not replace + return + elif item == bdir and self.precedence == EGG_DIST: + # if it's an .egg, give it precedence over its directory + # UNLESS it's already been added to sys.path and replace=False + if (not replace) and nloc in npath[p:]: + return + if path is sys.path: + self.check_version_conflict() + path.insert(p, loc) + npath.insert(p, nloc) + break + else: + if path is sys.path: + self.check_version_conflict() + if replace: + path.insert(0, loc) + else: + path.append(loc) + return + + # p is the spot where we found or inserted loc; now remove duplicates + while True: + try: + np = npath.index(nloc, p + 1) + except ValueError: + break + else: + del npath[np], path[np] + # ha! + p = np + + return + + def check_version_conflict(self): + if self.key == 'setuptools': + # ignore the inevitable setuptools self-conflicts :( + return + + nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) + loc = normalize_path(self.location) + for modname in self._get_metadata('top_level.txt'): + if (modname not in sys.modules or modname in nsp + or modname in _namespace_packages): + continue + if modname in ('pkg_resources', 'setuptools', 'site'): + continue + fn = getattr(sys.modules[modname], '__file__', None) + if fn and (normalize_path(fn).startswith(loc) or + fn.startswith(self.location)): + continue + issue_warning( + "Module %s was already imported from %s, but %s is being added" + " to sys.path" % (modname, fn, self.location), + ) + + def has_version(self): + try: + self.version + except ValueError: + issue_warning("Unbuilt egg for " + repr(self)) + return False + return True + + def clone(self, **kw): + """Copy this distribution, substituting in any changed keyword args""" + names = 'project_name version py_version platform location precedence' + for attr in names.split(): + kw.setdefault(attr, getattr(self, attr, None)) + kw.setdefault('metadata', self._provider) + return self.__class__(**kw) + + @property + def extras(self): + return [dep for dep in self._dep_map if dep] + + +class EggInfoDistribution(Distribution): + def _reload_version(self): + """ + Packages installed by distutils (e.g. numpy or scipy), + which uses an old safe_version, and so + their version numbers can get mangled when + converted to filenames (e.g., 1.11.0.dev0+2329eae to + 1.11.0.dev0_2329eae). These distributions will not be + parsed properly + downstream by Distribution and safe_version, so + take an extra step and try to get the version number from + the metadata file itself instead of the filename. + """ + md_version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if md_version: + self._version = md_version + return self + + +class DistInfoDistribution(Distribution): + """ + Wrap an actual or potential sys.path entry + w/metadata, .dist-info style. + """ + PKG_INFO = 'METADATA' + EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") + + @property + def _parsed_pkg_info(self): + """Parse and cache metadata""" + try: + return self._pkg_info + except AttributeError: + metadata = self.get_metadata(self.PKG_INFO) + self._pkg_info = email.parser.Parser().parsestr(metadata) + return self._pkg_info + + @property + def _dep_map(self): + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._compute_dependencies() + return self.__dep_map + + def _compute_dependencies(self): + """Recompute this distribution's dependencies.""" + dm = self.__dep_map = {None: []} + + reqs = [] + # Including any condition expressions + for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: + reqs.extend(parse_requirements(req)) + + def reqs_for_extra(extra): + for req in reqs: + if not req.marker or req.marker.evaluate({'extra': extra}): + yield req + + common = frozenset(reqs_for_extra(None)) + dm[None].extend(common) + + for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: + s_extra = safe_extra(extra.strip()) + dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) + + return dm + + +_distributionImpl = { + '.egg': Distribution, + '.egg-info': EggInfoDistribution, + '.dist-info': DistInfoDistribution, +} + + +def issue_warning(*args, **kw): + level = 1 + g = globals() + try: + # find the first stack frame that is *not* code in + # the pkg_resources module, to use for the warning + while sys._getframe(level).f_globals is g: + level += 1 + except ValueError: + pass + warnings.warn(stacklevel=level + 1, *args, **kw) + + +class RequirementParseError(ValueError): + def __str__(self): + return ' '.join(self.args) + + +def parse_requirements(strs): + """Yield ``Requirement`` objects for each specification in `strs` + + `strs` must be a string, or a (possibly-nested) iterable thereof. + """ + # create a steppable iterator, so we can handle \-continuations + lines = iter(yield_lines(strs)) + + for line in lines: + # Drop comments -- a hash without a space may be in a URL. + if ' #' in line: + line = line[:line.find(' #')] + # If there is a line continuation, drop it, and append the next line. + if line.endswith('\\'): + line = line[:-2].strip() + try: + line += next(lines) + except StopIteration: + return + yield Requirement(line) + + +class Requirement(packaging.requirements.Requirement): + def __init__(self, requirement_string): + """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" + try: + super(Requirement, self).__init__(requirement_string) + except packaging.requirements.InvalidRequirement as e: + raise RequirementParseError(str(e)) + self.unsafe_name = self.name + project_name = safe_name(self.name) + self.project_name, self.key = project_name, project_name.lower() + self.specs = [ + (spec.operator, spec.version) for spec in self.specifier] + self.extras = tuple(map(safe_extra, self.extras)) + self.hashCmp = ( + self.key, + self.specifier, + frozenset(self.extras), + str(self.marker) if self.marker else None, + ) + self.__hash = hash(self.hashCmp) + + def __eq__(self, other): + return ( + isinstance(other, Requirement) and + self.hashCmp == other.hashCmp + ) + + def __ne__(self, other): + return not self == other + + def __contains__(self, item): + if isinstance(item, Distribution): + if item.key != self.key: + return False + + item = item.version + + # Allow prereleases always in order to match the previous behavior of + # this method. In the future this should be smarter and follow PEP 440 + # more accurately. + return self.specifier.contains(item, prereleases=True) + + def __hash__(self): + return self.__hash + + def __repr__(self): + return "Requirement.parse(%r)" % str(self) + + @staticmethod + def parse(s): + req, = parse_requirements(s) + return req + + +def _always_object(classes): + """ + Ensure object appears in the mro even + for old-style classes. + """ + if object not in classes: + return classes + (object,) + return classes + + +def _find_adapter(registry, ob): + """Return an adapter factory for `ob` from `registry`""" + types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) + for t in types: + if t in registry: + return registry[t] + + +def ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + py31compat.makedirs(dirname, exist_ok=True) + + +def _bypass_ensure_directory(path): + """Sandbox-bypassing version of ensure_directory()""" + if not WRITE_SUPPORT: + raise IOError('"os.mkdir" not supported on this platform.') + dirname, filename = split(path) + if dirname and filename and not isdir(dirname): + _bypass_ensure_directory(dirname) + try: + mkdir(dirname, 0o755) + except FileExistsError: + pass + + +def split_sections(s): + """Split a string or iterable thereof into (section, content) pairs + + Each ``section`` is a stripped version of the section header ("[section]") + and each ``content`` is a list of stripped lines excluding blank lines and + comment-only lines. If there are any such lines before the first section + header, they're returned in a first ``section`` of ``None``. + """ + section = None + content = [] + for line in yield_lines(s): + if line.startswith("["): + if line.endswith("]"): + if section or content: + yield section, content + section = line[1:-1].strip() + content = [] + else: + raise ValueError("Invalid section heading", line) + else: + content.append(line) + + # wrap up last segment + yield section, content + + +def _mkstemp(*args, **kw): + old_open = os.open + try: + # temporarily bypass sandboxing + os.open = os_open + return tempfile.mkstemp(*args, **kw) + finally: + # and then put it back + os.open = old_open + + +# Silence the PEP440Warning by default, so that end users don't get hit by it +# randomly just because they use pkg_resources. We want to append the rule +# because we want earlier uses of filterwarnings to take precedence over this +# one. +warnings.filterwarnings("ignore", category=PEP440Warning, append=True) + + +# from jaraco.functools 1.3 +def _call_aside(f, *args, **kwargs): + f(*args, **kwargs) + return f + + +@_call_aside +def _initialize(g=globals()): + "Set up global resource manager (deliberately not state-saved)" + manager = ResourceManager() + g['_manager'] = manager + g.update( + (name, getattr(manager, name)) + for name in dir(manager) + if not name.startswith('_') + ) + + +@_call_aside +def _initialize_master_working_set(): + """ + Prepare the master working set and make the ``require()`` + API available. + + This function has explicit effects on the global state + of pkg_resources. It is intended to be invoked once at + the initialization of this module. + + Invocation by other packages is unsupported and done + at their own risk. + """ + working_set = WorkingSet._build_master() + _declare_state('object', working_set=working_set) + + require = working_set.require + iter_entry_points = working_set.iter_entry_points + add_activation_listener = working_set.subscribe + run_script = working_set.run_script + # backward compatibility + run_main = run_script + # Activate all distributions already on sys.path with replace=False and + # ensure that all distributions added to the working set in the future + # (e.g. by calling ``require()``) will get activated as well, + # with higher priority (replace=True). + tuple( + dist.activate(replace=False) + for dist in working_set + ) + add_activation_listener( + lambda dist: dist.activate(replace=True), + existing=False, + ) + working_set.entries = [] + # match order + list(map(working_set.add_entry, sys.path)) + globals().update(locals()) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b6c7d2110b5cfd87b3b1cf71e234465b841d994f GIT binary patch literal 95982 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/__pycache__/py31compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ca0dca3a9ee4643970c3afce56fedd3ede0430a9 GIT binary patch literal 599 zcmYjO!EO^V5S_7|WRoU=69+y3X%B5^+9N_$QK}-Lf)oVp3TcUAQ+795FXL@VP~d?0 z58%iz`N}E3z=`of5o668d&ZjgJU$)_dcc-^z4vM?0DgwUjY-}dvAfp{8Z<5-`4ch0 z<}4DyQ7q(AB?>`DTItpoOj<_e?dpkc8<BSuNGQ;r>P`Wr5`d6ICZZRnRVo8{H|c7e zLfqXl3!KI1rOQ?)b5_$>P!TjfVt1zu>tPMwa0A~F;U$!Z3TjdG=osOnK=^QHgLHo* za#_n<6_UoE`4+3>>L+my7f>>4U`9NPTV7b_qvfnHIwR*hPp1<iOTJ}@O6%K`$@$~y z^H_RS&FZ&4GONthsV%%TtN9P09TxO!GOCx=sLHC{taSBkvDlrzzby0m-C;;Jo?e?$ zTN+ixWlF}`E1DZOs@4blbGzi$d)3<a(;FS>!G08;+x!g*9O7+WG~iq;wqYV$750*b z9Oza^U`XIe+@nyZHUm#`?fedF*!#;*VX93ZFP~kEegE2!%WRou<s0jVr7_z5Q$c~F gdEtN14}GHtORKLI=3yXpK|_SRL|^v$ZM-Xf143krF#rGn literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py b/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py new file mode 100644 index 0000000..a2d3007 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pkg_resources/py31compat.py @@ -0,0 +1,23 @@ +import os +import errno +import sys + +from pip._vendor import six + + +def _makedirs_31(path, exist_ok=False): + try: + os.makedirs(path) + except OSError as exc: + if not exist_ok or exc.errno != errno.EEXIST: + raise + + +# rely on compatibility behavior until mode considerations +# and exists_ok considerations are disentangled. +# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 +needs_makedirs = ( + six.PY2 or + (3, 4) <= sys.version_info < (3, 4, 1) +) +makedirs = _makedirs_31 if needs_makedirs else os.makedirs diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/progress/__init__.py new file mode 100644 index 0000000..a41f65d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/progress/__init__.py @@ -0,0 +1,127 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import division + +from collections import deque +from datetime import timedelta +from math import ceil +from sys import stderr +from time import time + + +__version__ = '1.4' + + +class Infinite(object): + file = stderr + sma_window = 10 # Simple Moving Average window + + def __init__(self, *args, **kwargs): + self.index = 0 + self.start_ts = time() + self.avg = 0 + self._ts = self.start_ts + self._xput = deque(maxlen=self.sma_window) + for key, val in kwargs.items(): + setattr(self, key, val) + + def __getitem__(self, key): + if key.startswith('_'): + return None + return getattr(self, key, None) + + @property + def elapsed(self): + return int(time() - self.start_ts) + + @property + def elapsed_td(self): + return timedelta(seconds=self.elapsed) + + def update_avg(self, n, dt): + if n > 0: + self._xput.append(dt / n) + self.avg = sum(self._xput) / len(self._xput) + + def update(self): + pass + + def start(self): + pass + + def finish(self): + pass + + def next(self, n=1): + now = time() + dt = now - self._ts + self.update_avg(n, dt) + self._ts = now + self.index = self.index + n + self.update() + + def iter(self, it): + try: + for x in it: + yield x + self.next() + finally: + self.finish() + + +class Progress(Infinite): + def __init__(self, *args, **kwargs): + super(Progress, self).__init__(*args, **kwargs) + self.max = kwargs.get('max', 100) + + @property + def eta(self): + return int(ceil(self.avg * self.remaining)) + + @property + def eta_td(self): + return timedelta(seconds=self.eta) + + @property + def percent(self): + return self.progress * 100 + + @property + def progress(self): + return min(1, self.index / self.max) + + @property + def remaining(self): + return max(self.max - self.index, 0) + + def start(self): + self.update() + + def goto(self, index): + incr = index - self.index + self.next(incr) + + def iter(self, it): + try: + self.max = len(it) + except TypeError: + pass + + try: + for x in it: + yield x + self.next() + finally: + self.finish() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6492871387a77f1da8ef2b65e4f3f43a73553ede GIT binary patch literal 3867 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 WRz7m2zK<0huY+rV`}u+2|KR`RwC?Z# literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/bar.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d9cf8e0a87287691079f6fbfe7bf53a32d076bcd GIT binary patch literal 2689 zcmbVOTaVjB6!!QYC)sAV+bg$4Wvd#gU4#k(3DBx5ad{xBR3wB2irkEoI5<u^cG!y? zgtQg3Tm?w2cw)DGKs;6Ag-8C!Ji^odg}%UdY-cyy7K!5QoHOUlc>J9+XTI4>^}3_r z@qRx0;ipwa`HPI{W1zE&mfV5h3TKfrU>;-CS0mL^xyJQK8|a=6pT>>I7?_^Pl(!Ua za_hRnt-uWQZQZlrv3UiaN?>hko(<dKRoK<QhFyVO<8|2e+;(8k@guO0<nybr8+;!2 zd{D*w8tesr6!y{Fu5<N@;x6t1r{Xf%7{_6I$b(iCrh)LIq`Ak65&N<jc14gRm{ogU zU^t534L8ELO|MQL6`fVI<RV0%c#JCumU$XiJ)LWw!FA8%hG%ipv$^F}xa~Q-!kz1i zSLIbesY&gUFZP!3zErm6m(PVU4>nxBvV3mfLvN`|*_N6u-Dmha^In_a(PNiw4La#V zq)Mjr8JfDNY_kdVSjJ8&6BRuzQ;sVW$iAMjMP;I+XJnW;G0-#fQIoSBE2BAfrf1}@ zWM<dgWfLn?cAU)G%{LU7)uy1&yH%-$aVm}Vkf%LqkIIZmYk<7@-9YM{Fp8uT3`Xf@ zEAN}hxYG$Yq~0Hfv2?EbqBRl$dGdZaYONOucWtRBLDZ3TdO6^&D2TiGRIOOCu*4j& zNDWI#BlnAWa_CVQ2fr%fNf`HET}cO{l~Fi4AI3@QN74EAdN=N;*DjJXZ>>*)m=DFu zG>R20cww|D&GCr)X>bP1BnuD<YcNN3Sn*q6HrsNrgBOZvO>C&$YQ_E_Xtku%Y7K^b z98tg4YF!)qQ86NFSSSacgB3@~TqMyTaRfqEdm#$5Jr>DOh^NU-q0ES<$TT5Nq2<_Y zrXT*P`S_udr2<-|7nUF%Dp?gJtD$6Z61jn`Hf43K=ZkI_cM;@Pefiud5bYpNUB0|5 zDp+EyLHv2+r$XPl(R6L`3|wM~#Iq!5KOPn0Oe}e5c|ert7tj)-n}dJ^`5zq!<?W$B zG=SIT{F|s7V84RY<1izH66T#!-)*|agK+n^;F0*A!`EIxOLPdrC&=@^k*$TI9nB!S zeXl@v`{rXKTLzBT4<RGZA!HgHt2E_#h-uCOt*`GGob57k8oXu3#9Sx=Zh)o0T*#y) z=iZ6iA{b!j{RnB4+Ikqf+Drx9`g&RcZe`Z}UFrU|)ZdhPI{mBC{<73JOMPRX>gcRc zrL7V0-yjOAD@iV=HxQYc>X{0kMmp0@DnxX!iRyAYr#jFYh!BL=XPli<G7WE9na<UZ zb#axvnSM%%abHbrSY~Q*H8b!%dmB``O@vv2A7fa>;o1%;5;n*&vojj0W=<DGIjMp& zYgu)lGWF)(-*^O_zJfgKQUiZUbJX*bASno;PNTS7OKPA(lp3yq;sg=<%p9X*Fx{Fs zPLr&-SVlSrL@AB9GY0({`H(c@f*gr01u=%Sz%2qBDo&FtKcr7k?|^3V14-2LHd;c{ z6!2aRoL6w*96QcV!qb3n>)7E6*(byY=|F19W`f%y^3%>x45R}>7HP5`raeJr`R`nJ z7NeKYlKk?+H%(Pn1$hq@`98x@{-#A<T*@eAP1={kjev^SwToKY{jAj2OZ|DNzbN$G zss5$3e=qePO;>-AJ@OC^Qg}dYF9FR5gkFWPnIQY|a9`>9e3Nh+vj^<^0?e%+O8sN0 z!NmU^+{*y-(F{1U-8s6zI^%RKaDfSeEnXx+=@&$Q(&_~fE`&tTe}MU2lk;>=iGtWC r-<>>EK}*im)_!87{aSHJzCk6J5S!OjTdlF0ws4|hHw^qvH1vM}Z)Y`| literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/counter.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7cfde8c83526d2967da64bac835bad9ef65f2eb8 GIT binary patch literal 1531 zcmbVL&ui2`6rRZ>*=)L7*QII|5j`m6(C$S%sT6w<4=#lYLJ&gOnYO7(Hl0aqE!%@` z{Q(|C@W)X-`Y+8<PyG+1C*R9vx2>!w4!rj=-%MuSeD8aAnoXC$@IPOB^wT2b2TsNV z=41&>NpPHS8k2<jloD=m78?okSz`KTIX7b~v3;A8yM$ZZ-Y47^wqQfkuK`ly4j>L7 zCLj(Vb?yS<R!AL?8QuV-A?icsyS%wdyx9Y|mv~gSiZtr=xd`GY7cz|10mTJFJNMGH zC<RbEE3&^Xg;KEHeJBCCAMHeG4^J2m13s3()J1TD_>>dh;M8Z_@J-IRxleqHTX3_j zYs>v2h08Q~(8J4cU^Ky&!PFeM0r^65Iv|_IkbXs82>eUC9@Ew~rl6V1rM9A!iyg?z zR3cvcMr0FyJ-pS)ldO|P*+P`6JdERo-u8OBnQvW3u(aTbNO@m&vg&D_-YBQV?5Vbk zjEA|nfT`fS2;H5nQeGS_b>S6G5Ts!uf<U`Lko0*G<98znwu&&WR%!{b7Oo3Dvk?Ks zy+W$Kl&9dxGSOph7O@(*vtY^w=TMWHMu|;ldLA~NWSTQz+2kfLW$AjEGVgDv|HHDZ z!|4+BtLsuEAt)hT_o!?jj3kd-nKr)X3fP#e*5u|1U6yR&Kc~^P(P4@IOvD*jy#%IE z5<r9@5t&ZIKM2lR&BNYfuYO1`7Yq*i{_$BApI32M#r-P2sN%~izN+HuBQEhE?BZoG zbpu=un%$&Bx<_+kKslW!IRnHT&^a=sLu1bXO<TBUV4NotO&eW_M}eYPEK+S}8=(?P zvm{D2i_%;>V~v(I@mN^{T}!KtG@4cq53@oU5$e);y4xrznAF4my&fp`zZB&hY`F?{ zT%CyZz$OFxcnM5ly-%tWRLL}3iG*j3*!=XSitnrVu8JS3__phrQxiQBVEI+5@G@N3 z!JDyV9V&6&^=7a;*NVK5(47*Oq=OEHC9!<Ewjtt7NF|Z2vfWCtNqky)$T4~+w`u3* WsO4{?q!o5WgSKdcwVigY?fwEQ1U3x- literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/helpers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..18ab229314218ff1f55f4340e80f09406a04e55e GIT binary patch literal 2973 zcmai0TW=gS6t?HSm$YdcickwI1p*6dBSo|ih;nJ6ZG=drhPGmgG}^9bvlC`#Q`<}0 zX#12%<)!=u(ntQ1UwPs$^oj3yCcB$U!>)YB_SoZd`ObHIV{Wd_@QeRi{Pm9pWB<@# z|L39eEt(P#f(f3p0gpLn!igQ>#_nw<JmK#$;iuk?8~YdsBE&ef;{bc2JRF2^IEdm1 z`<STZwLv|ubB48b(ZJe<UE2`NHP)W{7bmecH>WmbR_LTRD!Muw7TdvvN8c=8&8ug> zOUw3uq$d5;GDON^E*R9~u`6mXSdR-=c)PV2ii%*D#l8qdglF)Ac`OcbXx-Ew%1oy} zWlyu>)@s+WUt`S0(?^3_nCe4lrumrdI2%rnjh#Qq5f~@#n9ECJ>Um?f;Y&esFL=dl zFO+w5q-(;VS>e8PInxpP-t3IsQGdnAMbOAwl^o|8)^?1W7Q%SFEKl1F<EznTDkW)V zq9n<ROecv6lC4bWz6l4ZQl0fw2J}A2R7dM)rqRztnsi4}4W;p|UrpoA%J)AcH}BtD zyL-?0y?mtlZP$1z&3lsYV1nPaI&xhh6161h<{hPy<Zt%+`jQ@OE^TI;m$O3YPM%-x zZmky^`pFkGX<PC;6duZ@O*veb&}XTi=FnMP*?cA=eEJ<Ubryp0vpnD)51e^C=P}wo zH;u!Ued{LSpfFQ7Zlb9e0#0M{0m(fMXFs4|Y&Z+-xijW_F7;pW=dSj~&e(k$n5C6f z0DO9@gE8OXJD5-GyS;EG0Izu@>BP1p=}_y^c4Qxt03mA-#?LoKO3OLwyMxYC<K}50 zPh;5j<UGxCW%y&myYd`HrC6YOe~TdZF}kV=!Qg;8Z}J6l!~BdJ?6NMQfqwLy_~0`P z$R@c+()xgUj$G8R+Ij<46W}bU+|{E7`7;KQ8l@$TwL5noR_JJRYsX>rgC4M_`j@ds z+5F?@`SzI^z03D)zS@omsYPdy0;%;R84SfJr+za@o{Tzq`9|8)2_NzziT5DPTm`*u zn&(L}RRKB?fFwE6=E8Y&6m5>U=bUOrk)1uBB)-J510>Nni6lf#)Ik=ZC5s5D*)&aS zWnP>}7q@WAQMv$8T(m?%==9_bl6yX|OT9qe(4mfO+&~T|#;qnp93Vd=VVy=vdt5B# zDZFUAWen}2Gc-{-&|=bhkv?)2P0<?4Ov+1y^sQNAr#X2n9zViP*ui9rq{U-PgNSD{ zucEhYZ|=gQACKbEow0$E>J8`%yLsA?d2t;}D)`Ow?S%unR!b)IL99MWoooB5E>BcN zZ_gnD(BSjg<gqKf2{rs*8j%-l8kIEQlr-SwS&>c=Y@utyE#iQ@_>Rn=2oMWIXopOx zmL1Om$C;unp9%gFB?{`ha#=fIgmTuFpehdVFV%{pftV!*3PhQo@1l2nNNmF1#_Ne4 zO^|v;=vA&<nQ}r+zE2-*k@$ebH2tmr7HN(+Kwcs-;m&>FTFesqspMPC+RTq4FA8i{ zpl}8%TQ54f3D#C_udM!zQs$*kGkt&+Tx_SG`V?Z86)Y#<j<Xx#;$ZJMv2Qsb00#u7 zv6ii`6xve2_O*NIdZsjLT&vS64{h~3g~(Ic(*2HZbx|l)tF*o~ELx>PlW>v})TnGI zvUf@xAPalXAVNnV{T-(wbMR_VasX9<k^?@W9vNazCs2d#Pn8-K0T_>Jx_mPO+{flB zpHPMtW{jMs{=UoTNjY_s_E0>KKg{M2vS)|xMs$;L%9{+TsEuYD>-Lqg@fi(p{g5aQ z(-@bu{yA3uLZ2?HOT@P?98l+wf#D%QnJ`Jju#2iec_ry<Cqapvc#lq_Y#=B#JxOz` z;Cs}p-bjxmYL+B}Eu~6I1rrP(Z=_vqt4&G9(-^qwnUZ9${m_hg6Vf%&S7kB$+D4w3 Py6Jk{bLTJO&ztUlAOJ=8 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/progress/__pycache__/spinner.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cd8f9e8aec4a62c57aece5b4e9b97095af6ec2ae GIT binary patch literal 1448 zcmbVMJ8#rL5Z?7WzRPh02yZC`LYz=?4JDux6bOk#k%EL|MY2w}n~Ni#?d+aOh(eXr z5s!j0gsZ4%ct|||$Cgm#FI>fpy@4Figtca7zuEEbw=-kk8Xxxwj9~Zj;;v1|4+IAT zFlm9v4N#0Q8j~IkC?(8bW^DA#z%1rgZ1wEGrsNJ`HgmQKbGXgTEh})q<1!CC9(T6P zzy&<Ue87HzJ-`)K1zaug7~pYM16(Vx&yFpSMtvX7Ck?9Vc@lL}#=|)3bJ33FJ}no# zyU9|NfD?lJ2LdLu(R!40@V$d!z@!Btr$BKMP(}iS(ZFOzU@<eWnZ@jF5;)9(GhO8_ zWKoiEp-96T(&-^x9Ma7pZQk$Tp*V0y3*<J4yaZ~KtdKqhZEVp=@)%|>O+=gYEZM`n z5!ji|H7sRE3FGU^jCrD*Y`HDDRQ4JYZy3swJYG^XdQHRx>^i*B?Dw)}7G={>BKz$) zp6;x5la>DJHFOpdKI92YMKcp=S8yqtvLru~JyK4dv38%IN0vyJ&^q0y>D$eei*s;c zFAS4*kB6c1!?2gKJjQu73|I4ZtXJF~Y~Jp2QG<O{WjTUkbaEk6Ax?s);Co1&K%WC@ z5=45SJZj-%6yA~gAhi~TodNZ`KG<u_>RM1I8?xspe?H=xd~QPM_ZJ_ueXs31ZQnws z#VH68c)U1`3V9zQi1`%-%X2WB0+Co%j|#;9#ji4(rpYM5r<%|+ZJ%iS{3ryme%NFO z1QCxA#5}h!-~y;W69`E(y3Vg8R_;Z~Xcl)qmZWw*Y5Q5*FGnGXM_)k>I*W)$NMaAP zFklMQUnJr0f&YuH2Smr9+P<pJN9#NuN$22e$!wtOK6s<?ZfW<vmG+gk1AU{xk#2Gk z_+3S!`X-3y8WsFDmhyfs;M)+mBwSS3yvkkXamIxd_~R@Zyyzl<l@gc<ft&oR`;>RR W{NQdLhX{#HTBY!q6Mo%-$NUL|P%g;; literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/bar.py b/env/lib/python3.7/site-packages/pip/_vendor/progress/bar.py new file mode 100644 index 0000000..025e61c --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/progress/bar.py @@ -0,0 +1,94 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals + +import sys + +from . import Progress +from .helpers import WritelnMixin + + +class Bar(WritelnMixin, Progress): + width = 32 + message = '' + suffix = '%(index)d/%(max)d' + bar_prefix = ' |' + bar_suffix = '| ' + empty_fill = ' ' + fill = '#' + hide_cursor = True + + def update(self): + filled_length = int(self.width * self.progress) + empty_length = self.width - filled_length + + message = self.message % self + bar = self.fill * filled_length + empty = self.empty_fill * empty_length + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix, + suffix]) + self.writeln(line) + + +class ChargingBar(Bar): + suffix = '%(percent)d%%' + bar_prefix = ' ' + bar_suffix = ' ' + empty_fill = '∙' + fill = '█' + + +class FillingSquaresBar(ChargingBar): + empty_fill = '▢' + fill = '▣' + + +class FillingCirclesBar(ChargingBar): + empty_fill = '◯' + fill = '◉' + + +class IncrementalBar(Bar): + if sys.platform.startswith('win'): + phases = (u' ', u'▌', u'█') + else: + phases = (' ', '▏', '▎', '▍', '▌', '▋', '▊', '▉', '█') + + def update(self): + nphases = len(self.phases) + filled_len = self.width * self.progress + nfull = int(filled_len) # Number of full chars + phase = int((filled_len - nfull) * nphases) # Phase of last char + nempty = self.width - nfull # Number of empty chars + + message = self.message % self + bar = self.phases[-1] * nfull + current = self.phases[phase] if phase > 0 else '' + empty = self.empty_fill * max(0, nempty - len(current)) + suffix = self.suffix % self + line = ''.join([message, self.bar_prefix, bar, current, empty, + self.bar_suffix, suffix]) + self.writeln(line) + + +class PixelBar(IncrementalBar): + phases = ('⡀', '⡄', '⡆', '⡇', '⣇', '⣧', '⣷', '⣿') + + +class ShadyBar(IncrementalBar): + phases = (' ', '░', '▒', '▓', '█') diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/counter.py b/env/lib/python3.7/site-packages/pip/_vendor/progress/counter.py new file mode 100644 index 0000000..6b45a1e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/progress/counter.py @@ -0,0 +1,48 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Infinite, Progress +from .helpers import WriteMixin + + +class Counter(WriteMixin, Infinite): + message = '' + hide_cursor = True + + def update(self): + self.write(str(self.index)) + + +class Countdown(WriteMixin, Progress): + hide_cursor = True + + def update(self): + self.write(str(self.remaining)) + + +class Stack(WriteMixin, Progress): + phases = (' ', '▁', '▂', '▃', '▄', '▅', '▆', '▇', '█') + hide_cursor = True + + def update(self): + nphases = len(self.phases) + i = min(nphases - 1, int(self.progress * nphases)) + self.write(self.phases[i]) + + +class Pie(Stack): + phases = ('○', '◔', '◑', '◕', '●') diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py b/env/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py new file mode 100644 index 0000000..0cde44e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/progress/helpers.py @@ -0,0 +1,91 @@ +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import print_function + + +HIDE_CURSOR = '\x1b[?25l' +SHOW_CURSOR = '\x1b[?25h' + + +class WriteMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WriteMixin, self).__init__(**kwargs) + self._width = 0 + if message: + self.message = message + + if self.file and self.file.isatty(): + if self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + print(self.message, end='', file=self.file) + self.file.flush() + + def write(self, s): + if self.file and self.file.isatty(): + b = '\b' * self._width + c = s.ljust(self._width) + print(b + c, end='', file=self.file) + self._width = max(self._width, len(s)) + self.file.flush() + + def finish(self): + if self.file and self.file.isatty() and self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +class WritelnMixin(object): + hide_cursor = False + + def __init__(self, message=None, **kwargs): + super(WritelnMixin, self).__init__(**kwargs) + if message: + self.message = message + + if self.file and self.file.isatty() and self.hide_cursor: + print(HIDE_CURSOR, end='', file=self.file) + + def clearln(self): + if self.file and self.file.isatty(): + print('\r\x1b[K', end='', file=self.file) + + def writeln(self, line): + if self.file and self.file.isatty(): + self.clearln() + print(line, end='', file=self.file) + self.file.flush() + + def finish(self): + if self.file and self.file.isatty(): + print(file=self.file) + if self.hide_cursor: + print(SHOW_CURSOR, end='', file=self.file) + + +from signal import signal, SIGINT +from sys import exit + + +class SigIntMixin(object): + """Registers a signal handler that calls finish on SIGINT""" + + def __init__(self, *args, **kwargs): + super(SigIntMixin, self).__init__(*args, **kwargs) + signal(SIGINT, self._sigint_handler) + + def _sigint_handler(self, signum, frame): + self.finish() + exit(0) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py b/env/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py new file mode 100644 index 0000000..464c7b2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/progress/spinner.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Giorgos Verigakis <verigak@gmail.com> +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +from __future__ import unicode_literals +from . import Infinite +from .helpers import WriteMixin + + +class Spinner(WriteMixin, Infinite): + message = '' + phases = ('-', '\\', '|', '/') + hide_cursor = True + + def update(self): + i = self.index % len(self.phases) + self.write(self.phases[i]) + + +class PieSpinner(Spinner): + phases = ['◷', '◶', '◵', '◴'] + + +class MoonSpinner(Spinner): + phases = ['◑', '◒', '◐', '◓'] + + +class LineSpinner(Spinner): + phases = ['⎺', '⎻', '⎼', '⎽', '⎼', '⎻'] + +class PixelSpinner(Spinner): + phases = ['⣾','⣷', '⣯', '⣟', '⡿', '⢿', '⣻', '⣽'] diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pyparsing.py b/env/lib/python3.7/site-packages/pip/_vendor/pyparsing.py new file mode 100644 index 0000000..865152d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pyparsing.py @@ -0,0 +1,5742 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2018 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars +============================================================================= + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements +(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to +L{Literal} expressions):: + + from pip._vendor.pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments + + +Getting Started - +----------------- +Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing +classes inherit from. Use the docstrings for examples of how to: + - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes + - construct character word-group expressions using the L{Word} class + - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes + - use L{'+'<And>}, L{'|'<MatchFirst>}, L{'^'<Or>}, and L{'&'<Each>} operators to combine simple expressions into more complex ones + - associate names with your parsed results using L{ParserElement.setResultsName} + - find some helpful expression short-cuts like L{delimitedList} and L{oneOf} + - find more useful common expressions in the L{pyparsing_common} namespace class +""" + +__version__ = "2.2.1" +__versionTime__ = "18 Sep 2018 00:49 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + # Python 3 + from collections.abc import Iterable + from collections.abc import MutableMapping +except ImportError: + # Python 2.7 + from collections import Iterable + from collections import MutableMapping + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', +'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', +'CloseMatch', 'tokenMap', 'pyparsing_common', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # build list of single arg builtins, tolerant of Python version, that can be used as parse actions + singleArgBuiltins = [] + import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + from_symbols = '&><"\'' + to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) + for from_,to_ in zip(from_symbols, to_symbols): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +alphas = string.ascii_uppercase + string.ascii_lowercase +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join(c for c in string.printable if c not in string.whitespace) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + + Example:: + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + Expected integer (at char 0), (line:1, col:1) + column: 1 + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like L{ParseFatalException}, but thrown internally when an + L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop + immediately because an unbacktrackable syntax error has been found""" + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup[0]) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """ + Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) + + Example:: + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + prints:: + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v, isinstance=isinstance ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,(int,slice)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return ( not not self.__toklist ) + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( self.__toklist[::-1] ) + def _iterkeys( self ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys (Python 3.x only).""" + + values = _itervalues + """Returns an iterator of all named result values (Python 3.x only).""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples (Python 3.x only).""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + def keys( self ): + """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iterkeys()) + + def values( self ): + """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.itervalues()) + + def items( self ): + """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iteritems()) + + def haskeys( self ): + """Since keys() returns an iterator, this method is helpful in bypassing + code that looks for the existence of any defined results names.""" + return bool(self.__tokdict) + + def pop( self, *args, **kwargs): + """ + Removes and returns item at specified index (default=C{last}). + Supports both C{list} and C{dict} semantics for C{pop()}. If passed no + argument or an integer argument, it will use C{list} semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use C{dict} + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in C{dict.pop()}. + + Example:: + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + prints:: + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + for k,v in kwargs.items(): + if k == 'default': + args = (args[0], v) + else: + raise TypeError("pop() got an unexpected keyword argument '%s'" % k) + if (isinstance(args[0], int) or + len(args) == 1 or + args[0] in self): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified. + + Similar to C{dict.get()}. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to C{list.insert()}. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def append( self, item ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + def __getattr__( self, name ): + try: + return self[name] + except KeyError: + return "" + + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = lambda a: offset if a<0 else a+offset + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + # useful for merging many ParseResults using sum() builtin + return self.copy() + else: + # this may raise a TypeError - so be it + return other + self + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + result_list = result.asList() + print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] + """ + return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a C{ParseResults} object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """ + (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. + """ + nl = "\n" + out = [] + namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + for i,res in enumerate(self.__toklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + prints:: + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + next(iter(self.__tokdict.values()))[0][1] in (0,-1)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + prints:: + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + items = sorted((str(k), v) for k,v in self.items()) + for k,v in items: + if out: + out.append(NL) + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + elif any(isinstance(vv,ParseResults) for vv in self): + v = self + for i,vv in enumerate(v): + if isinstance(vv,ParseResults): + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) + + Example:: + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + prints:: + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + s = strg + return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'decorator to trim function calls to match the arity of the target' +def _trim_arity(func, maxargs=2): + if func in singleArgBuiltins: + return lambda s,l,t: func(t) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + if system_version[:2] >= (3,5): + def extract_stack(limit=0): + # special handling for Python 3.5.0 - extra deep call stack by 1 + offset = -3 if system_version == (3,5,0) else -2 + frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] + return [frame_summary[:2]] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [frame_summary[:2]] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND + # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! + this_line = extract_stack(limit=2)[-1] + pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element. + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") + integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + prints:: + [5120, 100, 655360, 268435456] + Equivalent form of C{expr.copy()} is just C{expr()}:: + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + + Example:: + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def setParseAction( self, *fns, **kwargs ): + """ + Define one or more actions to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{parseString}<parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + + Example:: + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # note that integer fields are now ints, not strings + date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] + """ + self.parseAction = list(map(_trim_arity, list(fns))) + self.callDuringTry = kwargs.get("callDuringTry", False) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. + + See examples in L{I{copy}<copy>}. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, + functions passed to C{addCondition} need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) + """ + msg = kwargs.get("message", "failed user-defined condition") + exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException + for fn in fns: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + C{fn(s,loc,expr,err)} where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException as err: + #~ print ("Exception raised:", err) + if self.debugActions[2]: + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or preloc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException as err: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + - cache_size_limit - (default=C{128}) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + + Example:: + from pip._vendor import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + def parseString( self, instring, parseAll=False ): + """ + Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}<parseWithTabs>}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + + Example:: + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + se._parse( instring, loc ) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): + """ + Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}<parseString>} for more information on parsing + strings with embedded tabs. + + Example:: + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def transformString( self, instring ): + """ + Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string. + + Example:: + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + Prints:: + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + out = [o for o in out if o] + return "".join(map(_ustr,_flatten(out))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + + Example:: + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + prints:: + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional C{maxsplit} argument, to limit the number of splits; + and the optional C{includeSeparators} argument (default=C{False}), if the separating + matching text should be included in the split results. + + Example:: + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + prints:: + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + for t,s,e in self.scanString(instring, maxMatches=maxsplit): + yield instring[last:s] + if includeSeparators: + yield t[0] + last = e + yield instring[last:] + + def __add__(self, other ): + """ + Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement + converts them to L{Literal}s by default. + + Example:: + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + Prints:: + Hello, World! -> ['Hello', ',', 'World', '!'] + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """ + Implementation of + operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns C{L{And}} with error stop + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns C{L{MatchFirst}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns C{L{Or}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns C{L{Each}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns C{L{NotAny}} + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + + Example:: + # these are equivalent + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + """ + if name is not None: + return self.setResultsName(name) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{<TAB>} characters. + """ + self.keepTabs = True + return self + + def ignore( self, other ): + """ + Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + + Example:: + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable. + + Example:: + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using L{setDebugActions}. Prior to attempting + to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} + is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} + message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """ + Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + + Example:: + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): + """ + Execute the parse expression on a series of test strings, showing each + test, the parsed results or where the parse failed. Quick and easy way to + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + - comment - (default=C{'#'}) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default=C{True}) prints test output to stdout + - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTests} is True), and the results contain a list of lines of each + test's output + + Example:: + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + prints:: + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + for t in tests: + if comment is not None and comment.matches(t, False) or comments and not t: + comments.append(t) + continue + if not t: + continue + out = ['\n'.join(comments), t] + comments = [] + try: + t = t.replace(r'\n','\n') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + except ParseBaseException as pe: + fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" + if '\n' in t: + out.append(line(pe.loc, t)) + out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """ + Abstract C{ParserElement} subclass, for defining atomic matching patterns. + """ + def __init__( self ): + super(Token,self).__init__( savelist=False ) + + +class Empty(Token): + """ + An empty token, will always match. + """ + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """ + A token that will never match. + """ + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + + def parseImpl( self, instring, loc, doActions=True ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use L{CaselessLiteral}. + + For keyword matching (force word break before and after the matched string), + use L{Keyword} or L{CaselessKeyword}. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}: + - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. + - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + - C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$" + - C{caseless} allows case-insensitive matching, default is C{False}. + + Example:: + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use L{CaselessKeyword}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for L{CaselessKeyword}.) + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of L{Keyword}. + + Example:: + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for L{CaselessLiteral}.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class CloseMatch(Token): + """ + A variation on L{Literal} which matches "close" matches, that is, + strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: + - C{match_string} - string to be matched + - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match + + The results from a successful parse will contain the matched text from the input string and the following named results: + - C{mismatches} - a list of the positions within the match_string where mismatches were found + - C{original} - the original match_string used to compare against the input string + + If C{mismatches} is an empty list, then the match was an exact match. + + Example:: + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """ + Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{excludeChars} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + + L{srange} is useful for defining custom character set strings for defining + C{Word} expressions, using range notation from regular expression character sets. + + A common mistake is to use C{Word} to match a specific literal string, as in + C{Word("Address")}. Remember that C{Word} uses the string argument to define + I{sets} of matchable characters. This expression would match "Add", "AAA", + "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. + To match an exact literal string, use L{Literal} or L{Keyword}. + + pyparsing includes helper strings for building Words: + - L{alphas} + - L{nums} + - L{alphanums} + - L{hexnums} + - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) + - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - L{printables} (any non-whitespace character) + + Example:: + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # any string of non-whitespace characters, except for ',' + csv_value = Word(printables, excludeChars=",") + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): + super(Word,self).__init__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.initCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc, result.group() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + if len(s)>4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + r""" + Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as + named parse results. + + Example:: + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression + roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=C{None}) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) + + Example:: + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + prints:: + [['This is the quote']] + [['This is the "quote"']] + [['This is the quote with "embedded" quotes']] + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if not quoteChar: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped whitespace + if '\\' in ret and self.convertWhitespaceEscapes: + ws_map = { + r'\t' : '\t', + r'\n' : '\n', + r'\f' : '\f', + r'\r' : '\r', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """ + Token for matching words composed of characters I{not} in a given set (will + include whitespace in matched characters if not listed in the provided exclusion set - see example). + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + + Example:: + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + prints:: + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """ + Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class. + """ + whiteStrs = { + " " : "<SPC>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) + #~ self.leaveWhitespace() + self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """ + Token to advance to a specific column of input text; useful for tabular report scraping. + """ + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """ + Matches if current position is at the beginning of a line within the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + Prints:: + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +class LineEnd(_PositionToken): + """ + Matches if current position is at the end of a line within the parse string + """ + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """ + Matches if current position is at the beginning of the parse string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc != 0: + # see if entire string up to here is just whitespace and ignoreables + if loc != self.preParse( instring, 0 ): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class StringEnd(_PositionToken): + """ + Matches if current position is at the end of the parse string + """ + def __init__( self ): + super(StringEnd,self).__init__() + self.errmsg = "Expected end of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc < len(instring): + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """ + Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """ + Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of + the string being parsed, or at the end of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class ParseExpression(ParserElement): + """ + Abstract subclass of ParserElement, for combining and post-processing parsed tokens. + """ + def __init__( self, exprs, savelist = False ): + super(ParseExpression,self).__init__(savelist) + if isinstance( exprs, _generatorType ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( exprs ) ] + elif isinstance( exprs, Iterable ): + exprs = list(exprs) + # if sequence of strings provided, wrap with Literal + if all(isinstance(expr, basestring) for expr in exprs): + exprs = map(ParserElement._literalStringClass, exprs) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on + all contained expressions.""" + self.skipWhitespace = False + self.exprs = [ e.copy() for e in self.exprs ] + for e in self.exprs: + e.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + def streamline( self ): + super(ParseExpression,self).streamline() + + for e in self.exprs: + e.streamline() + + # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) + # but only if there are no parse actions or resultsNames on the nested And's + # (likewise for Or's and MatchFirst's) + if ( len(self.exprs) == 2 ): + other = self.exprs[0] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = other.exprs[:] + [ self.exprs[1] ] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + other = self.exprs[-1] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the C{'+'} operator. + May also be constructed using the C{'-'} operator, which will suppress backtracking. + + Example:: + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + expr = And([integer("id"),name_expr("name"),integer("age")]) + # more easily written as: + expr = integer("id") + name_expr("name") + integer("age") + """ + + class _ErrorStop(Empty): + def __init__(self, *args, **kwargs): + super(And._ErrorStop,self).__init__(*args, **kwargs) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = True + + def parseImpl( self, instring, loc, doActions=True ): + # pass False as last arg to _parse for first element, since we already + # pre-parsed the string as part of our And pre-parsing + loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + loc, exprtokens = e._parse( instring, loc, doActions ) + if exprtokens or exprtokens.haskeys(): + resultlist += exprtokens + return loc, resultlist + + def __iadd__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #And( [ self, other ] ) + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the expression that matches the longest string will be used. + May be constructed using the C{'^'} operator. + + Example:: + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + prints:: + [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(Or,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + # save match among all matches, to retry longest to shortest + matches.append((loc2, e)) + + if matches: + matches.sort(key=lambda x: -x[0]) + for _,e in matches: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + + Example:: + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) + print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + + Example:: + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + prints:: + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = True + self.initExprGroups = True + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """ + Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens. + """ + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + if issubclass(ParserElement._literalStringClass, Token): + expr = ParserElement._literalStringClass(expr) + else: + expr = ParserElement._literalStringClass(Literal(expr)) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except Exception: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """ + Lookahead matching of the given parse expression. C{FollowedBy} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list. + + Example:: + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + prints:: + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. C{NotAny} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression does I{not} match at the current + position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator. + + Example:: + + """ + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr.canParseNext(instring, loc): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + def __init__( self, expr, stopOn=None): + super(_MultipleMatch, self).__init__(expr) + self.saveAsList = True + ender = stopOn + if isinstance(ender, basestring): + ender = ParserElement._literalStringClass(ender) + self.not_ender = ~ender if ender is not None else None + + def parseImpl( self, instring, loc, doActions=True ): + self_expr_parse = self.expr._parse + self_skip_ignorables = self._skipIgnorables + check_ender = self.not_ender is not None + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = (not not self.ignoreExprs) + while 1: + if check_ender: + try_not_ender(instring, loc) + if hasIgnoreExprs: + preloc = self_skip_ignorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to L{OneOrMore} + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + prints:: + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + FAIL: Expected end of text (at char 5), (line:1, col:6) + """ + def __init__( self, expr, default=_optionalNotMatched ): + super(Optional,self).__init__( expr, savelist=False ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default=C{False}) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default=C{None}) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default=C{None}) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + prints:: + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.asList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + + See L{ParseResults.pprint} for an example of a recursive parser created using + C{Forward}. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of C{ParseExpression}, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """ + Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + + Example:: + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # no match when there are internal spaces + print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """ + Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. + + Example:: + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] + + func = ident + Group(Optional(delimitedList(term))) + print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """ + Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + prints:: + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + See more examples at L{ParseResults} of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """ + Converter for ignoring the results of a parsed expression. + + Example:: + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + prints:: + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + (See also L{delimitedList}.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """ + Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """ + Decorator for debugging parse actions. + + When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} + When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. + + Example:: + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens)))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + prints:: + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +def delimitedList( expr, delim=",", combine=False ): + """ + Helper to define a delimited list of expressions - the delimiter defaults to ','. + By default, the list elements and delimiters can have intervening whitespace, and + comments, but this can be overridden by passing C{combine=True} in the constructor. + If C{combine} is set to C{True}, the matching tokens are returned as a single token + string, with the delimiters included; otherwise, the matching tokens are returned + as a list of tokens, with the delimiters suppressed. + + Example:: + delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] + delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] + """ + dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """ + Helper to define a counted list of expressions. + This helper defines a pattern of the form:: + integer expr expr expr... + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. + + If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. + + Example:: + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + intExpr = Word(nums).setParseAction(lambda t:int(t[0])) + else: + intExpr = intExpr.copy() + intExpr.setName("arrayLen") + intExpr.addParseAction(countFieldParseAction, callDuringTry=True) + return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches a + previous literal, will also match the leading C{"1:1"} in C{"1:10"}. + If this is not desired, use C{matchPreviousExpr}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches by + expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; + the expressions are evaluated first, and then compared, so + C{"1"} is compared with C{"10"}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + if theseTokens != matchTokens: + raise ParseException("",0,"") + rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def _escapeRegexRangeChars(s): + #~ escape these chars: ^-] + for c in r"\^-]": + s = s.replace(c,_bslash+c) + s = s.replace("\n",r"\n") + s = s.replace("\t",r"\t") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """ + Helper to quickly define a set of alternative Literals, and makes sure to do + longest-first testing when there is a conflict, regardless of the input order, + but returns a C{L{MatchFirst}} for best performance. + + Parameters: + - strs - a string of space-delimited literals, or a collection of string literals + - caseless - (default=C{False}) - treat all literals as caseless + - useRegex - (default=C{True}) - as an optimization, will generate a Regex + object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or + if creating a C{Regex} raises an exception) + + Example:: + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + prints:: + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + if isinstance(strs,basestring): + symbols = strs.split() + elif isinstance(strs, Iterable): + symbols = list(strs) + else: + warnings.warn("Invalid argument to oneOf, expected string or iterable", + SyntaxWarning, stacklevel=2) + if not symbols: + return NoMatch() + + i = 0 + while i < len(symbols)-1: + cur = symbols[i] + for j,other in enumerate(symbols[i+1:]): + if ( isequal(other, cur) ): + del symbols[i+j+1] + break + elif ( masks(cur, other) ): + del symbols[i+j+1] + symbols.insert(i,other) + cur = other + break + else: + i += 1 + + if not caseless and useRegex: + #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) + else: + return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) + except Exception: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) + +def dictOf( key, value ): + """ + Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + + Example:: + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + prints:: + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """ + Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. By default, returns astring containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values. + + Example:: + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + prints:: + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """ + Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """ + Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{<TAB>} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + + Example:: + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + prints:: + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) +_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +def srange(s): + r""" + Helper to easily define string ranges for use in Word construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be: + - a single character + - an escaped character with a leading backslash (such as C{\-} or C{\]}) + - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) + (C{\0x##} is also supported for backwards compatibility) + - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) + - a range of any of the above, separated by a dash (C{'a-z'}, etc.) + - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.) + """ + _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +def matchOnlyAtCol(n): + """ + Helper method for defining parse actions that require matching at a specific + column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """ + Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString<ParserElement.transformString>}()}. + + Example:: + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """ + Helper parse action for removing quotation marks from parsed quoted strings. + + Example:: + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """ + Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional + args are passed, they are forwarded to the given function as additional arguments after + the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the + parsed data to an integer using base 16. + + Example (compare the last to example in L{ParserElement.transformString}:: + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + prints:: + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + now is the winter of our discontent made glorious summer by this sun of york + ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] + """ + def pa(s,l,t): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches + tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. + + Example:: + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are also accessible as named results + print(link.link_text, '->', link.href) + prints:: + pyparsing -> http://pyparsing.wikispaces.com + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for XML, given a tag name. Matches + tags only in the given upper/lower case. + + Example: similar to L{makeHTMLTags} + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """ + Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{<TD>} or C{<DIV>}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "align":"right"}} + - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) + For attribute names with a namespace prefix, you must use the second form. Attribute + names are matched insensitive to upper/lower case. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + + Example:: + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """ + Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + + Example:: + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): + """ + Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary or + binary, left- or right-associative. Parse actions can also be attached + to operator expressions. The generated parser will also recognize the use + of parentheses to override operator precedences (see example below). + + Note: if you define a deep operator list, you may see performance issues + when using infixNotation. See L{ParserElement.enablePackrat} for a + mechanism to potentially improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted); if the parse action + is passed a tuple or list of functions, this is equivalent to + calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) + - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) + - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) + + Example:: + # simple example of four-function arithmetic with ints and variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + prints:: + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + ret = Forward() + lastExpr = baseExpr | ( lpar + ret + rpar ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" + +dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") +sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") +quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| + Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """ + Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression + - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression + - content - expression for items within the nested lists (default=C{None}) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + + Example:: + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + prints:: + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + ret.setName('nested %s%s expression' % (opener,closer)) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """ + Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single grammar + should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond the + the current level; set to False for block of left-most statements + (default=C{True}) + + A valid block must contain at least one C{blockStatement}. + + Example:: + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + funcDef = Group( funcDecl + func_body ) + + rvalue = Forward() + funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") + rvalue << (funcCall | identifier | Word(nums)) + assignment = Group(identifier + "=" + rvalue) + stmt << ( funcDef | assignment | identifier ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + prints:: + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') + PEER = Empty().setParseAction(checkPeerIndent).setName('') + UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) +_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) +commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") +def replaceHTMLEntity(t): + """Helper parser action to replace common HTML entities with their special characters""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form C{/* ... */}" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form C{<!-- ... -->}" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form C{// ... (to end of line)}" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" + +javaStyleComment = cppStyleComment +"Same as C{L{cppStyleComment}}" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form C{# ... (to end of line)}" + +_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + + Optional( Word(" \t") + + ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") +commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") +"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. + This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """ + Here are some common low-level expressions that may be useful in jump-starting parser development: + - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) + - common L{programming identifiers<identifier>} + - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) + - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} + - L{UUID<uuid>} + - L{comma-separated list<comma_separated_list>} + Parse actions: + - C{L{convertToInteger}} + - C{L{convertToFloat}} + - C{L{convertToDate}} + - C{L{convertToDatetime}} + - C{L{stripHTMLTags}} + - C{L{upcaseTokens}} + - C{L{downcaseTokens}} + + Example:: + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + prints:: + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + integer = Word(nums).setName("integer").setParseAction(convertToInteger) + """expression that parses an unsigned integer, returns an int""" + + hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" + mixed_integer.addParseAction(sum) + + real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) + """expression that parses a floating point number and returns a float""" + + sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) + """expression that parses a floating point number with optional scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) + """any int or real number, returned as float""" + + identifier = Word(alphas+'_', alphanums+'_').setName("identifier") + """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" + + ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") + "IPv4 address (C{0.0.0.0 - 255.255.255.255})" + + _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") + _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") + _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") + _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) + _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") + ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) + + Example:: + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + prints:: + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """ + Helper to create a parse action for converting parsed datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) + + Example:: + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + prints:: + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (C{yyyy-mm-dd})" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """ + Parse action to remove HTML tags from web page HTML source + + Example:: + # strip HTML links from normal text + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + td,td_end = makeHTMLTags("TD") + table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end + + print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' + """ + return pyparsing_common._html_stripper.transformString(tokens[0]) + + _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') + + Optional( White(" \t") ) ) ).streamline().setName("commaItem") + comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py new file mode 100644 index 0000000..8dc7315 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__init__.py @@ -0,0 +1,3 @@ +from .core import TomlError +from .parser import load, loads +from .writer import dump, dumps diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1456bc4969f07889185d6bf0b7deac0dc3d466f6 GIT binary patch literal 287 zcmXwz&q@O^5XO_;WcvpTK83J{x;^w*qzGQU=qVJ!(kzmaY~m!f^l3c%O1XOS6+Ah! z;K2N5z7K}^9#^X+!&0AjhXc-U68}}<vd2yvgkgp|=DFgW_R3YhR<##OOuBZ`H>&Y7 zHA5|4SSx=xp0&IzUW0c}00G*n2p4)&Br%aRXCI3srssBE#4*4C^td#!hcp1xC_qfk z1#Ct~lG7l*7*P5Nzq>B`*hL%Hc1*c<ZhgGGji>y+C39;1F^nca7q1y3bz0leX07kz Uwaj-un6n!mD0HHCH~g0W0S&cC1poj5 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/core.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9bbeae95745529c5d7c56bebd1ace6608b4d1e81 GIT binary patch literal 896 zcmbVKON$dh5U!s0u8H8{!J`WzJK!c44<aIqBHnUPPeEwHbZ41iURym;Hkq8<|KaY@ zztmU%g&<hfVZ$hTv4(o|qiVjds$Y%Ahd?s_`uO8d0q~s{w-QirMr!Vpc?$}ZxFXf? z#h(l1y@%A#=wvS*MQ5bu5g8412j-rln^!RRm9GNwfeKYbK2$N~C-&e&Q<ZNJ8_Yt= zVqqVXz9uyjG96rt9(vJxz265nq2L&#M{AHi?STyXfNZFMii%kp+0naI-Q|^brEMZ* zUgw>ZHm<ZWi*s#*GOxAuv!=AkGB0(#sB{|I!02*`%p4g9Mr;_(H^2jOKb}pys-3oZ zdz#m#Ta@K#_W8Unx{Ig0=~RBwwQ6wMUUo!onl-2=?Irq@&Mh*o<Kjp}?pq)2TQIqW znb9bmuxALa7Y`^<;u?A=h<`!s3*ue`HvzHsX6w6~?a5~Q<l$zUK4%l!XxU)3=p2Co zAEuWIOvpJ>JHxPSET!pCO6F=9Er|8KAwYNffB25~bxt<N$Uy(FX&T}k`sLsH{|~%0 zS=2279t{Bh*3sQDzX`g_Q>IsNC}q{CRmt&4%8S*a+?}`~A=kn&8*anEaEp*<!fJRh fiAdtacYCwcL++Sc43b<8*WBdA?yoOhI$ecdp{Ts4 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/parser.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae6275affb1af417c475bdb138ccdc45c7e571bb GIT binary patch literal 11099 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/__pycache__/writer.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35a26307d4cb118572090c70a50ac59976361434 GIT binary patch literal 3798 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py new file mode 100644 index 0000000..c182734 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/core.py @@ -0,0 +1,13 @@ +class TomlError(RuntimeError): + def __init__(self, message, line, col, filename): + RuntimeError.__init__(self, message, line, col, filename) + self.message = message + self.line = line + self.col = col + self.filename = filename + + def __str__(self): + return '{}({}, {}): {}'.format(self.filename, self.line, self.col, self.message) + + def __repr__(self): + return 'TomlError({!r}, {!r}, {!r}, {!r})'.format(self.message, self.line, self.col, self.filename) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pytoml/parser.py b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/parser.py new file mode 100644 index 0000000..9f94e92 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/parser.py @@ -0,0 +1,374 @@ +import string, re, sys, datetime +from .core import TomlError + +if sys.version_info[0] == 2: + _chr = unichr +else: + _chr = chr + +def load(fin, translate=lambda t, x, v: v, object_pairs_hook=dict): + return loads(fin.read(), translate=translate, object_pairs_hook=object_pairs_hook, filename=getattr(fin, 'name', repr(fin))) + +def loads(s, filename='<string>', translate=lambda t, x, v: v, object_pairs_hook=dict): + if isinstance(s, bytes): + s = s.decode('utf-8') + + s = s.replace('\r\n', '\n') + + root = object_pairs_hook() + tables = object_pairs_hook() + scope = root + + src = _Source(s, filename=filename) + ast = _p_toml(src, object_pairs_hook=object_pairs_hook) + + def error(msg): + raise TomlError(msg, pos[0], pos[1], filename) + + def process_value(v, object_pairs_hook): + kind, text, value, pos = v + if kind == 'str' and value.startswith('\n'): + value = value[1:] + if kind == 'array': + if value and any(k != value[0][0] for k, t, v, p in value[1:]): + error('array-type-mismatch') + value = [process_value(item, object_pairs_hook=object_pairs_hook) for item in value] + elif kind == 'table': + value = object_pairs_hook([(k, process_value(value[k], object_pairs_hook=object_pairs_hook)) for k in value]) + return translate(kind, text, value) + + for kind, value, pos in ast: + if kind == 'kv': + k, v = value + if k in scope: + error('duplicate_keys. Key "{0}" was used more than once.'.format(k)) + scope[k] = process_value(v, object_pairs_hook=object_pairs_hook) + else: + is_table_array = (kind == 'table_array') + cur = tables + for name in value[:-1]: + if isinstance(cur.get(name), list): + d, cur = cur[name][-1] + else: + d, cur = cur.setdefault(name, (None, object_pairs_hook())) + + scope = object_pairs_hook() + name = value[-1] + if name not in cur: + if is_table_array: + cur[name] = [(scope, object_pairs_hook())] + else: + cur[name] = (scope, object_pairs_hook()) + elif isinstance(cur[name], list): + if not is_table_array: + error('table_type_mismatch') + cur[name].append((scope, object_pairs_hook())) + else: + if is_table_array: + error('table_type_mismatch') + old_scope, next_table = cur[name] + if old_scope is not None: + error('duplicate_tables') + cur[name] = (scope, next_table) + + def merge_tables(scope, tables): + if scope is None: + scope = object_pairs_hook() + for k in tables: + if k in scope: + error('key_table_conflict') + v = tables[k] + if isinstance(v, list): + scope[k] = [merge_tables(sc, tbl) for sc, tbl in v] + else: + scope[k] = merge_tables(v[0], v[1]) + return scope + + return merge_tables(root, tables) + +class _Source: + def __init__(self, s, filename=None): + self.s = s + self._pos = (1, 1) + self._last = None + self._filename = filename + self.backtrack_stack = [] + + def last(self): + return self._last + + def pos(self): + return self._pos + + def fail(self): + return self._expect(None) + + def consume_dot(self): + if self.s: + self._last = self.s[0] + self.s = self[1:] + self._advance(self._last) + return self._last + return None + + def expect_dot(self): + return self._expect(self.consume_dot()) + + def consume_eof(self): + if not self.s: + self._last = '' + return True + return False + + def expect_eof(self): + return self._expect(self.consume_eof()) + + def consume(self, s): + if self.s.startswith(s): + self.s = self.s[len(s):] + self._last = s + self._advance(s) + return True + return False + + def expect(self, s): + return self._expect(self.consume(s)) + + def consume_re(self, re): + m = re.match(self.s) + if m: + self.s = self.s[len(m.group(0)):] + self._last = m + self._advance(m.group(0)) + return m + return None + + def expect_re(self, re): + return self._expect(self.consume_re(re)) + + def __enter__(self): + self.backtrack_stack.append((self.s, self._pos)) + + def __exit__(self, type, value, traceback): + if type is None: + self.backtrack_stack.pop() + else: + self.s, self._pos = self.backtrack_stack.pop() + return type == TomlError + + def commit(self): + self.backtrack_stack[-1] = (self.s, self._pos) + + def _expect(self, r): + if not r: + raise TomlError('msg', self._pos[0], self._pos[1], self._filename) + return r + + def _advance(self, s): + suffix_pos = s.rfind('\n') + if suffix_pos == -1: + self._pos = (self._pos[0], self._pos[1] + len(s)) + else: + self._pos = (self._pos[0] + s.count('\n'), len(s) - suffix_pos) + +_ews_re = re.compile(r'(?:[ \t]|#[^\n]*\n|#[^\n]*\Z|\n)*') +def _p_ews(s): + s.expect_re(_ews_re) + +_ws_re = re.compile(r'[ \t]*') +def _p_ws(s): + s.expect_re(_ws_re) + +_escapes = { 'b': '\b', 'n': '\n', 'r': '\r', 't': '\t', '"': '"', '\'': '\'', + '\\': '\\', '/': '/', 'f': '\f' } + +_basicstr_re = re.compile(r'[^"\\\000-\037]*') +_short_uni_re = re.compile(r'u([0-9a-fA-F]{4})') +_long_uni_re = re.compile(r'U([0-9a-fA-F]{8})') +_escapes_re = re.compile('[bnrt"\'\\\\/f]') +_newline_esc_re = re.compile('\n[ \t\n]*') +def _p_basicstr_content(s, content=_basicstr_re): + res = [] + while True: + res.append(s.expect_re(content).group(0)) + if not s.consume('\\'): + break + if s.consume_re(_newline_esc_re): + pass + elif s.consume_re(_short_uni_re) or s.consume_re(_long_uni_re): + res.append(_chr(int(s.last().group(1), 16))) + else: + s.expect_re(_escapes_re) + res.append(_escapes[s.last().group(0)]) + return ''.join(res) + +_key_re = re.compile(r'[0-9a-zA-Z-_]+') +def _p_key(s): + with s: + s.expect('"') + r = _p_basicstr_content(s, _basicstr_re) + s.expect('"') + return r + if s.consume('\''): + if s.consume('\'\''): + r = s.expect_re(_litstr_ml_re).group(0) + s.expect('\'\'\'') + else: + r = s.expect_re(_litstr_re).group(0) + s.expect('\'') + return r + return s.expect_re(_key_re).group(0) + +_float_re = re.compile(r'[+-]?(?:0|[1-9](?:_?\d)*)(?:\.\d(?:_?\d)*)?(?:[eE][+-]?(?:\d(?:_?\d)*))?') +_datetime_re = re.compile(r'(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))') + +_basicstr_ml_re = re.compile(r'(?:(?:|"|"")[^"\\\000-\011\013-\037])*') +_litstr_re = re.compile(r"[^'\000\010\012-\037]*") +_litstr_ml_re = re.compile(r"(?:(?:|'|'')(?:[^'\000-\010\013-\037]))*") +def _p_value(s, object_pairs_hook): + pos = s.pos() + + if s.consume('true'): + return 'bool', s.last(), True, pos + if s.consume('false'): + return 'bool', s.last(), False, pos + + if s.consume('"'): + if s.consume('""'): + r = _p_basicstr_content(s, _basicstr_ml_re) + s.expect('"""') + else: + r = _p_basicstr_content(s, _basicstr_re) + s.expect('"') + return 'str', r, r, pos + + if s.consume('\''): + if s.consume('\'\''): + r = s.expect_re(_litstr_ml_re).group(0) + s.expect('\'\'\'') + else: + r = s.expect_re(_litstr_re).group(0) + s.expect('\'') + return 'str', r, r, pos + + if s.consume_re(_datetime_re): + m = s.last() + s0 = m.group(0) + r = map(int, m.groups()[:6]) + if m.group(7): + micro = float(m.group(7)) + else: + micro = 0 + + if m.group(8): + g = int(m.group(8), 10) * 60 + int(m.group(9), 10) + tz = _TimeZone(datetime.timedelta(0, g * 60)) + else: + tz = _TimeZone(datetime.timedelta(0, 0)) + + y, m, d, H, M, S = r + dt = datetime.datetime(y, m, d, H, M, S, int(micro * 1000000), tz) + return 'datetime', s0, dt, pos + + if s.consume_re(_float_re): + m = s.last().group(0) + r = m.replace('_','') + if '.' in m or 'e' in m or 'E' in m: + return 'float', m, float(r), pos + else: + return 'int', m, int(r, 10), pos + + if s.consume('['): + items = [] + with s: + while True: + _p_ews(s) + items.append(_p_value(s, object_pairs_hook=object_pairs_hook)) + s.commit() + _p_ews(s) + s.expect(',') + s.commit() + _p_ews(s) + s.expect(']') + return 'array', None, items, pos + + if s.consume('{'): + _p_ws(s) + items = object_pairs_hook() + if not s.consume('}'): + k = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + items[k] = _p_value(s, object_pairs_hook=object_pairs_hook) + _p_ws(s) + while s.consume(','): + _p_ws(s) + k = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + items[k] = _p_value(s, object_pairs_hook=object_pairs_hook) + _p_ws(s) + s.expect('}') + return 'table', None, items, pos + + s.fail() + +def _p_stmt(s, object_pairs_hook): + pos = s.pos() + if s.consume( '['): + is_array = s.consume('[') + _p_ws(s) + keys = [_p_key(s)] + _p_ws(s) + while s.consume('.'): + _p_ws(s) + keys.append(_p_key(s)) + _p_ws(s) + s.expect(']') + if is_array: + s.expect(']') + return 'table_array' if is_array else 'table', keys, pos + + key = _p_key(s) + _p_ws(s) + s.expect('=') + _p_ws(s) + value = _p_value(s, object_pairs_hook=object_pairs_hook) + return 'kv', (key, value), pos + +_stmtsep_re = re.compile(r'(?:[ \t]*(?:#[^\n]*)?\n)+[ \t]*') +def _p_toml(s, object_pairs_hook): + stmts = [] + _p_ews(s) + with s: + stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook)) + while True: + s.commit() + s.expect_re(_stmtsep_re) + stmts.append(_p_stmt(s, object_pairs_hook=object_pairs_hook)) + _p_ews(s) + s.expect_eof() + return stmts + +class _TimeZone(datetime.tzinfo): + def __init__(self, offset): + self._offset = offset + + def utcoffset(self, dt): + return self._offset + + def dst(self, dt): + return None + + def tzname(self, dt): + m = self._offset.total_seconds() // 60 + if m < 0: + res = '-' + m = -m + else: + res = '+' + h = m // 60 + m = m - h * 60 + return '{}{:.02}{:.02}'.format(res, h, m) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/pytoml/writer.py b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/writer.py new file mode 100644 index 0000000..6eaf5d7 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/pytoml/writer.py @@ -0,0 +1,127 @@ +from __future__ import unicode_literals +import io, datetime, math, sys + +if sys.version_info[0] == 3: + long = int + unicode = str + + +def dumps(obj, sort_keys=False): + fout = io.StringIO() + dump(obj, fout, sort_keys=sort_keys) + return fout.getvalue() + + +_escapes = {'\n': 'n', '\r': 'r', '\\': '\\', '\t': 't', '\b': 'b', '\f': 'f', '"': '"'} + + +def _escape_string(s): + res = [] + start = 0 + + def flush(): + if start != i: + res.append(s[start:i]) + return i + 1 + + i = 0 + while i < len(s): + c = s[i] + if c in '"\\\n\r\t\b\f': + start = flush() + res.append('\\' + _escapes[c]) + elif ord(c) < 0x20: + start = flush() + res.append('\\u%04x' % ord(c)) + i += 1 + + flush() + return '"' + ''.join(res) + '"' + + +def _escape_id(s): + if any(not c.isalnum() and c not in '-_' for c in s): + return _escape_string(s) + return s + + +def _format_list(v): + return '[{0}]'.format(', '.join(_format_value(obj) for obj in v)) + +# Formula from: +# https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds +# Once support for py26 is dropped, this can be replaced by td.total_seconds() +def _total_seconds(td): + return ((td.microseconds + + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6) + +def _format_value(v): + if isinstance(v, bool): + return 'true' if v else 'false' + if isinstance(v, int) or isinstance(v, long): + return unicode(v) + if isinstance(v, float): + if math.isnan(v) or math.isinf(v): + raise ValueError("{0} is not a valid TOML value".format(v)) + else: + return repr(v) + elif isinstance(v, unicode) or isinstance(v, bytes): + return _escape_string(v) + elif isinstance(v, datetime.datetime): + offs = v.utcoffset() + offs = _total_seconds(offs) // 60 if offs is not None else 0 + + if offs == 0: + suffix = 'Z' + else: + if offs > 0: + suffix = '+' + else: + suffix = '-' + offs = -offs + suffix = '{0}{1:.02}{2:.02}'.format(suffix, offs // 60, offs % 60) + + if v.microsecond: + return v.strftime('%Y-%m-%dT%H:%M:%S.%f') + suffix + else: + return v.strftime('%Y-%m-%dT%H:%M:%S') + suffix + elif isinstance(v, list): + return _format_list(v) + else: + raise RuntimeError(v) + + +def dump(obj, fout, sort_keys=False): + tables = [((), obj, False)] + + while tables: + name, table, is_array = tables.pop() + if name: + section_name = '.'.join(_escape_id(c) for c in name) + if is_array: + fout.write('[[{0}]]\n'.format(section_name)) + else: + fout.write('[{0}]\n'.format(section_name)) + + table_keys = sorted(table.keys()) if sort_keys else table.keys() + new_tables = [] + has_kv = False + for k in table_keys: + v = table[k] + if isinstance(v, dict): + new_tables.append((name + (k,), v, False)) + elif isinstance(v, list) and v and all(isinstance(o, dict) for o in v): + new_tables.extend((name + (k,), d, True) for d in v) + elif v is None: + # based on mojombo's comment: https://github.com/toml-lang/toml/issues/146#issuecomment-25019344 + fout.write( + '#{} = null # To use: uncomment and replace null with value\n'.format(_escape_id(k))) + has_kv = True + else: + fout.write('{0} = {1}\n'.format(_escape_id(k), _format_value(v))) + has_kv = True + + tables.extend(reversed(new_tables)) + + if (name or has_kv) and tables: + fout.write('\n') diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py new file mode 100644 index 0000000..3f3f4f2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/__init__.py @@ -0,0 +1,138 @@ +# -*- coding: utf-8 -*- + +# __ +# /__) _ _ _ _ _/ _ +# / ( (- (/ (/ (- _) / _) +# / + +""" +Requests HTTP Library +~~~~~~~~~~~~~~~~~~~~~ + +Requests is an HTTP library, written in Python, for human beings. Basic GET +usage: + + >>> import requests + >>> r = requests.get('https://www.python.org') + >>> r.status_code + 200 + >>> 'Python is a programming language' in r.content + True + +... or POST: + + >>> payload = dict(key1='value1', key2='value2') + >>> r = requests.post('http://httpbin.org/post', data=payload) + >>> print(r.text) + { + ... + "form": { + "key2": "value2", + "key1": "value1" + }, + ... + } + +The other HTTP methods are supported - see `requests.api`. Full documentation +is at <http://python-requests.org>. + +:copyright: (c) 2017 by Kenneth Reitz. +:license: Apache 2.0, see LICENSE for more details. +""" + +from pip._vendor import urllib3 +from pip._vendor import chardet +import warnings +from .exceptions import RequestsDependencyWarning + + +def check_compatibility(urllib3_version, chardet_version): + urllib3_version = urllib3_version.split('.') + assert urllib3_version != ['dev'] # Verify urllib3 isn't installed from git. + + # Sometimes, urllib3 only reports its version as 16.1. + if len(urllib3_version) == 2: + urllib3_version.append('0') + + # Check urllib3 for compatibility. + major, minor, patch = urllib3_version # noqa: F811 + major, minor, patch = int(major), int(minor), int(patch) + # urllib3 >= 1.21.1, <= 1.23 + assert major == 1 + assert minor >= 21 + assert minor <= 23 + + # Check chardet for compatibility. + major, minor, patch = chardet_version.split('.')[:3] + major, minor, patch = int(major), int(minor), int(patch) + # chardet >= 3.0.2, < 3.1.0 + assert major == 3 + assert minor < 1 + assert patch >= 2 + + +def _check_cryptography(cryptography_version): + # cryptography < 1.3.4 + try: + cryptography_version = list(map(int, cryptography_version.split('.'))) + except ValueError: + return + + if cryptography_version < [1, 3, 4]: + warning = 'Old version of cryptography ({0}) may cause slowdown.'.format(cryptography_version) + warnings.warn(warning, RequestsDependencyWarning) + +# Check imported dependencies for compatibility. +try: + check_compatibility(urllib3.__version__, chardet.__version__) +except (AssertionError, ValueError): + warnings.warn("urllib3 ({0}) or chardet ({1}) doesn't match a supported " + "version!".format(urllib3.__version__, chardet.__version__), + RequestsDependencyWarning) + +# Attempt to enable urllib3's SNI support, if possible +from pip._internal.utils.compat import WINDOWS +if not WINDOWS: + try: + from pip._vendor.urllib3.contrib import pyopenssl + pyopenssl.inject_into_urllib3() + + # Check cryptography version + from cryptography import __version__ as cryptography_version + _check_cryptography(cryptography_version) + except ImportError: + pass + +# urllib3's DependencyWarnings should be silenced. +from pip._vendor.urllib3.exceptions import DependencyWarning +warnings.simplefilter('ignore', DependencyWarning) + +from .__version__ import __title__, __description__, __url__, __version__ +from .__version__ import __build__, __author__, __author_email__, __license__ +from .__version__ import __copyright__, __cake__ + +from . import utils +from . import packages +from .models import Request, Response, PreparedRequest +from .api import request, get, head, post, patch, put, delete, options +from .sessions import session, Session +from .status_codes import codes +from .exceptions import ( + RequestException, Timeout, URLRequired, + TooManyRedirects, HTTPError, ConnectionError, + FileModeWarning, ConnectTimeout, ReadTimeout +) + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +logging.getLogger(__name__).addHandler(NullHandler()) + +# FileModeWarnings go off per the default. +warnings.simplefilter('default', FileModeWarning, append=True) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..db44191c414da4af60403e4e1970024d4a9468a6 GIT binary patch literal 3744 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/__version__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..47aa3cbfbd1cdd703169114a7bcb5e42c4d3f168 GIT binary patch literal 507 zcmZ8eO-lnY5Y5(pY_}Fg52AR;NhsJ|TRf<U_;C>gDe5T*Vco=TbT=EbS*80Q{0D+p zy?OB0^r(NpvnOX;E9!(9-h0CfGs%9l=^zO5xN`n#A@p95NdQN?km)KEh6rL7u~><e z*c6#!Wm0ApQejn6Wi?V`HnCZq)R}XNT8*Kt`Ax=CljaM(fe90d56{ke_%hM>FpGVe zy7^LQjN0-%HR`t~1~<|DyxMg;n{G!~izSpdkGPcFg!qIDljrj>-@P6yx)4SNXHWS- z$Z^+Q%a;!lHPE6T8r)s$Y~VlkY#Nq%dw9YhkM}Paz;VkN)+sf@M4Zy$45f^xffmY$ zM1oMGG}94)2Bo)Lr(+cy7nz6{=nkcR1}kd7vp<-}zW8=UBH%JDE^ksAOlAXW1NE<= z@r-ma)~I~$c_vn#5~?j^YWyf_2X}pWWp36Bag;EKWQq1BZ|40P%~gY;y&Weki}+5Z M_`W$PW$XX>0%32U0RR91 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/_internal_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2bc6da6565dd3f3dd7fcb23129ee48df29b43b23 GIT binary patch literal 1265 zcmZ8h&5j&35VpH}eqyqtRm3R=<P%~fGK(U_VTGcEus{w(5gQ~lLhAIiYqy<r+a24z zlU@xRAnySjxp3kwc!R!j;uSbi<(@$hOZM2+<@)))&-2OAkzhF1KfU|y7a3!J(%~>t z+}y|MSGXv)W{Rt%=1sCrnsl8u**fD)-B6jDyyokPnyT4rww|i_Ia`YB--Lsg9r)l^ zxi$fuDeAlny7uDx{|zCYID4fPcuAji=;cLc%Al?BGE_y7g#%gQscS&VL#(=&n_hmk z&mp#zE-R^^1*4=j5?%!d4WQQrZ0QsWkQLM|I4|Gx9l94D<2G#(mf|mtO)k@6s(s$} zcZat&ovwp6xesngX_*wh)VfU2j|QPb^C8ZNP+&V2_>YM@-m&izb2}tX?%2=ij{m~( zEO4KV`(1(v@#{Z6*H>U<Au+l(m(p&YLmA$e4lWC)YVcm#3mN(r$QC+>coev69e6OI zAcW9ENE{KTeH?A@2-2X#6&!+(VZfADQLX|}Qm{X4D{v6Q7$`Aq;rf+)T4_w@33M+X zoIiZ@NOmR`6>N<VV+yy`9#-+<axw_*weg`aB{%}c5mLi6ri5V{vjHJImO0E1#SE$K z!mrHTME}3fPD0b3w7R_$gVpt&a(ii>hnF9cG0q%OQ`Vgv^mX!vzE*8N90!|^01$!L z@q%cg3~VC!G|BkQL?n)^B{5Hfe&;wNqaWesz^Gq@<Okj_h)soTqUw>sjD_rla365I zh?ex6eZy3S%ucR<{}fPfjW!_l1;VBg=zp2821SW-4h43&N4BgASCn|iuSCT2v_(Th z<jHQ|!RecUf|X?j<%^a4vhzW1;NTD=kSd5}V}pFshYGcFS3bjl&ql^h9ZBL;Zmg~2 z1vkN#pMLguIdN0mIs7|d!{UMW;7Dm_&ROSXWW4qD*wGoO3F3z(ALfTbBa!2BMDE9X z0CId<@eRF$){%?Zf+t+?j4!ymh1SPQ9?MwHhFP8~Tju#N9iM2F(<m&eEK(Qm{3jjp Y>tfFN$Bk884fk$PF6t*s-cH5wKZurVp8x;= literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/adapters.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ba1d03e65e85ca6401ac5f01172feffbb010dd02 GIT binary patch literal 16730 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/api.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1a6e3c5c2156ba381c7e25e1517d26643c668780 GIT binary patch literal 6456 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/auth.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d1de425b6bea3b181a728c0ce3a7ccb79238843f GIT binary patch literal 8301 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/certs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4538915b3d8c1d7dc282c8691662cd959bf86aa9 GIT binary patch literal 590 zcmY*Wy>1jS5VkjWaIy#uFEFBrIO($2(18#?5)x8G5mKFyEN4BtXR<rq_$T2Sgp^lE zPtD_`-4ZHZfeNp0Q!tW8Gb4ZB%s2D)@KCU1n;%D??>J+>$K>9M6ueH)A0?;RhH0*g zmUqRb;0zD+!A0So;tY!$cEdT-vrlX}kM9$WaCjNf2VYj`f*0TZGa=5l#zSXyY!MuW z=*UCZBJ>VxbPhFWtW|6Syn6#9g{e)Y0>XJD-C_x6TXYD<3rp<|EFt{*ew!)AxOTS7 z$pnR7RTrwkQiu;V>}&*;(EFmH22Q7GSAb<xuAsIK6r31}UqKrmoH>udSb|*d6eTV# zkgklg)FFjcCan}fwN=z$Zk{9<GJ9MN*W<*`mJsZuICb#YE0<)oJ26eDN5PXw@h7dF zE%`9d*kK`MrwmE?aXB9zN~vun<?y68eJQVyv~_vgX;p5#-1whVhw0C}cZR}G<`$`* z-QO4M(DmztJvQWnYTM)Lx}h)O^7&ZIZz5ga-*TOAS@yeO@p6B=SC12)e~{daKPndd EA1TYcc>n+a literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf851ab34d8ccdd01257c9200dedddc57d1224ba GIT binary patch literal 1600 zcmZuw&2rl|5GF;5q9{u8kNjJ^VH(E?n^;Qibf$+)r_*#g(}R=Fq$f;gI1~v<kO6`Q zAgAh~&(JsMxz`>#eTqH+u08n`a_WMlTc<TS`1tJtSbhuae%b5!7Ch*e<M01$Th?F3 zxOp5PU%-&R+m@AC$ja=jL2cGR4cl;sI>^D!qKR6#mDzh%*1TvSx8^P2?Q)feJnV{h zz+Kv5KJr-?by<J{)<ZqkM}0Ox1Ga|N*g9Hg8)&19-lm&u6K%2~8nP|4#kSEl+d(_! zoJV)r9@?u_?4x~%-Ju__19VXOe0s<Z(P7EE^h0(J-D4pN*?n}s^ab=I_5eMwEqsI? z!Z^l{&=G!&9^(jqjGs&$^wh9v1D)i5;P%h9_znKhqoe;RGV1@E(T&PJ9UGN*W;dYE z*e7VeRMVlSx0Ij#qdWlRrAqjBmp*?#i(2^+J_hxGpw*~<0$<QRwb4oDys@ISA1{4@ zFPB&<IZ8Pz66OE&{^R@K&4~;d&z2O2^CZtGmLXvU7b>i_kO`qgtwJItL<%QZy~Q{W zzg?+0&%@IY_V~4NHuA4c0Y$cMr}IQ)SiQP#faBVfQ`FI|%OzJ>x0iWE{PGhQbSZUE zJ1eWR6cpzv&#?AqSQUc*Krk#aWED?VMIxo%y=}!fzaoO?4ChL3|GVe5KWb?Y0vCyp z5Es}ouXr2yf|I<QmIWlNje-nMMKXhQ2IaDNu2d0IA{DsYa}H4`Fz<~LB%girI&!r4 zGNCk?P)PDTDGG4w{`pcFPi@17?rS(2fwQkjsv=+X;c&#jz?y+|104e`1FivRPfK_P zHUOfQ*fiX<ujm>G4D<jXdMD-lg5X6WqEB@@jx(OdvF;Y67{ymO&$tlgPP8LeaG+OM zNW$}&<WsJjus~>+$hcUY*55PTTu7d47tVu{$(^D~wRfnwGc}U|lt3Bnv`pkiGKAOe z%Tm1<nvAy0(r(Hr#i;_7QfwRdj)7eO6y3^dRE0bn6-j!L%&;8s>X_pU&ROi4SdLUe zcPC3i70F{`v?ePBg#{%^s%o1g5*o%_sCEdHQj>C^ttsV+(!G4iupnuyRt4<p!2&$P zqBes{0SGYl)vv9(1$EO@kJvXd0z;uC%{@uoAY2b_B{@na>93af%w%cc-HWke#TZgO zA-PmgU?=I@S-w!0&yBMj_05iN`h8qA@2FU5??u(#pPO5fUjsB7LBngiPT&L`&u!XI godY|tJs5#Kgt?|&y}s=?T>F`AW~+Bt&v~%=Z+P0tX#fBK literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/cookies.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b636da93a64943df2a7308f80e0c5730858650bb GIT binary patch literal 18709 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb1fd7e1b15c214ccbc1bb9e245ef226b4212ad1 GIT binary patch literal 5462 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/help.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f732d9fc893be2f64dee6cbfa751819c87bfb53f GIT binary patch literal 2654 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 M8SZ8Grfa$Se~a$h#{d8T literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/hooks.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..12854002e3879db8934f7acd9254cf970914773f GIT binary patch literal 954 zcmY*Y%Wl&^6rCB{c~}IAhhT%yED$1#IxH#{rK)&zfmA7#+6ttI%9(m5iHT!7Gt);Z zhfTWX7l0*8erLA)MK^F~nw0ih=X!kR&e6Tc_PbUqL=e62&p-bq2>r1StAJ<p2B4lo z;;4r>9^xM6gnJjLN4U=exO=>|kJ|O~-=P%KW1+N)Mny4J;n!Och6kfm(MiFNGeJvP zoTOYRsz-t*tYk-Nmg*FUK_MNvw-lpJjH;Q^ViJYn+Y^>%><Bd6#zq+S`%<W~$d%~# zH$n<=0HQ074n-~`(}L51EGCrErE(OS#;PcR0k6Y@)q8-t4@tw&oLnG{x6uMGFpTPT z6TB?84%u>L@d#3d4)4x!g@<TBJ|c{!gd;eDyT4GI7!tiSfjAMlmiDAem#;f|Qg+I; zTuXDMS(dFOr^Eb<o~~QcA%-Koke!vm9XEPZ&MupqcD%DvZrNs)RrS$1<zm2&GaX;m zZDvKnGPM<57eg;TPZMo|54*cN`~SPSS_L3uTDL^*t>h7wO;{&(Y#TLz57+^yJxCQU z8yYQ;wc!V@&`)evva3mjIbIO?0_*|q>{$h#9zL1-m0ytouDow}9#jD*<ED(NU{0pd zCsYyZ`1z~tRFzC8Bltp?d-K%xpB6cjGg{<84pVT6mZ?YtEe4b`%_7r?V;DV)<8IrN zb?DA`L!nK5#1zw7wrj>4i<t?WQKo5cu{~*O<5MPw%J`Ntp>xvh-0*5?)3P&H^4PlY z5E3FG4zUlY0q)=iT=D_%-L`M)am<S(j%5P~XQ$h`A?-d7r{CDT`en9SP^+BVxaKu# F{{R*{_|^ab literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/models.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..58645ed758deb1684705f9dfa23f824c3f623464 GIT binary patch literal 23921 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/packages.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..54b63e432993cce8fbced28be38182245a225e3f GIT binary patch literal 467 zcmYjMyH3ME5Ztq!*cgaHLzIRRDMjpplu?8bB}zjP$pTr%w<Jz3j&pY=kAlYHJAjfe z;9st#;uokm=Yd#hXZJ=syK`5^$1dmyUeE774S=umv5%^5E_I4$4HPJ05Wq5{#x>lJ z0zyqB4G0W0(I^O71t96d@&+pi<7z?lR4=g6Mq^@#KH6^%8q{jQJK-J89#FF&l)M;C z2;5SEb`#1<E9f?$3-itZ=Cy&odkd}VxAp-2mZ|KVGnPDDC@Z09r0jSUaf)(%lqH!L zK4D5{+*8C`pZzB|&T|w}cv%!rq9F>eb*N0S63X5&s=n1C4fl*2hRHOWaT$iH%4TuI zgtAy7q_U?onllv2)Qxh5jJOnwM2?inFjciY%{V?LOTA1Fd;mYu?l<t$^W`-2wYPSX wY8_+kcri@Ja^5M)P40f-?@jxErn8lDy4%}5qF0KV2B+c@ht$kEIVE-S3!^27`2YX_ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/sessions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9941b33031c7251587f297ae49238dd973d017d GIT binary patch literal 18526 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/status_codes.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..887d5faf9545e98c47ddce1aa49ef28305e6d513 GIT binary patch literal 4123 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 Rez&omJTYsqQ1J%G{|A4DEr0+3 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..474c25fdea92f2940474952eb5504944d3aa7427 GIT binary patch literal 4336 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 QK6RCvS^&>kcW?jhKNO=Hg8%>k literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/requests/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..48c20445c5f7165e11804e6c8e26b15e1b295374 GIT binary patch literal 21906 zcmch94Qw3Qec#UPCzljO@g$uj%krEoiCP`G`aGSE`nb~vb*DQWPe)N7x2L<+a^H|# za=-LuRwDP77st9dHW0@~(gIFkIF#EuuIr*jT_mj=1cjRdY2h?YfEMroEt0xGdq9!4 z4$uNBTKD(+znSHdr@J^sTT1(8-kUdX-u&PH`~QD)Vbi8;41a~+IB@5Otyt{GtVDlt zoV<je_cc2fQ?Wu!S<0?j1xt>0!IopZ5SL@3kdR}tkd$MpkdkA%kd|Ynkdb3wp-+z4 zLROCbg?<%RiRwUYpfF&?aGtDgstpzf<vdm0TpKD3$$7fEr8Zo6O3pJl-&)vO+g8|C z+g{jSd%Ey+ZAW28ZD(O;ZC7De?NfzM)pi$l*FIhNbZt*zPwg{>&(xfPQ+uZHOl@yr zuZ+=G{cLStVV|65tNUvQ3J2u8zdBMoSU6bA6>_yhg+sMx3(ul`pfKtVu8uv574mLo z;jr4YXn)nx2i2h3{6Va6L=CAeIDSeEtEX^0s<x_aI3823dRp!Hz$zS9JJl|<oKT-q zyK#I@eOm3o@ud2Ua&UZJJ)`#GcuIX%?Zfc}HLLck1GsZsji`fYIjwT)5RPZmvuYH_ zvuaG`aXhCEt0OqRsE(>*IKHHgs}ne$SI?=FI9_lss^=eCg-hy`dI9wbHLgzMcv+oM zXK{R4ol`I3_=<W-oyYNtx}YxN_^N9!yrwRxi4S79`>MLEUPkNdYEHePu3%o1>Q(g` zTHa9e>UA}VmTT$_bqy_VsyEdXj#KLT>UA~!$SO>`)9S|7Sm6eaH*vhFZmHYoaZA0W z3OL?YZ>u{vzU3xY3+f%*@wS}3i?chbsP5w0JF28+aC}#lmBO*8?CY^yrTtg3+P&9u zJ>Sc>{7Ti!zQ67-o1LDocuuXMT2<F+>c;(way^G#EB>-G+p3rSN~7*M{(Q-IO4@Z= zo~xV(6@R``cc#Ljv)!wus@Gtb*;dt=ZD_|`@?BjoRh=>hY1Nt>ET8?5R5baag)(Oa z{l(&aS9`cpETWn$yW00~GUPXk^^#w??-o5@SL$<U+uST^&n?dTezRDucz$kkki6Gw z_->GC>8e}|k~7P`>jiP#6!gELm8)HKsZ#cXbgORqX6IZV@48e$w*j6k7iX56CC>}8 z7^PJ=<78(_9stKD2b(H&-<@-H(O+)jrc}i%HkXeFJ9=*}y7l`N-Kf{xx*u#`d&Ii- z^y{T&)4a=5<wj$%;x3eQaaK2KMTI%y6`#6@$6l#>Zr!W!<vI0SBFJ8;-!D}w>c-U7 zU{iShid(|l1)DEds_yFz<=!gkI%m7>MqRrPDs@$wsk#>$YI#EIhR)gTRKD)|x*Vj6 z=9omM<HyQe2>zw;%iwnrKkvVwSl;Ew^blB4tZJ=Tbuy_~)n2h~#p+uVF+aYT)p;w% ze?+(2vE`E;Yc<ia7LqFd$X>Di6zb`YtrCyG5O;!9R^nkx(zL83!m%<KtKB<RC$2x} zB)l(j<W6F>Po*AND~YAsoy4WsJJ(i{ouo=H+WPOROeeOO#<36mlB-#jQCU12*Kyvj z2D;~)REFn%|LQ;|*@^l63!5Ir_1Adcy|3MpH^>c6Y69bO`}Fn3tp5NAf9Lf|SvNe? z?%V=I8xOoY7h76mjc*#Hy>kVqp#e|ly6gJ@zgOtLMx2_c6a0luQh5U?u0dOmt<&xF znQEh4s-6q1{B+yClMk#zZ99MHvGrnZP!HqrK?>`l-MJuL3{U#6)S3<L%Q^<>H=1t! zHFr7K^2%!yZxt`zn3|fHoG#wDJ~0)<fvCa2n=Mx_-z-&I?!*$hUpMz9y(XwSNNcxQ zEtTEC)^3ojmHhI2U|q?jg2a3S=)M;dC=3zb`BH1|B&Z&}lT@O23KF0<|8K_hQQZ3Y z^kKi&Jlw1_$0~KtFIB5!<p*>11^?a&Hp&n54oK?55o<autSR4I4z|g_AvG2O0?@c# z9>ciaDHJiwwh~s>9<T<jlx<rXlo@NlPN9w#)Dy|9oy8Gn)`0vQ!nr<<d%I}P6^7I{ zXub<4e(YgP5BgRI2zou{+vccn4x0J(Dc5i5x-+d??x<6l1uJwNLdx;x8?CBxW?aW` z4_D>0SttCvIPaDhJ+joLWycFK!<j4LZtx?A6fYz7Fbx^qYr5siY{gZh-J!ro`OF9! z`R;|uTwHI({Pj~T_>MVCALcn%!W74NHi%*xKaUh1O94=}w5<aPRT`oE?Ktsc9jG)9 zZ9UwHty+&_E2s-N4jXWIPO0t~BmsB#C<y9h*C7uBBQNP?r`1#?-^~ZfitpCEoE@a+ zOJ2$MwLXFI!RRctVVc1ZZ!d!FN8{Z^Pc!E@7S-0zqu!l!0+l}eWX>nBs4BJs^$T2w zbGI?~-DXL_xn`s-j<$R!wm@EXO<EFYd4G8T?`Y#4<KRWx$=4PV;6??*joymY_uY>9 z$<<UR{>WNL;~C%{3mNd7_x(Qbn3UiD$hHi`(hsTl?2r)$FrtkS_hH0M{@|>QF~4ud z?0}Ch_UYg1V73_lU5w8;XUyGlH6!C3z|1y->-O;pIOmu^)78x#yZIAkJ+iDAp0H=_ z3Ak%}$VKs%7~8%b>yCE-(6M~*^N!WAcf=l2MaUYC2Ub(8x{$y@9ETt^3z1T91lCMx zKOh?kdIwABC>N}uR;dGviI$M;KDgl+`p^0EBK4shctBUtJD?4KCrZzmiXetpX}eCt z&=DUq4r+Sff<KN*FE+_@W?Z-KG{EZcASfF?bO|adu5+-Gck`lyG+MsgGcq&c%vMWt z(hqZDw_M&ax=m@>sX|aXe#78wxdHZF_BTvC?_60^Xq@BuBcqPjYLe;VN!2Q;T)VZ# zebO!nlC$*IO)F0}Sgi&L&vh3+B!9_m(a+(aUtlqgBCsosVCxNNLNc(cz{oW;oJKvc z8(xr{1-}G;_WUAY6eRc>K?YKYQr!y@Jkw-Y`V5O4hfH62L%6#>%UZlvT7t4*HG%=Z z0p`m!#i|5DWh1kS%?7oKMqTE!k^cHHG3YqBr-H$}mr%sOM-$+v!c}p!!BdC8bq5kz zT(MKB_<*zxCo|}?-L}D-Gl^kqtK5;W^;L{<xlC~IZvek8%>q$l%l}ObomdUDQiFCt zBLh<YRo{k`zp#>A-cD*<O{xUwFZl=<zmf_yhBWBu)ezU?)IOwVrUN}e@9v~l64zq) zcHe^TpyG=eU03Mi_mQ=)q*Zby<7cS@fc}5ElUW@Q?IP1jFKk*J>|`E+kL--C^g*Ao zJBf!D=&cV=&UUi;k2^5UcE<GYDywd*^h$px+v(pKLu+PdY!(z{=&=*`hlJvP5>dSV zv(Lv2J)*}hQ0x|em_0zTFyZ*mT;)7-eeKf`pCyfT>CbO9K^>)5NN6Qz4jN+Jf!1my zil}vY(P6-GlSa$iJV~YR8Z~D@mC1JU{lo7aS^0Ac!to$k^2(Kp<`U_1C~{Bf*LgmP zBIuu-n4Y>=ynN;A#C3h1Er}*%Sdev>nx(pes;|K;8X9UukbzEOG>w$I1i|fTDw9FB z0uBJohJ4U8sDqSp%f##yrUy+(A7bMmUkZGrQZD%o?dg}%sQ1a0^AH-9nU-&6pBo6` zc;8?^mntv?T&lKS&y2J3(nXo2H4ApuC_~e!1R2qOpiUSGxtl|$tBtuzy;#{u2!qhx zjf!04w7!MDM*oQ0){sqlu&wRZU;=aiDoDklZP=LvG!y(Af?hI+`VeSfI1Vi&zSYtS zBXk89Ax+^Wg6jfKg!#jN@GuVMZs~InTb54&b`GpNzB8s0i*Y$m;ylH3Llhm5!*!#$ zrrSrRHS8I3xjEQ-wAftXQuR`;%We&}G-ejS|G=+!$*}*&)|n4~ioeI!IVgf@yuL{4 zTbP_4V!@@?Qz(KA%_80j1dC%R?efxkg(Dc0ITS^TpzDv&#UnDr0I*$PA-an5E<n<# zB=Hk~d><!1Wb`W3Fi`Rk^$w}WS-%78W5r%N1~5&9y#NHyoWr&Vd%*1iJ0#w*=WNie zeQ)nABf;5sMn+7+E<tT2K?+~ZJfaQJkt>ktkg`dRzL4l7XCW(BG2SEV8}={9R#M?p z!DYPP>LeEWaeq?TU$$3LofIfH-u}HQqhCAqMqTItSnUuULo2!pv(Kqk7F{mUGNj6^ z3k46t$*H-u8Jt5lmYjB_DSBQ>m*+v_BJN~OX*-aEOSd{LY+Wk*5KHAob2*Z$eo12u zM;)5rRnL`?7Fy6*wNYk?98gVZ?JJp^151CtRG*^`OAYq1br`xN7d$txw)pxc8VtQA z78;d$kj6B*$RzS&be=9$nwQy_A)3%k4>HgJ!;Y92E2^S{bU683+MrfCeAysnAQ7aR zfKFwpkipP`OhFvRMPab}(n97Nk#B2wnG<TdO8R(zikW*3idb^MP9%n`VaTyzP%^0* zR16y4f#aa9+vw9pO|nQT&4QYFoKP)>I2oXIK)Urosear~%u<y+-~$yNTA#OI_=+u& zi<kZ>hL|p4wV^N@%EKA75tvL|b!ZDTDk{)N&_T2eyfi3`OA2kPB+Id;SLdA@b*LWD zJ<J{ThW~`SyjFRBG+OLZUB>8fg^W6Gel9<1td;TcHLK;^xpN{&ii_@Y5&i~ovK)N- z;0Wp?qs|DLMsn}uWIUot&zPUk>&c^z7~jgs+GxgNB|{%~>Mq{D)_}(e&ZW9@)WM@$ zsKC7h|4ezYJB23?{+`Tu+{}1o?Gc|mVHtE>)5$a5`)<-c*?tyFM0ms0p&n{hv&T2a zYsbb!Mti_%;hvOunkr9_m}xYsdW5IhwKvuMXn-}8l=s_+%3H)U)VmlK(8&|O^bn=a zFwLU(F~pNG_9a~T88Mc)oB|G?f_ae!1C04_tk50?4*$~sZ5+PRgYj#43a$vEplLug z$NNMqg_YO~mQTRGjo7;mb2bk1ad`8W8sw8P`!9h+p+6zQNP_481Qq)>prU>cXd#%W zJ3QOQf>wEu5T~l8SJ<*arf=Q=t6juIdKO}vBTN({{c~vPVq+YYu4uo5${Y;XC5UU{ z7F7JpD>mGN(0zWvh7xTf!eQ|&5sSy*+&c-)$JVdb6IQG~1g*$c=)vny;%zt*aW75a zdxKE(iK)qwjR%URE4T#qNqf~RLw^K2nOSzGE?;zx9XWXl&N}f_ILAU5!}^2U7wTuL zT7o4iE?|h%TCFtZxv0UHp~5jA(1jzi*sZ$s_IkisSr>{`!QmQ=&Pu&pZGlaQ&smKb zZs+A4=luF6JOyqfxu3Rl3AS#@JX!ieix@LQIA#dbA0{%i0=Z!9(0L=}YZaxcFpr%# z=@th7FxAL#g)ZBGq7D_iT3vQZv#{gkMPXe=P=GKgd0~eK4Gj;LXe#531dQJmsK7hp z7w5(GeAf}BLfrr2=8?DH%frj<mb6oARs9N07Qa&CWFYv;P#+=njCY$s2KWj@;%V5{ z;WVZJ$52x-Y#)6}czxVo(#jbxSK+K5ze`Zx4W$>wfSDd!!}%Q?@f(Y7ebm_-LQqEA z8;YE_%~i^^-peEJ7<o9|aLU@ny5rI2b=SOh>t^7T=CEj^jC&9(1O_3%6k;A-SVhs4 zh^mQIH6z!?<@Fe9Fp6Huppkj3(a6RPK*ra<y?IzDvH0fFFlns0Indi<Yi}+d3_}TG z;G_pO!PYPw63&m}z6GO<D_2+WERqKVDd-|t!yv)s-N+HPd}Pp*<OwwLV^1ew1s#Nr zHE8KyM7_%qX!&$G0@+W696@(E!t4t8LC1zVzE6S1JN6mSH&k$#<P0jn0Ep8W8F2!f zB@FindB$y(1kb33JOf4qcuFGV8MqH4#yMihF;b;>VUArRa0KKeWe0*~G}JemrHcMp zxCl{OKo1gzD@)u`HLw8D>zm8|JQQ{+aXr|ooU<Xuirdqy^}&(ZM&s;W!S~sUH@|lj z1gX#N1s{6=?^1-i#CB>a2UU*r!vW;!bW+O+J9uzjx$2<G3uzwA87&Bs3?mZh!!bv4 zqmDe5ZQTb$%`;>GQ4OR97r~`^BLoXwU?swdYG~viyE_Sk=cDwv?(HbE89jvO&LCV! ziz0V7Tp4#b;L6WVjeOGG|0mSQkwYf%G1Mr}7SKo1nk~}s*gD%okoxC=^B}L!;~=J# ze#nM|k-5LX)-SMdS!@u&A;EFvkZNy|;I^V`Y&!{#fe*MSgz#Wxe+lhf-y86J&Fw%@ z+==PiR1P6{K~7zv>%d=T>)S#=C)UUdL}%$ss3%p5<b>#3ocFKdjFB}Q`$(XO!ZA{i zZU2WGCfrKa9r90MF_29Mr|9qX5IF#~g{)Fo@H$>}H)miiZd}!X{Gfsza#_d++-_JH z*(Ur$&I1OiXEb7T7+fSDEaMi1ovefLL=$!StTmxGzK#)7hWAd_m>e>@Xz7i80BJ14 zinmRZ*UHig>zx!&8iIRw9$R;C*b8I&S@g)+hOPF)T#lS08x~p6VVTP+T7G6<av;4G zz9ebya?yD2V(vvnxaf{f3_8^ib*cq&I(xwaugiwK&T4-yaw-b#9yYR-*c8TWBq~*M zE=pkf)skK>smcrEYnLKh77Q*lx1pCXp6!X0To0-)DTMDY$PKY%mluM5bDM;}gOsUk z07>waV7%Buro%!>{|Z4QKBY8G_#s<=1z=c*?F7<A`~;E^Fbwc9=3%veum*^W(aRd? z{$$8}5+DEp_&3S(&D^Mt`Hc_&2DQuudBt((5_yS{GG+zDX%`M55~Dk%^-%0K3)%sr z7^nk8e+dWuWfmLQ#kP_{dI*^XRChB60PYb1M`jSq=&z#e;uIxw*DpDZijUBrf`8)? z!&`8}D|k8>+K02tl6s<B$CcHDf`eWH{P2D}0`|dWkK@y^PCPmT@Kfz-1bnfhL5Buq zLSJ?mPYRXY4S+YXrg3QU^q+{n)PsQQ$1}id|8;2gQJ~qxb?Dsfb~U*d(L*Cq7HZ6S z=Q6m3cp)lv<K+gWz&b!cNwipF2B?ZxZh6dLaqz$5d2m#G_SmtLC-crhVP0VfCyE$1 z>QujthTMQ#JfCYnbEXELYyQxS@WMeC@z1`!_s+;WhYseSeKE(=bMMecz!;a;ezx1! zfFtaCx_fWWUG07Ep1JelQmu-iqj!G7*l9h1_12eB1jCnH=;Ox8c+13|^e8W+VGcFn z*VFWa1?gEPm{h9>H{pWB0E28edqnPozNRkC)k-`~;rTdjM9*CxzYyOgj?(cQOCrh? zPr;i$WM$*Smi{%gbupG4vWv05j*5sQx^>|}r$}Synm%-+0on*Mt;E48fvGFWCDn<8 zTi&7Lmi>6t$2uvMLcjD10!ga~@L;UIPM^v^*nI)l5}iH@zg3IDsFidlg=_Jrp@a6c zW;&TpqLT*aJqFGT_cFsm2<dz)!utr@C`ZI55-!28>N-j=Qpl)3p^P$3;~{YfAL!Zz zCN{*eVU18Ee&jJ^1tF&o4OY1D94evk)AH#?p6vl3jZh<(m~6-Qjv)Kti)^KogYI$& zhagD;Yz7J9K`tAl%-n*Mm|RG#3Lh^iQ}E>SAxMoeN8w6^K~YR4;4ecZ<zf(rk|<)b zuo*+UOU1@)5y52SmVE?+LbIm#QK1U)kBLFMG0#{gi;#nfVlpd)F`5j#zuOsx_$ID* zv5DfMD>5#j(u+;rFcXm&nRyrnAr!(3iz$7AUJGCZlbjfhNp>u>zN8QgkQ}^pdnH=; zhyd5E@+;HR*PK_xoEFirp5qyydgHyB6;I%JPmsBhdeV*-VvOiE31T%IrfrYxWypHT zZ)dMue`D;_spno8I|`v32U!YWG${%V>2MPI8>s8wV6j2a?Chmv!%@R~e$*x8bk^n~ z3?N}=5I_B!7^f?(>0&1#m+|v73gnO(NBiC-WT1ddvs7wsB1(F12)SBxzSI4KUWnCV z0lo~uv*bw69f;|~SK}Ql2eZKRcqb|Mje{8D3t$D*U?IYIt!}PKs!zJT>$(rEvIdV4 z{kzm#fuQjGG<1H_sBcz~G6Baw#~fqR!jqBJKqi=pR+mZ)M(~1dfC`*IkR|XDm8xb` zt#9K_1lcmt*ny=*;}6nd52QfOx9W?CTHfCX=sj3f%&=&Bf~R^-Bv!h`R=vW9{u!aY zgHuDk4FAzVEJu_GN?Q7RxYmU_k-ZD`tEeb(t0{Xi<81}ov=$LbH-<S(^g|uVta)fH zLQuev#(H!h+{yR|U)G)ngT1#W%%zLBoht%9c*>#eJ6^R?22i2-lp^6STxJrQ3{xb4 zX(_T4Brpz0-za$@j--W+faoXmie^YAa~Y=tFpTM5gCKAH+k8{NL;m=t)D<t{=iNuq ztJ=^d=_9(hfJi^FOuxE3;4{Z3)j<&UIzZ$z*Wi^XlE0cUZbuWZUmlA33LYYQkN$n= z-wgX>9A+n|1cX4c{qG`XKszJUOW;|Ic=ZfI8_*wN*vNveX9ft1Ooc1nqkaR+qVC;c zs49o|P9rR=Lbt=wyc1HtQFg<p3TF`Be=P6JLZ-v#fN9WM7v>5&Yz*flLonnBc@avW z^#)P<uRT%a3U4>;A;R3Q^Wgut#ud`D{x*<dGM8P`fAp`QMYxmx7SE_-=)a007`R~; zMRFYU2W;w_22Yhbq~hOU%VuCOVvZ3r@bur}{ZHbTPlQL7xGZ98z$iY6IQb^iZU(I( zrXS#_{}IM)UpRl^;-!hpFTZl-)z_}RKKaJAH>a*o-?(|}_FIM0Oj)_JbMuvj#cHkI zXx`JF-@5-`X}Nvm=&|D`o;&&csTaob#rM1Pk;H)Ayqw=hWli)g{XHKX7D<s1d=G7K z;#IodJM;jAYSl^{SK|*Yan^r_y!TN|e`k5vPk=J8W#J)0qLSz9fHG2`4Bt?OpH|4J z+YV>`=c7!ugr9-%{2J6J^Mr&-lfS@(KphIz_f76vPs^^4wt)X+R{KnH1k|o?->8ov z1W*!PYuQ1DQyKg?YKl?~#fe^WZcJTaz%k5qM-na!JNTsq&q+E4@59tGSONDbCO{ie zN91r;tL_|J6Qmyc?$2Mpc;$*QSi-<z<mHYWMUkX_Z0$FGTXHRNAbdy_xV=A2_x`x4 zBg(no8<`B?bO|*x%}Bm5)gWDgo2A~W1@ZE{?uq$ON(6&9CZ{HlHhgp9Qt|r4w63Eu zmt=lTC7?3qdx2F6EaV55H=^)x<UMY6fpna>y9-0aQdu}Gm;hsg6N4K=-tV%9Z8$NA zTV1SM$Cbx%1@Z^Dwqk>)Qq=-xP<j8d;la$GM4Bi6Q6^FC;*~CE{qB@&0woffF{v(C z&WH^%Co%HCL*@05+rPdeYP!*yo5#w9ekJ#?xP6@Ra+x8FhF}3A7cCQ&_UZhTQ6-$h z*an0#eDFXo7<h8;$E|gH>ocF-xBtM%!Q7!|M-PvmKKtTJZ@=??`zf?;Y=n}L@Jh2T zvwhP5lE6@N{m}4Fa0s^WvN%tRA$A8_yG``8hOHadu%Ge=QKBN&`?anR%|K1FY-C6b zCiD+6d{<rI!@EMXib^Czp=?17Lqb1DmCOO20Hn%_r#`XP$4??F0wVSy?6a^hl5C8J z0VCiJ)7nYCL|Y7LH7~_rU!h#YGUpQQ|17q2cMU;y@bo#$jTT*WW#(HmlLD)E<r-2V zstr08aHWJ?0-v!gBy`T;)CjGKrBV%M{5U9=>D`{>cS|Nl6Mp%lFC5DsJ$WjBG=J0( zGGuIT>yg99P6#%L0mUL3<}%C_lhN@rjC15jUPf9cMwuoc4Q>1ERbz+M0PI{^)T0(Q zvZPE31nQ0QqU#5JNXGSx&{OM%{s&b9IW~$JY_*cNC{&NzZCGn@v|;;76P_XD-=HEV ziJ1yWomKXi69Q}_z6`T7a!-oLnL}T8DG_aqqY?>m)*hHzn%Q1m8prju1eyb=FxU&z zDYhea4hGVW*m-JSKm(syR^a=O5YiP*>E|z+PztsuVNyn6IlQ#Q^jicmxw1=3OZlGP zhJ^(#$c>=TV<*-~KU%0`&pnrqen+0H$W+Ooe)@Ai{keEd81sh?>TUbn6?p6a5T_yF z;q5EwKVTiXk>y3?#U%vn{~ApjK&bx+ZB4?AdUp(tU1{k;i=4kpVzjcC2MHUJmt=Y~ zJ3Y2QPPor-LRv21fFzK3d;62|=<+le1?Q{(C5j*^77VybpV799mF9+72AkoYt~BqT zD25CEUU!ufOm0L1u%-V5V|C}vRqoFFi>O5U18fOfe-2r^cn6rsAbm0k=mWibh)#v? zB3ZoP`1WGVdlkpTVnR<cA9i_%j~w9c2uOo8@VNH@;E`CMPSNQdqYefH^PBm2>Gn;5 z%1!Kual8s?KI9cJM5u$8D+=k{2B)BS*BeE%XXAcJSGa*EQo+L*YnM7TiBizwvJQC4 zwVMW+B@xfB`$p7q2~Cbg7ykO+q767Q7(zcJB>ivLb%UO`3F`nSeMJ>H%P(*hjC>u0 zWF@`PF_u8W=?>aG&=d8KF-n(V6UV64mGSfF&;?Ab#Xhld_J(<kfFxbEtaV~%Vr^tM z)0(4=4NGVe`Ww^TE}83RWA!XDo5Q}qJ5s9M{ukIKB(Ut+%z{9nfuA#iR&3;}xg(@m zrjWJV5kqj-nZp2Q<NZpb<(bgpsIy#gt7=r(F4l+6TMrgE<S!O$eP5W7xWL^3vc&B0 z7tA1BOvE(9c~E{c$~fw%2E$9();LE&dmhk2exljYr~d|O#>6*oVuCoE<W-7L3z;_= z^fju=#56Z9V?Q${!m+-=MU;SDhTf<F80I!|<r6Slv$p<^cu;rwxO8N#7xDA<0KLdM zKM)DaC6l!F-B5#QwqgOPF2VI->3>cK#|Kz!$W{}Yv$25$**4M-ju9HV`U^|#4l{5@ zk?IOp2wF7dGgDrX1@<|W#kRO<QwIr8n>te0FR=~sIkAw|--JiBALcO5AJO<vEgg_C z_rNoXUQoi(?)?CsR5{b%mQlWqWZW!RJ+|X~1qlOSasBL#*<~<3jf4Sz(}HZ6L2^8D zfA~)gtYo6}c@=*%HU+lV;U<|~98(Pd5jVB33LZojHu7|U5*mT?$nkFWX)*Jadq0^S zizWX!0`D?65;jTcI@f`=*&69Iu|d+LD%0o@!DUTCIuL#Izh^<z36j|G;cBp4>mxEX zbEaCV&8X73-yve4bF4jLHkL)Z;KJGF&8|W398Sy~lSr@)xm9<rWW@Y&B#-f-PVAjQ z$ts6lCT=iWF+6Kc3X*~k+4&<++B5dJ@5~&w-Yhlsxqrr)anMApeef@uTXfT7%hA7! zdmdY()9u7Kwi{f|ZI%rIVtI?AA~Gb%a5EkGgD@}A9w11OyP(Ok=vPx7QwD@MWZRnl zhqz!Qa0aP2MxOO)#<cZ+;yr!zM+zGc1|kp@krFL#Xl!5(GI9|zt}w`_hq^PLd6@U7 z45DnL<84oT`M*!_oWgCf4EF#q1P@l6*exzN>`sKR%)*FI;W&gq<@R_c!#y*DVBlNP ziaj!qac`IE4WL7+C$|@42aNm6wjQcr?R@JY%24E=@4<MdBwk{A*m~Jugg@(b9L56V zUU=UKvq=OJIS;)F1<t#`+z5oHjIUR=Itz?JNk1V7=);YrkV<Xq|ADja3$dL)VPo{Y zb*yHJ;p&iOF<4Exl)>ISN$FeQ9$^?0GzgGQV8dsN5DR-rNi9*%l|7eOfqcS#p*<4H z*-oFXxZiKXUjQvZ_5j_6-`Duw{`Pew>>>DC5)Odv?O*^D8rV)EdoK}^gO9RT=u1F? z*T=D$Ogh4{U~DD2HT2*KB*Pd@2=8&{e6Q0Ui{imXVHO;o8lBQfKm-&+MQ{=xh^r<J zGa1BT;<V%AhYz<?IKvT~g<6*WuPlVKq|8XUlq^_~4j&$Ehlf_5m0_7IiydZi&d?n9 zyfe(QLE#wi1VV;({uftOd{HSPHEjAgeaPH&%P<PtQnrqRJwD!SQk=%3Kx>yDk$1-N zlf@sv3DgQ;^sK#|T*z*}u^xYoP6UxJ8G+ah1W<E@;LR!_4UNekNIU|M*~qmcA4)s9 z-#fe?pAXP{Dh@6V8{cv`9InXWiZa{|bT>iqlulyOW!%>N>te4VM-m|Rmk5T^2d0u= zhw#Gdq}neSL<n`o2pW0J4t5*d244ONyZhyywms_5a+t%W1x5l8>h;}r{LtY;?d+oK zHpid_-gjXIXK!HAW9JEj_U7~DvfK2>CYX>;$9c*$1X<Wlb(7%=W#(zTiM*9KczU2A ztA7kvgUu00!nn;dgooI5(D=FLwxzR#3m24s>y(o}MgzU*phcUSKmFrO((`sPEteid zLJL-m4Ta;IEAi#6@DjobM97Q@eTkK%*)=C$6nNJNe0mNMh{d&VUmR49Rpc5yvMSgE zxOA<P<Oo!2uum|(Jlsj6j-7iLFSEj3c(j%Hg@SLH@vg<pIMMvzTF980!mro{kAT~P zdj}C=I>;K<v#<R-Mwf8Hd`u8AI0C<bQLWS$!!#kY$s1fSR3v0~>Q!7Hch2xb72}8V z`TSvc<bkvcO?U3xY2bJDtTddKEI#D>)qsVEd3En-c$3^kKYZ^^te>X0ecdhVIeRw? zv>kUw_O=tF&Y?3}V!9M9B9w($w3BDfp@Rf=b4dyINu1w^<_`OQfFjptwB00M*$Xy> z5do^b8eiFf4s2uv<ATf|uP^FV-usBf2KF*6(2J71WWX^Z+5z;9WfC?MdEk9Q(8`AM z5Qe5b2m{AB5i|A<)bwT`;A1PMuW|TuC_cmhYiP*|b+wE5c{F#Cum-J}PGo99)YkB` zvGFpck?02T0;Dz3d$cq0?W9VEt&--3R`{?Ml5)qCO7q%k%4c2x1Q+rGY&|cZp0Keq z&(>d;@hqgsAtnrGwynQF{S>YJc+Ohu*Qv2mcSnyO_ROIV^?#r?MR#!C2qvMA8idRz zQf_W<TgPM~&NulX-@Bb^`LkokkLfLdQ@f9qQ)6Cb&g7%X#iJ+1RBb2aqUm$=<QR6I z5kI>1s%uV<AH${YY1M_3`Mc;B3|x5Q_2P}`%g2uuuTJ#VE=&ZO@Y<<v`_YrVy->R_ zq5qV_B#ZSHc1`1pBsd%kkH--UOyKhYCAhf6O&9d>vN5bT;8eKPaKXd(WAH||iBB}U zV`=VGPQU@3fO%{L78x1q_`xO3t2CcAZL6-jLIF!pr(h7(I-`F*wC|*tJwk@Gl7f8` z_x2%75eJJx8}}w)yCG~Ru$A;|O2mQH{?5y?J(ppHtB_;xS}`{s@}CDLGfEPFDO3lL zR|MjMx+@~jIIxX)H>pgQq7=w(P>wfnt5`Syf@#<oOnC{5mO75v--kS3I7OlUwit-s zVD3cd1C>uyi_LiBT*hb<*h>4LXl9`QC))K}ET&ipwI{K|UoQulS!ViR=#Au#&*RAZ zgkuydvv3=_*mAhUMdIUPsqIMcf#JKCOMsvJ;p$p6>H;dErf9(r1R`EQJV}m-In5$k z0A9bFejuMjn$>4QgAoK8a(sHn?Dl)nVsN*#K&ofUF>|+=-UPs5KL>UmnQfH>W;c!7 zB-n(RGgKXDw2U&808i*fNB=<pb`(F8bPedz7?J|Inn0S`5cITg9GE2GK>BU=q=^I3 zEo%6GXU_y@yAi@$sEqT1iK^nwzC_S+=vXQvjv*ufU}GXc>v3t{y>tETckk#s^>+^K z>%6<Ky?H}JcMZr)x)H%yR5~$8R=^Z%VM7D5^$s88P)7<N<oPbhb7<u-_D^67B-Y48 z^{_IBurl<|-8HMi4U&xI`S>ajR&QPOPj<d1+W!i!I(`9#;TcejQAonPb9ie&Es`XF zY~M<G9&Q`gtB;tkIUw&zSR+68K+O?7kR}M9EC@n}9{Qf>br{71l41`%RB!}jnZ^eE zlu^P5SL)m?4g81*$Jhks>bTje2I~PIr~uuCe#C=<8D`F55_9|cD2its&};MH+@cwq z$zrf*`2Ak{+)df}NQ)z!(tG=n5VYT0!S)*Lm&2Y>x-ywd2FP$U$&MTq2D9Ir1U28n z`k76LJBk;tPMn`CzA|zC(!^A8YU1UI+r<lSO-}?*Kk3T#=_x(Nn|HDxP9kLpPl6%x zb+(9hEgMDR*x|epJGV(tCKC716e<cEe!f8r6%SZC19?wl0v<4MVo6YWwwDo*4|jR- zWmF6!04D|_M!dLVdwaRn+hq44>y#25IjhXd0=f#i8Q!cCA!kmuZ^;t(as-orU{*2Y zXORz5KDYoB;kOCMD1ZSU$3`DpFNqj6`QW5^5HZOeJ89$t1X>tu+7R{=n5uRF0R0S$ z4T5eHs2f^3=0<}59-$}-dTMK&EEEaQ_!ie16QwZk67XGA2s;|u(RT*mX7AI}{Myk1 z_Ai5=r<Vsony5XLV8gvTAYH`lgsEN&$v3TVmErn(cW%e(8HDg*`g|T^g2g7=v#%r5 zN4`4XG_gG#DIzA51b$xxm_UK}_6m2LV<#83+JQo&&ymP#;L~xv+o18u7Q8BG0T73m zx5AIM7(poCI+<*rK9BA1+%4=h%JO{^e3;HSjPcbhVE~~4=FH$5XkxN=$7w%%Lq5+% zm$dm-8V=@zH6QH^3aW4kv4dAF3o!+QMV_yHPGt+On{QU+c=jn2u;zv+0I>s4AyZ2R z5BlUbej;Y$@*)_^Y0J33$HkScm5D)#qBEmuD6WrVfpgYn`OmZ|_(o&7yZm;KYLtsb zqnKqSt7pltR%Y~zoXmL^qb&ZA#UG%+*YTD;O(&sAd};6u4-L%&GXG#R!hBdkWVb=D z!lwgulC4N?tC7@c6PrCOBv2#Kh;AldhMSr-rI5IjjMI*YZ$2g=z#3-tDHh}fvImuk z#Il7zGTVbJ*jZ>ciwVn*j?ml%33?L$He88Dxd2?hiL)Rn+cSghNR2sv<LY$r;`!o* z8<Ur=P86@5pMC{m7KSz1w0tj1z9=Q%sL_hUR9UoHywBouEPj#2msmVx@f8+dW$|k) zzRBV@S$vPhZ?j-}PS6JfuZ?5@Bvbx?jla+0hb(@?;*VJT35y@22nNGNtCi}o1hw&X zia(CNG;y*R3!X-}7(vKHlx^sG2U~Ws;Er5TW<{M6p|5|Hw~z3`K^A1M!Y2fmdT{V4 z`-v+ca|YiX!sj5*aXGy&qM)+;gn#&!#{hrUr3A|zarBE1#4{tAflOcKZ1#92lW{UT zGrLiKHoG&kIn$rniu$(9a3-7CZ}Y<`J2Km)y+5;KaC_!lb|AAW+lTuPh<_=LJGW%E LAcHZEySDsqc=!7? literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py new file mode 100644 index 0000000..ef61ec0 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/__version__.py @@ -0,0 +1,14 @@ +# .-. .-. .-. . . .-. .-. .-. .-. +# |( |- |.| | | |- `-. | `-. +# ' ' `-' `-`.`-' `-' `-' ' `-' + +__title__ = 'requests' +__description__ = 'Python HTTP for Humans.' +__url__ = 'http://python-requests.org' +__version__ = '2.19.1' +__build__ = 0x021901 +__author__ = 'Kenneth Reitz' +__author_email__ = 'me@kennethreitz.org' +__license__ = 'Apache 2.0' +__copyright__ = 'Copyright 2018 Kenneth Reitz' +__cake__ = u'\u2728 \U0001f370 \u2728' diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py new file mode 100644 index 0000000..759d9a5 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/_internal_utils.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- + +""" +requests._internal_utils +~~~~~~~~~~~~~~ + +Provides utility functions that are consumed internally by Requests +which depend on extremely few external helpers (such as compat) +""" + +from .compat import is_py2, builtin_str, str + + +def to_native_string(string, encoding='ascii'): + """Given a string object, regardless of type, returns a representation of + that string in the native string type, encoding and decoding where + necessary. This assumes ASCII unless told otherwise. + """ + if isinstance(string, builtin_str): + out = string + else: + if is_py2: + out = string.encode(encoding) + else: + out = string.decode(encoding) + + return out + + +def unicode_is_ascii(u_string): + """Determine if unicode string only contains ASCII characters. + + :param str u_string: unicode string to check. Must be unicode + and not Python 2 `str`. + :rtype: bool + """ + assert isinstance(u_string, str) + try: + u_string.encode('ascii') + return True + except UnicodeEncodeError: + return False diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py new file mode 100644 index 0000000..f6f3f99 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/adapters.py @@ -0,0 +1,530 @@ +# -*- coding: utf-8 -*- + +""" +requests.adapters +~~~~~~~~~~~~~~~~~ + +This module contains the transport adapters that Requests uses to define +and maintain connections. +""" + +import os.path +import socket + +from pip._vendor.urllib3.poolmanager import PoolManager, proxy_from_url +from pip._vendor.urllib3.response import HTTPResponse +from pip._vendor.urllib3.util import parse_url +from pip._vendor.urllib3.util import Timeout as TimeoutSauce +from pip._vendor.urllib3.util.retry import Retry +from pip._vendor.urllib3.exceptions import ClosedPoolError +from pip._vendor.urllib3.exceptions import ConnectTimeoutError +from pip._vendor.urllib3.exceptions import HTTPError as _HTTPError +from pip._vendor.urllib3.exceptions import MaxRetryError +from pip._vendor.urllib3.exceptions import NewConnectionError +from pip._vendor.urllib3.exceptions import ProxyError as _ProxyError +from pip._vendor.urllib3.exceptions import ProtocolError +from pip._vendor.urllib3.exceptions import ReadTimeoutError +from pip._vendor.urllib3.exceptions import SSLError as _SSLError +from pip._vendor.urllib3.exceptions import ResponseError + +from .models import Response +from .compat import urlparse, basestring +from .utils import (DEFAULT_CA_BUNDLE_PATH, extract_zipped_paths, + get_encoding_from_headers, prepend_scheme_if_needed, + get_auth_from_url, urldefragauth, select_proxy) +from .structures import CaseInsensitiveDict +from .cookies import extract_cookies_to_jar +from .exceptions import (ConnectionError, ConnectTimeout, ReadTimeout, SSLError, + ProxyError, RetryError, InvalidSchema, InvalidProxyURL) +from .auth import _basic_auth_str + +try: + from pip._vendor.urllib3.contrib.socks import SOCKSProxyManager +except ImportError: + def SOCKSProxyManager(*args, **kwargs): + raise InvalidSchema("Missing dependencies for SOCKS support.") + +DEFAULT_POOLBLOCK = False +DEFAULT_POOLSIZE = 10 +DEFAULT_RETRIES = 0 +DEFAULT_POOL_TIMEOUT = None + + +class BaseAdapter(object): + """The Base Transport Adapter""" + + def __init__(self): + super(BaseAdapter, self).__init__() + + def send(self, request, stream=False, timeout=None, verify=True, + cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + """ + raise NotImplementedError + + def close(self): + """Cleans up adapter specific items.""" + raise NotImplementedError + + +class HTTPAdapter(BaseAdapter): + """The built-in HTTP Adapter for urllib3. + + Provides a general-case interface for Requests sessions to contact HTTP and + HTTPS urls by implementing the Transport Adapter interface. This class will + usually be created by the :class:`Session <Session>` class under the + covers. + + :param pool_connections: The number of urllib3 connection pools to cache. + :param pool_maxsize: The maximum number of connections to save in the pool. + :param max_retries: The maximum number of retries each connection + should attempt. Note, this applies only to failed DNS lookups, socket + connections and connection timeouts, never to requests where data has + made it to the server. By default, Requests does not retry failed + connections. If you need granular control over the conditions under + which we retry a request, import urllib3's ``Retry`` class and pass + that instead. + :param pool_block: Whether the connection pool should block for connections. + + Usage:: + + >>> import requests + >>> s = requests.Session() + >>> a = requests.adapters.HTTPAdapter(max_retries=3) + >>> s.mount('http://', a) + """ + __attrs__ = ['max_retries', 'config', '_pool_connections', '_pool_maxsize', + '_pool_block'] + + def __init__(self, pool_connections=DEFAULT_POOLSIZE, + pool_maxsize=DEFAULT_POOLSIZE, max_retries=DEFAULT_RETRIES, + pool_block=DEFAULT_POOLBLOCK): + if max_retries == DEFAULT_RETRIES: + self.max_retries = Retry(0, read=False) + else: + self.max_retries = Retry.from_int(max_retries) + self.config = {} + self.proxy_manager = {} + + super(HTTPAdapter, self).__init__() + + self._pool_connections = pool_connections + self._pool_maxsize = pool_maxsize + self._pool_block = pool_block + + self.init_poolmanager(pool_connections, pool_maxsize, block=pool_block) + + def __getstate__(self): + return dict((attr, getattr(self, attr, None)) for attr in + self.__attrs__) + + def __setstate__(self, state): + # Can't handle by adding 'proxy_manager' to self.__attrs__ because + # self.poolmanager uses a lambda function, which isn't pickleable. + self.proxy_manager = {} + self.config = {} + + for attr, value in state.items(): + setattr(self, attr, value) + + self.init_poolmanager(self._pool_connections, self._pool_maxsize, + block=self._pool_block) + + def init_poolmanager(self, connections, maxsize, block=DEFAULT_POOLBLOCK, **pool_kwargs): + """Initializes a urllib3 PoolManager. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param connections: The number of urllib3 connection pools to cache. + :param maxsize: The maximum number of connections to save in the pool. + :param block: Block when no free connections are available. + :param pool_kwargs: Extra keyword arguments used to initialize the Pool Manager. + """ + # save these values for pickling + self._pool_connections = connections + self._pool_maxsize = maxsize + self._pool_block = block + + self.poolmanager = PoolManager(num_pools=connections, maxsize=maxsize, + block=block, strict=True, **pool_kwargs) + + def proxy_manager_for(self, proxy, **proxy_kwargs): + """Return urllib3 ProxyManager for the given proxy. + + This method should not be called from user code, and is only + exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxy: The proxy to return a urllib3 ProxyManager for. + :param proxy_kwargs: Extra keyword arguments used to configure the Proxy Manager. + :returns: ProxyManager + :rtype: urllib3.ProxyManager + """ + if proxy in self.proxy_manager: + manager = self.proxy_manager[proxy] + elif proxy.lower().startswith('socks'): + username, password = get_auth_from_url(proxy) + manager = self.proxy_manager[proxy] = SOCKSProxyManager( + proxy, + username=username, + password=password, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs + ) + else: + proxy_headers = self.proxy_headers(proxy) + manager = self.proxy_manager[proxy] = proxy_from_url( + proxy, + proxy_headers=proxy_headers, + num_pools=self._pool_connections, + maxsize=self._pool_maxsize, + block=self._pool_block, + **proxy_kwargs) + + return manager + + def cert_verify(self, conn, url, verify, cert): + """Verify a SSL certificate. This method should not be called from user + code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param conn: The urllib3 connection object associated with the cert. + :param url: The requested URL. + :param verify: Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use + :param cert: The SSL certificate to verify. + """ + if url.lower().startswith('https') and verify: + + cert_loc = None + + # Allow self-specified cert location. + if verify is not True: + cert_loc = verify + + if not cert_loc: + cert_loc = extract_zipped_paths(DEFAULT_CA_BUNDLE_PATH) + + if not cert_loc or not os.path.exists(cert_loc): + raise IOError("Could not find a suitable TLS CA certificate bundle, " + "invalid path: {0}".format(cert_loc)) + + conn.cert_reqs = 'CERT_REQUIRED' + + if not os.path.isdir(cert_loc): + conn.ca_certs = cert_loc + else: + conn.ca_cert_dir = cert_loc + else: + conn.cert_reqs = 'CERT_NONE' + conn.ca_certs = None + conn.ca_cert_dir = None + + if cert: + if not isinstance(cert, basestring): + conn.cert_file = cert[0] + conn.key_file = cert[1] + else: + conn.cert_file = cert + conn.key_file = None + if conn.cert_file and not os.path.exists(conn.cert_file): + raise IOError("Could not find the TLS certificate file, " + "invalid path: {0}".format(conn.cert_file)) + if conn.key_file and not os.path.exists(conn.key_file): + raise IOError("Could not find the TLS key file, " + "invalid path: {0}".format(conn.key_file)) + + def build_response(self, req, resp): + """Builds a :class:`Response <requests.Response>` object from a urllib3 + response. This should not be called from user code, and is only exposed + for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>` + + :param req: The :class:`PreparedRequest <PreparedRequest>` used to generate the response. + :param resp: The urllib3 response object. + :rtype: requests.Response + """ + response = Response() + + # Fallback to None if there's no status_code, for whatever reason. + response.status_code = getattr(resp, 'status', None) + + # Make headers case-insensitive. + response.headers = CaseInsensitiveDict(getattr(resp, 'headers', {})) + + # Set encoding. + response.encoding = get_encoding_from_headers(response.headers) + response.raw = resp + response.reason = response.raw.reason + + if isinstance(req.url, bytes): + response.url = req.url.decode('utf-8') + else: + response.url = req.url + + # Add new cookies from the server. + extract_cookies_to_jar(response.cookies, req, resp) + + # Give the Response some context. + response.request = req + response.connection = self + + return response + + def get_connection(self, url, proxies=None): + """Returns a urllib3 connection for the given URL. This should not be + called from user code, and is only exposed for use when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param url: The URL to connect to. + :param proxies: (optional) A Requests-style dictionary of proxies used on this request. + :rtype: urllib3.ConnectionPool + """ + proxy = select_proxy(url, proxies) + + if proxy: + proxy = prepend_scheme_if_needed(proxy, 'http') + proxy_url = parse_url(proxy) + if not proxy_url.host: + raise InvalidProxyURL("Please check proxy URL. It is malformed" + " and could be missing the host.") + proxy_manager = self.proxy_manager_for(proxy) + conn = proxy_manager.connection_from_url(url) + else: + # Only scheme should be lower case + parsed = urlparse(url) + url = parsed.geturl() + conn = self.poolmanager.connection_from_url(url) + + return conn + + def close(self): + """Disposes of any internal state. + + Currently, this closes the PoolManager and any active ProxyManager, + which closes any pooled connections. + """ + self.poolmanager.clear() + for proxy in self.proxy_manager.values(): + proxy.clear() + + def request_url(self, request, proxies): + """Obtain the url to use when making the final request. + + If the message is being sent through a HTTP proxy, the full URL has to + be used. Otherwise, we should only use the path portion of the URL. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs. + :rtype: str + """ + proxy = select_proxy(request.url, proxies) + scheme = urlparse(request.url).scheme + + is_proxied_http_request = (proxy and scheme != 'https') + using_socks_proxy = False + if proxy: + proxy_scheme = urlparse(proxy).scheme.lower() + using_socks_proxy = proxy_scheme.startswith('socks') + + url = request.path_url + if is_proxied_http_request and not using_socks_proxy: + url = urldefragauth(request.url) + + return url + + def add_headers(self, request, **kwargs): + """Add any headers needed by the connection. As of v2.0 this does + nothing by default, but is left for overriding by users that subclass + the :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param request: The :class:`PreparedRequest <PreparedRequest>` to add headers to. + :param kwargs: The keyword arguments from the call to send(). + """ + pass + + def proxy_headers(self, proxy): + """Returns a dictionary of the headers to add to any request sent + through a proxy. This works with urllib3 magic to ensure that they are + correctly sent to the proxy, rather than in a tunnelled request if + CONNECT is being used. + + This should not be called from user code, and is only exposed for use + when subclassing the + :class:`HTTPAdapter <requests.adapters.HTTPAdapter>`. + + :param proxies: The url of the proxy being used for this request. + :rtype: dict + """ + headers = {} + username, password = get_auth_from_url(proxy) + + if username: + headers['Proxy-Authorization'] = _basic_auth_str(username, + password) + + return headers + + def send(self, request, stream=False, timeout=None, verify=True, cert=None, proxies=None): + """Sends PreparedRequest object. Returns Response object. + + :param request: The :class:`PreparedRequest <PreparedRequest>` being sent. + :param stream: (optional) Whether to stream the request content. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple or urllib3 Timeout object + :param verify: (optional) Either a boolean, in which case it controls whether + we verify the server's TLS certificate, or a string, in which case it + must be a path to a CA bundle to use + :param cert: (optional) Any user-provided SSL certificate to be trusted. + :param proxies: (optional) The proxies dictionary to apply to the request. + :rtype: requests.Response + """ + + conn = self.get_connection(request.url, proxies) + + self.cert_verify(conn, request.url, verify, cert) + url = self.request_url(request, proxies) + self.add_headers(request, stream=stream, timeout=timeout, verify=verify, cert=cert, proxies=proxies) + + chunked = not (request.body is None or 'Content-Length' in request.headers) + + if isinstance(timeout, tuple): + try: + connect, read = timeout + timeout = TimeoutSauce(connect=connect, read=read) + except ValueError as e: + # this may raise a string formatting error. + err = ("Invalid timeout {0}. Pass a (connect, read) " + "timeout tuple, or a single float to set " + "both timeouts to the same value".format(timeout)) + raise ValueError(err) + elif isinstance(timeout, TimeoutSauce): + pass + else: + timeout = TimeoutSauce(connect=timeout, read=timeout) + + try: + if not chunked: + resp = conn.urlopen( + method=request.method, + url=url, + body=request.body, + headers=request.headers, + redirect=False, + assert_same_host=False, + preload_content=False, + decode_content=False, + retries=self.max_retries, + timeout=timeout + ) + + # Send the request. + else: + if hasattr(conn, 'proxy_pool'): + conn = conn.proxy_pool + + low_conn = conn._get_conn(timeout=DEFAULT_POOL_TIMEOUT) + + try: + low_conn.putrequest(request.method, + url, + skip_accept_encoding=True) + + for header, value in request.headers.items(): + low_conn.putheader(header, value) + + low_conn.endheaders() + + for i in request.body: + low_conn.send(hex(len(i))[2:].encode('utf-8')) + low_conn.send(b'\r\n') + low_conn.send(i) + low_conn.send(b'\r\n') + low_conn.send(b'0\r\n\r\n') + + # Receive the response from the server + try: + # For Python 2.7+ versions, use buffering of HTTP + # responses + r = low_conn.getresponse(buffering=True) + except TypeError: + # For compatibility with Python 2.6 versions and back + r = low_conn.getresponse() + + resp = HTTPResponse.from_httplib( + r, + pool=conn, + connection=low_conn, + preload_content=False, + decode_content=False + ) + except: + # If we hit any problems here, clean up the connection. + # Then, reraise so that we can handle the actual exception. + low_conn.close() + raise + + except (ProtocolError, socket.error) as err: + raise ConnectionError(err, request=request) + + except MaxRetryError as e: + if isinstance(e.reason, ConnectTimeoutError): + # TODO: Remove this in 3.0.0: see #2811 + if not isinstance(e.reason, NewConnectionError): + raise ConnectTimeout(e, request=request) + + if isinstance(e.reason, ResponseError): + raise RetryError(e, request=request) + + if isinstance(e.reason, _ProxyError): + raise ProxyError(e, request=request) + + if isinstance(e.reason, _SSLError): + # This branch is for urllib3 v1.22 and later. + raise SSLError(e, request=request) + + raise ConnectionError(e, request=request) + + except ClosedPoolError as e: + raise ConnectionError(e, request=request) + + except _ProxyError as e: + raise ProxyError(e) + + except (_SSLError, _HTTPError) as e: + if isinstance(e, _SSLError): + # This branch is for urllib3 versions earlier than v1.22 + raise SSLError(e, request=request) + elif isinstance(e, ReadTimeoutError): + raise ReadTimeout(e, request=request) + else: + raise + + return self.build_response(request, resp) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/api.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/api.py new file mode 100644 index 0000000..a2cc84d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/api.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- + +""" +requests.api +~~~~~~~~~~~~ + +This module implements the Requests API. + +:copyright: (c) 2012 by Kenneth Reitz. +:license: Apache2, see LICENSE for more details. +""" + +from . import sessions + + +def request(method, url, **kwargs): + """Constructs and sends a :class:`Request <Request>`. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param data: (optional) Dictionary or list of tuples ``[(key, value)]`` (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) A JSON serializable Python object to send in the body of the :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the :class:`Request`. + :param files: (optional) Dictionary of ``'name': file-like-objects`` (or ``{'name': file-tuple}``) for multipart encoding upload. + ``file-tuple`` can be a 2-tuple ``('filename', fileobj)``, 3-tuple ``('filename', fileobj, 'content_type')`` + or a 4-tuple ``('filename', fileobj, 'content_type', custom_headers)``, where ``'content-type'`` is a string + defining the content type of the given file and ``custom_headers`` a dict-like object containing additional headers + to add for the file. + :param auth: (optional) Auth tuple to enable Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How many seconds to wait for the server to send data + before giving up, as a float, or a :ref:`(connect timeout, read + timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Boolean. Enable/disable GET/OPTIONS/POST/PUT/PATCH/DELETE/HEAD redirection. Defaults to ``True``. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol to the URL of the proxy. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param stream: (optional) if ``False``, the response content will be immediately downloaded. + :param cert: (optional) if String, path to ssl client cert file (.pem). If Tuple, ('cert', 'key') pair. + :return: :class:`Response <Response>` object + :rtype: requests.Response + + Usage:: + + >>> import requests + >>> req = requests.request('GET', 'http://httpbin.org/get') + <Response [200]> + """ + + # By using the 'with' statement we are sure the session is closed, thus we + # avoid leaving sockets open which can trigger a ResourceWarning in some + # cases, and look like a memory leak in others. + with sessions.Session() as session: + return session.request(method=method, url=url, **kwargs) + + +def get(url, params=None, **kwargs): + r"""Sends a GET request. + + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query string for the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('get', url, params=params, **kwargs) + + +def options(url, **kwargs): + r"""Sends an OPTIONS request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return request('options', url, **kwargs) + + +def head(url, **kwargs): + r"""Sends a HEAD request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return request('head', url, **kwargs) + + +def post(url, data=None, json=None, **kwargs): + r"""Sends a POST request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('post', url, data=data, json=json, **kwargs) + + +def put(url, data=None, **kwargs): + r"""Sends a PUT request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('put', url, data=data, **kwargs) + + +def patch(url, data=None, **kwargs): + r"""Sends a PATCH request. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary (will be form-encoded), bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json data to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('patch', url, data=data, **kwargs) + + +def delete(url, **kwargs): + r"""Sends a DELETE request. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :return: :class:`Response <Response>` object + :rtype: requests.Response + """ + + return request('delete', url, **kwargs) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/auth.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/auth.py new file mode 100644 index 0000000..4ae4594 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/auth.py @@ -0,0 +1,305 @@ +# -*- coding: utf-8 -*- + +""" +requests.auth +~~~~~~~~~~~~~ + +This module contains the authentication handlers for Requests. +""" + +import os +import re +import time +import hashlib +import threading +import warnings + +from base64 import b64encode + +from .compat import urlparse, str, basestring +from .cookies import extract_cookies_to_jar +from ._internal_utils import to_native_string +from .utils import parse_dict_header + +CONTENT_TYPE_FORM_URLENCODED = 'application/x-www-form-urlencoded' +CONTENT_TYPE_MULTI_PART = 'multipart/form-data' + + +def _basic_auth_str(username, password): + """Returns a Basic Auth string.""" + + # "I want us to put a big-ol' comment on top of it that + # says that this behaviour is dumb but we need to preserve + # it because people are relying on it." + # - Lukasa + # + # These are here solely to maintain backwards compatibility + # for things like ints. This will be removed in 3.0.0. + if not isinstance(username, basestring): + warnings.warn( + "Non-string usernames will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({0!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(username), + category=DeprecationWarning, + ) + username = str(username) + + if not isinstance(password, basestring): + warnings.warn( + "Non-string passwords will no longer be supported in Requests " + "3.0.0. Please convert the object you've passed in ({0!r}) to " + "a string or bytes object in the near future to avoid " + "problems.".format(password), + category=DeprecationWarning, + ) + password = str(password) + # -- End Removal -- + + if isinstance(username, str): + username = username.encode('latin1') + + if isinstance(password, str): + password = password.encode('latin1') + + authstr = 'Basic ' + to_native_string( + b64encode(b':'.join((username, password))).strip() + ) + + return authstr + + +class AuthBase(object): + """Base class that all auth implementations derive from""" + + def __call__(self, r): + raise NotImplementedError('Auth hooks must be callable.') + + +class HTTPBasicAuth(AuthBase): + """Attaches HTTP Basic Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other + + def __call__(self, r): + r.headers['Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPProxyAuth(HTTPBasicAuth): + """Attaches HTTP Proxy Authentication to a given Request object.""" + + def __call__(self, r): + r.headers['Proxy-Authorization'] = _basic_auth_str(self.username, self.password) + return r + + +class HTTPDigestAuth(AuthBase): + """Attaches HTTP Digest Authentication to the given Request object.""" + + def __init__(self, username, password): + self.username = username + self.password = password + # Keep state in per-thread local storage + self._thread_local = threading.local() + + def init_per_thread_state(self): + # Ensure state is initialized just once per-thread + if not hasattr(self._thread_local, 'init'): + self._thread_local.init = True + self._thread_local.last_nonce = '' + self._thread_local.nonce_count = 0 + self._thread_local.chal = {} + self._thread_local.pos = None + self._thread_local.num_401_calls = None + + def build_digest_header(self, method, url): + """ + :rtype: str + """ + + realm = self._thread_local.chal['realm'] + nonce = self._thread_local.chal['nonce'] + qop = self._thread_local.chal.get('qop') + algorithm = self._thread_local.chal.get('algorithm') + opaque = self._thread_local.chal.get('opaque') + hash_utf8 = None + + if algorithm is None: + _algorithm = 'MD5' + else: + _algorithm = algorithm.upper() + # lambdas assume digest modules are imported at the top level + if _algorithm == 'MD5' or _algorithm == 'MD5-SESS': + def md5_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.md5(x).hexdigest() + hash_utf8 = md5_utf8 + elif _algorithm == 'SHA': + def sha_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha1(x).hexdigest() + hash_utf8 = sha_utf8 + elif _algorithm == 'SHA-256': + def sha256_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha256(x).hexdigest() + hash_utf8 = sha256_utf8 + elif _algorithm == 'SHA-512': + def sha512_utf8(x): + if isinstance(x, str): + x = x.encode('utf-8') + return hashlib.sha512(x).hexdigest() + hash_utf8 = sha512_utf8 + + KD = lambda s, d: hash_utf8("%s:%s" % (s, d)) + + if hash_utf8 is None: + return None + + # XXX not implemented yet + entdig = None + p_parsed = urlparse(url) + #: path is request-uri defined in RFC 2616 which should not be empty + path = p_parsed.path or "/" + if p_parsed.query: + path += '?' + p_parsed.query + + A1 = '%s:%s:%s' % (self.username, realm, self.password) + A2 = '%s:%s' % (method, path) + + HA1 = hash_utf8(A1) + HA2 = hash_utf8(A2) + + if nonce == self._thread_local.last_nonce: + self._thread_local.nonce_count += 1 + else: + self._thread_local.nonce_count = 1 + ncvalue = '%08x' % self._thread_local.nonce_count + s = str(self._thread_local.nonce_count).encode('utf-8') + s += nonce.encode('utf-8') + s += time.ctime().encode('utf-8') + s += os.urandom(8) + + cnonce = (hashlib.sha1(s).hexdigest()[:16]) + if _algorithm == 'MD5-SESS': + HA1 = hash_utf8('%s:%s:%s' % (HA1, nonce, cnonce)) + + if not qop: + respdig = KD(HA1, "%s:%s" % (nonce, HA2)) + elif qop == 'auth' or 'auth' in qop.split(','): + noncebit = "%s:%s:%s:%s:%s" % ( + nonce, ncvalue, cnonce, 'auth', HA2 + ) + respdig = KD(HA1, noncebit) + else: + # XXX handle auth-int. + return None + + self._thread_local.last_nonce = nonce + + # XXX should the partial digests be encoded too? + base = 'username="%s", realm="%s", nonce="%s", uri="%s", ' \ + 'response="%s"' % (self.username, realm, nonce, path, respdig) + if opaque: + base += ', opaque="%s"' % opaque + if algorithm: + base += ', algorithm="%s"' % algorithm + if entdig: + base += ', digest="%s"' % entdig + if qop: + base += ', qop="auth", nc=%s, cnonce="%s"' % (ncvalue, cnonce) + + return 'Digest %s' % (base) + + def handle_redirect(self, r, **kwargs): + """Reset num_401_calls counter on redirects.""" + if r.is_redirect: + self._thread_local.num_401_calls = 1 + + def handle_401(self, r, **kwargs): + """ + Takes the given response and tries digest-auth, if needed. + + :rtype: requests.Response + """ + + # If response is not 4xx, do not auth + # See https://github.com/requests/requests/issues/3772 + if not 400 <= r.status_code < 500: + self._thread_local.num_401_calls = 1 + return r + + if self._thread_local.pos is not None: + # Rewind the file position indicator of the body to where + # it was to resend the request. + r.request.body.seek(self._thread_local.pos) + s_auth = r.headers.get('www-authenticate', '') + + if 'digest' in s_auth.lower() and self._thread_local.num_401_calls < 2: + + self._thread_local.num_401_calls += 1 + pat = re.compile(r'digest ', flags=re.IGNORECASE) + self._thread_local.chal = parse_dict_header(pat.sub('', s_auth, count=1)) + + # Consume content and release the original connection + # to allow our new request to reuse the same one. + r.content + r.close() + prep = r.request.copy() + extract_cookies_to_jar(prep._cookies, r.request, r.raw) + prep.prepare_cookies(prep._cookies) + + prep.headers['Authorization'] = self.build_digest_header( + prep.method, prep.url) + _r = r.connection.send(prep, **kwargs) + _r.history.append(r) + _r.request = prep + + return _r + + self._thread_local.num_401_calls = 1 + return r + + def __call__(self, r): + # Initialize per-thread state, if needed + self.init_per_thread_state() + # If we have a saved nonce, skip the 401 + if self._thread_local.last_nonce: + r.headers['Authorization'] = self.build_digest_header(r.method, r.url) + try: + self._thread_local.pos = r.body.tell() + except AttributeError: + # In the case of HTTPDigestAuth being reused and the body of + # the previous request was a file-like object, pos has the + # file position of the previous body. Ensure it's set to + # None. + self._thread_local.pos = None + r.register_hook('response', self.handle_401) + r.register_hook('response', self.handle_redirect) + self._thread_local.num_401_calls = 1 + + return r + + def __eq__(self, other): + return all([ + self.username == getattr(other, 'username', None), + self.password == getattr(other, 'password', None) + ]) + + def __ne__(self, other): + return not self == other diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/certs.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/certs.py new file mode 100644 index 0000000..06a594e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/certs.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +""" +requests.certs +~~~~~~~~~~~~~~ + +This module returns the preferred default CA certificate bundle. There is +only one — the one from the certifi package. + +If you are packaging Requests, e.g., for a Linux distribution or a managed +environment, you can change the definition of where() to return a separately +packaged CA bundle. +""" +from pip._vendor.certifi import where + +if __name__ == '__main__': + print(where()) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/compat.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/compat.py new file mode 100644 index 0000000..ec5d305 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/compat.py @@ -0,0 +1,75 @@ +# -*- coding: utf-8 -*- + +""" +requests.compat +~~~~~~~~~~~~~~~ + +This module handles import compatibility issues between Python 2 and +Python 3. +""" + +from pip._vendor import chardet + +import sys + +# ------- +# Pythons +# ------- + +# Syntax sugar. +_ver = sys.version_info + +#: Python 2.x? +is_py2 = (_ver[0] == 2) + +#: Python 3.x? +is_py3 = (_ver[0] == 3) + +# Note: We've patched out simplejson support in pip because it prevents +# upgrading simplejson on Windows. +# try: +# import simplejson as json +# except (ImportError, SyntaxError): +# # simplejson does not support Python 3.2, it throws a SyntaxError +# # because of u'...' Unicode literals. +import json + +# --------- +# Specifics +# --------- + +if is_py2: + from urllib import ( + quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, + proxy_bypass, proxy_bypass_environment, getproxies_environment) + from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag + from urllib2 import parse_http_list + import cookielib + from Cookie import Morsel + from StringIO import StringIO + from collections import Callable, Mapping, MutableMapping + + from pip._vendor.urllib3.packages.ordered_dict import OrderedDict + + builtin_str = str + bytes = str + str = unicode + basestring = basestring + numeric_types = (int, long, float) + integer_types = (int, long) + +elif is_py3: + from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag + from urllib.request import parse_http_list, getproxies, proxy_bypass, proxy_bypass_environment, getproxies_environment + from http import cookiejar as cookielib + from http.cookies import Morsel + from io import StringIO + from collections import OrderedDict + from collections.abc import Callable, Mapping, MutableMapping + + builtin_str = str + str = str + bytes = bytes + basestring = (str, bytes) + numeric_types = (int, float) + integer_types = (int,) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py new file mode 100644 index 0000000..50883a8 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/cookies.py @@ -0,0 +1,546 @@ +# -*- coding: utf-8 -*- + +""" +requests.cookies +~~~~~~~~~~~~~~~~ + +Compatibility code to be able to use `cookielib.CookieJar` with requests. + +requests.utils imports from here, so be careful with imports. +""" + +import copy +import time +import calendar + +from ._internal_utils import to_native_string +from .compat import cookielib, urlparse, urlunparse, Morsel, MutableMapping + +try: + import threading +except ImportError: + import dummy_threading as threading + + +class MockRequest(object): + """Wraps a `requests.Request` to mimic a `urllib2.Request`. + + The code in `cookielib.CookieJar` expects this interface in order to correctly + manage cookie policies, i.e., determine whether a cookie can be set, given the + domains of the request and the cookie. + + The original request object is read-only. The client is responsible for collecting + the new headers via `get_new_headers()` and interpreting them appropriately. You + probably want `get_cookie_header`, defined below. + """ + + def __init__(self, request): + self._r = request + self._new_headers = {} + self.type = urlparse(self._r.url).scheme + + def get_type(self): + return self.type + + def get_host(self): + return urlparse(self._r.url).netloc + + def get_origin_req_host(self): + return self.get_host() + + def get_full_url(self): + # Only return the response's URL if the user hadn't set the Host + # header + if not self._r.headers.get('Host'): + return self._r.url + # If they did set it, retrieve it and reconstruct the expected domain + host = to_native_string(self._r.headers['Host'], encoding='utf-8') + parsed = urlparse(self._r.url) + # Reconstruct the URL as we expect it + return urlunparse([ + parsed.scheme, host, parsed.path, parsed.params, parsed.query, + parsed.fragment + ]) + + def is_unverifiable(self): + return True + + def has_header(self, name): + return name in self._r.headers or name in self._new_headers + + def get_header(self, name, default=None): + return self._r.headers.get(name, self._new_headers.get(name, default)) + + def add_header(self, key, val): + """cookielib has no legitimate use for this method; add it back if you find one.""" + raise NotImplementedError("Cookie headers should be added with add_unredirected_header()") + + def add_unredirected_header(self, name, value): + self._new_headers[name] = value + + def get_new_headers(self): + return self._new_headers + + @property + def unverifiable(self): + return self.is_unverifiable() + + @property + def origin_req_host(self): + return self.get_origin_req_host() + + @property + def host(self): + return self.get_host() + + +class MockResponse(object): + """Wraps a `httplib.HTTPMessage` to mimic a `urllib.addinfourl`. + + ...what? Basically, expose the parsed HTTP headers from the server response + the way `cookielib` expects to see them. + """ + + def __init__(self, headers): + """Make a MockResponse for `cookielib` to read. + + :param headers: a httplib.HTTPMessage or analogous carrying the headers + """ + self._headers = headers + + def info(self): + return self._headers + + def getheaders(self, name): + self._headers.getheaders(name) + + +def extract_cookies_to_jar(jar, request, response): + """Extract the cookies from the response into a CookieJar. + + :param jar: cookielib.CookieJar (not necessarily a RequestsCookieJar) + :param request: our own requests.Request object + :param response: urllib3.HTTPResponse object + """ + if not (hasattr(response, '_original_response') and + response._original_response): + return + # the _original_response field is the wrapped httplib.HTTPResponse object, + req = MockRequest(request) + # pull out the HTTPMessage with the headers and put it in the mock: + res = MockResponse(response._original_response.msg) + jar.extract_cookies(res, req) + + +def get_cookie_header(jar, request): + """ + Produce an appropriate Cookie header string to be sent with `request`, or None. + + :rtype: str + """ + r = MockRequest(request) + jar.add_cookie_header(r) + return r.get_new_headers().get('Cookie') + + +def remove_cookie_by_name(cookiejar, name, domain=None, path=None): + """Unsets a cookie by name, by default over all domains and paths. + + Wraps CookieJar.clear(), is O(n). + """ + clearables = [] + for cookie in cookiejar: + if cookie.name != name: + continue + if domain is not None and domain != cookie.domain: + continue + if path is not None and path != cookie.path: + continue + clearables.append((cookie.domain, cookie.path, cookie.name)) + + for domain, path, name in clearables: + cookiejar.clear(domain, path, name) + + +class CookieConflictError(RuntimeError): + """There are two cookies that meet the criteria specified in the cookie jar. + Use .get and .set and include domain and path args in order to be more specific. + """ + + +class RequestsCookieJar(cookielib.CookieJar, MutableMapping): + """Compatibility class; is a cookielib.CookieJar, but exposes a dict + interface. + + This is the CookieJar we create by default for requests and sessions that + don't specify one, since some clients may expect response.cookies and + session.cookies to support dict operations. + + Requests does not use the dict interface internally; it's just for + compatibility with external client code. All requests code should work + out of the box with externally provided instances of ``CookieJar``, e.g. + ``LWPCookieJar`` and ``FileCookieJar``. + + Unlike a regular CookieJar, this class is pickleable. + + .. warning:: dictionary operations that are normally O(1) may be O(n). + """ + + def get(self, name, default=None, domain=None, path=None): + """Dict-like get() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + + .. warning:: operation is O(n), not O(1). + """ + try: + return self._find_no_duplicates(name, domain, path) + except KeyError: + return default + + def set(self, name, value, **kwargs): + """Dict-like set() that also supports optional domain and path args in + order to resolve naming collisions from using one cookie jar over + multiple domains. + """ + # support client code that unsets cookies by assignment of a None value: + if value is None: + remove_cookie_by_name(self, name, domain=kwargs.get('domain'), path=kwargs.get('path')) + return + + if isinstance(value, Morsel): + c = morsel_to_cookie(value) + else: + c = create_cookie(name, value, **kwargs) + self.set_cookie(c) + return c + + def iterkeys(self): + """Dict-like iterkeys() that returns an iterator of names of cookies + from the jar. + + .. seealso:: itervalues() and iteritems(). + """ + for cookie in iter(self): + yield cookie.name + + def keys(self): + """Dict-like keys() that returns a list of names of cookies from the + jar. + + .. seealso:: values() and items(). + """ + return list(self.iterkeys()) + + def itervalues(self): + """Dict-like itervalues() that returns an iterator of values of cookies + from the jar. + + .. seealso:: iterkeys() and iteritems(). + """ + for cookie in iter(self): + yield cookie.value + + def values(self): + """Dict-like values() that returns a list of values of cookies from the + jar. + + .. seealso:: keys() and items(). + """ + return list(self.itervalues()) + + def iteritems(self): + """Dict-like iteritems() that returns an iterator of name-value tuples + from the jar. + + .. seealso:: iterkeys() and itervalues(). + """ + for cookie in iter(self): + yield cookie.name, cookie.value + + def items(self): + """Dict-like items() that returns a list of name-value tuples from the + jar. Allows client-code to call ``dict(RequestsCookieJar)`` and get a + vanilla python dict of key value pairs. + + .. seealso:: keys() and values(). + """ + return list(self.iteritems()) + + def list_domains(self): + """Utility method to list all the domains in the jar.""" + domains = [] + for cookie in iter(self): + if cookie.domain not in domains: + domains.append(cookie.domain) + return domains + + def list_paths(self): + """Utility method to list all the paths in the jar.""" + paths = [] + for cookie in iter(self): + if cookie.path not in paths: + paths.append(cookie.path) + return paths + + def multiple_domains(self): + """Returns True if there are multiple domains in the jar. + Returns False otherwise. + + :rtype: bool + """ + domains = [] + for cookie in iter(self): + if cookie.domain is not None and cookie.domain in domains: + return True + domains.append(cookie.domain) + return False # there is only one domain in jar + + def get_dict(self, domain=None, path=None): + """Takes as an argument an optional domain and path and returns a plain + old Python dict of name-value pairs of cookies that meet the + requirements. + + :rtype: dict + """ + dictionary = {} + for cookie in iter(self): + if ( + (domain is None or cookie.domain == domain) and + (path is None or cookie.path == path) + ): + dictionary[cookie.name] = cookie.value + return dictionary + + def __contains__(self, name): + try: + return super(RequestsCookieJar, self).__contains__(name) + except CookieConflictError: + return True + + def __getitem__(self, name): + """Dict-like __getitem__() for compatibility with client code. Throws + exception if there are more than one cookie with name. In that case, + use the more explicit get() method instead. + + .. warning:: operation is O(n), not O(1). + """ + return self._find_no_duplicates(name) + + def __setitem__(self, name, value): + """Dict-like __setitem__ for compatibility with client code. Throws + exception if there is already a cookie of that name in the jar. In that + case, use the more explicit set() method instead. + """ + self.set(name, value) + + def __delitem__(self, name): + """Deletes a cookie given a name. Wraps ``cookielib.CookieJar``'s + ``remove_cookie_by_name()``. + """ + remove_cookie_by_name(self, name) + + def set_cookie(self, cookie, *args, **kwargs): + if hasattr(cookie.value, 'startswith') and cookie.value.startswith('"') and cookie.value.endswith('"'): + cookie.value = cookie.value.replace('\\"', '') + return super(RequestsCookieJar, self).set_cookie(cookie, *args, **kwargs) + + def update(self, other): + """Updates this jar with cookies from another CookieJar or dict-like""" + if isinstance(other, cookielib.CookieJar): + for cookie in other: + self.set_cookie(copy.copy(cookie)) + else: + super(RequestsCookieJar, self).update(other) + + def _find(self, name, domain=None, path=None): + """Requests uses this method internally to get cookie values. + + If there are conflicting cookies, _find arbitrarily chooses one. + See _find_no_duplicates if you want an exception thrown if there are + conflicting cookies. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :return: cookie.value + """ + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + return cookie.value + + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def _find_no_duplicates(self, name, domain=None, path=None): + """Both ``__get_item__`` and ``get`` call this function: it's never + used elsewhere in Requests. + + :param name: a string containing name of cookie + :param domain: (optional) string containing domain of cookie + :param path: (optional) string containing path of cookie + :raises KeyError: if cookie is not found + :raises CookieConflictError: if there are multiple cookies + that match name and optionally domain and path + :return: cookie.value + """ + toReturn = None + for cookie in iter(self): + if cookie.name == name: + if domain is None or cookie.domain == domain: + if path is None or cookie.path == path: + if toReturn is not None: # if there are multiple cookies that meet passed in criteria + raise CookieConflictError('There are multiple cookies with name, %r' % (name)) + toReturn = cookie.value # we will eventually return this as long as no cookie conflict + + if toReturn: + return toReturn + raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) + + def __getstate__(self): + """Unlike a normal CookieJar, this class is pickleable.""" + state = self.__dict__.copy() + # remove the unpickleable RLock object + state.pop('_cookies_lock') + return state + + def __setstate__(self, state): + """Unlike a normal CookieJar, this class is pickleable.""" + self.__dict__.update(state) + if '_cookies_lock' not in self.__dict__: + self._cookies_lock = threading.RLock() + + def copy(self): + """Return a copy of this RequestsCookieJar.""" + new_cj = RequestsCookieJar() + new_cj.set_policy(self.get_policy()) + new_cj.update(self) + return new_cj + + def get_policy(self): + """Return the CookiePolicy instance used.""" + return self._policy + + +def _copy_cookie_jar(jar): + if jar is None: + return None + + if hasattr(jar, 'copy'): + # We're dealing with an instance of RequestsCookieJar + return jar.copy() + # We're dealing with a generic CookieJar instance + new_jar = copy.copy(jar) + new_jar.clear() + for cookie in jar: + new_jar.set_cookie(copy.copy(cookie)) + return new_jar + + +def create_cookie(name, value, **kwargs): + """Make a cookie from underspecified parameters. + + By default, the pair of `name` and `value` will be set for the domain '' + and sent on every request (this is sometimes called a "supercookie"). + """ + result = dict( + version=0, + name=name, + value=value, + port=None, + domain='', + path='/', + secure=False, + expires=None, + discard=True, + comment=None, + comment_url=None, + rest={'HttpOnly': None}, + rfc2109=False,) + + badargs = set(kwargs) - set(result) + if badargs: + err = 'create_cookie() got unexpected keyword arguments: %s' + raise TypeError(err % list(badargs)) + + result.update(kwargs) + result['port_specified'] = bool(result['port']) + result['domain_specified'] = bool(result['domain']) + result['domain_initial_dot'] = result['domain'].startswith('.') + result['path_specified'] = bool(result['path']) + + return cookielib.Cookie(**result) + + +def morsel_to_cookie(morsel): + """Convert a Morsel object into a Cookie containing the one k/v pair.""" + + expires = None + if morsel['max-age']: + try: + expires = int(time.time() + int(morsel['max-age'])) + except ValueError: + raise TypeError('max-age: %s must be integer' % morsel['max-age']) + elif morsel['expires']: + time_template = '%a, %d-%b-%Y %H:%M:%S GMT' + expires = calendar.timegm( + time.strptime(morsel['expires'], time_template) + ) + return create_cookie( + comment=morsel['comment'], + comment_url=bool(morsel['comment']), + discard=False, + domain=morsel['domain'], + expires=expires, + name=morsel.key, + path=morsel['path'], + port=None, + rest={'HttpOnly': morsel['httponly']}, + rfc2109=False, + secure=bool(morsel['secure']), + value=morsel.value, + version=morsel['version'] or 0, + ) + + +def cookiejar_from_dict(cookie_dict, cookiejar=None, overwrite=True): + """Returns a CookieJar from a key/value dictionary. + + :param cookie_dict: Dict of key/values to insert into CookieJar. + :param cookiejar: (optional) A cookiejar to add the cookies to. + :param overwrite: (optional) If False, will not replace cookies + already in the jar with new ones. + """ + if cookiejar is None: + cookiejar = RequestsCookieJar() + + if cookie_dict is not None: + names_from_jar = [cookie.name for cookie in cookiejar] + for name in cookie_dict: + if overwrite or (name not in names_from_jar): + cookiejar.set_cookie(create_cookie(name, cookie_dict[name])) + + return cookiejar + + +def merge_cookies(cookiejar, cookies): + """Add cookies to cookiejar and returns a merged CookieJar. + + :param cookiejar: CookieJar object to add the cookies to. + :param cookies: Dictionary or CookieJar object to be added. + """ + if not isinstance(cookiejar, cookielib.CookieJar): + raise ValueError('You can only merge into CookieJar') + + if isinstance(cookies, dict): + cookiejar = cookiejar_from_dict( + cookies, cookiejar=cookiejar, overwrite=False) + elif isinstance(cookies, cookielib.CookieJar): + try: + cookiejar.update(cookies) + except AttributeError: + for cookie_in_jar in cookies: + cookiejar.set_cookie(cookie_in_jar) + + return cookiejar diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py new file mode 100644 index 0000000..a91e1fd --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/exceptions.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- + +""" +requests.exceptions +~~~~~~~~~~~~~~~~~~~ + +This module contains the set of Requests' exceptions. +""" +from pip._vendor.urllib3.exceptions import HTTPError as BaseHTTPError + + +class RequestException(IOError): + """There was an ambiguous exception that occurred while handling your + request. + """ + + def __init__(self, *args, **kwargs): + """Initialize RequestException with `request` and `response` objects.""" + response = kwargs.pop('response', None) + self.response = response + self.request = kwargs.pop('request', None) + if (response is not None and not self.request and + hasattr(response, 'request')): + self.request = self.response.request + super(RequestException, self).__init__(*args, **kwargs) + + +class HTTPError(RequestException): + """An HTTP error occurred.""" + + +class ConnectionError(RequestException): + """A Connection error occurred.""" + + +class ProxyError(ConnectionError): + """A proxy error occurred.""" + + +class SSLError(ConnectionError): + """An SSL error occurred.""" + + +class Timeout(RequestException): + """The request timed out. + + Catching this error will catch both + :exc:`~requests.exceptions.ConnectTimeout` and + :exc:`~requests.exceptions.ReadTimeout` errors. + """ + + +class ConnectTimeout(ConnectionError, Timeout): + """The request timed out while trying to connect to the remote server. + + Requests that produced this error are safe to retry. + """ + + +class ReadTimeout(Timeout): + """The server did not send any data in the allotted amount of time.""" + + +class URLRequired(RequestException): + """A valid URL is required to make a request.""" + + +class TooManyRedirects(RequestException): + """Too many redirects.""" + + +class MissingSchema(RequestException, ValueError): + """The URL schema (e.g. http or https) is missing.""" + + +class InvalidSchema(RequestException, ValueError): + """See defaults.py for valid schemas.""" + + +class InvalidURL(RequestException, ValueError): + """The URL provided was somehow invalid.""" + + +class InvalidHeader(RequestException, ValueError): + """The header value provided was somehow invalid.""" + + +class InvalidProxyURL(InvalidURL): + """The proxy URL provided is invalid.""" + + +class ChunkedEncodingError(RequestException): + """The server declared chunked encoding but sent an invalid chunk.""" + + +class ContentDecodingError(RequestException, BaseHTTPError): + """Failed to decode response content""" + + +class StreamConsumedError(RequestException, TypeError): + """The content for this response was already consumed""" + + +class RetryError(RequestException): + """Custom retries logic failed""" + + +class UnrewindableBodyError(RequestException): + """Requests encountered an error when trying to rewind a body""" + +# Warnings + + +class RequestsWarning(Warning): + """Base warning for Requests.""" + pass + + +class FileModeWarning(RequestsWarning, DeprecationWarning): + """A file was opened in text mode, but Requests determined its binary length.""" + pass + + +class RequestsDependencyWarning(RequestsWarning): + """An imported dependency doesn't match the expected version range.""" + pass diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/help.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/help.py new file mode 100644 index 0000000..df1b4eb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/help.py @@ -0,0 +1,120 @@ +"""Module containing bug report helper(s).""" +from __future__ import print_function + +import json +import platform +import sys +import ssl + +from pip._vendor import idna +from pip._vendor import urllib3 +from pip._vendor import chardet + +from . import __version__ as requests_version + +try: + from pip._vendor.urllib3.contrib import pyopenssl +except ImportError: + pyopenssl = None + OpenSSL = None + cryptography = None +else: + import OpenSSL + import cryptography + + +def _implementation(): + """Return a dict with the Python implementation and version. + + Provide both the name and the version of the Python implementation + currently running. For example, on CPython 2.7.5 it will return + {'name': 'CPython', 'version': '2.7.5'}. + + This function works best on CPython and PyPy: in particular, it probably + doesn't work for Jython or IronPython. Future investigation should be done + to work out the correct shape of the code for those platforms. + """ + implementation = platform.python_implementation() + + if implementation == 'CPython': + implementation_version = platform.python_version() + elif implementation == 'PyPy': + implementation_version = '%s.%s.%s' % (sys.pypy_version_info.major, + sys.pypy_version_info.minor, + sys.pypy_version_info.micro) + if sys.pypy_version_info.releaselevel != 'final': + implementation_version = ''.join([ + implementation_version, sys.pypy_version_info.releaselevel + ]) + elif implementation == 'Jython': + implementation_version = platform.python_version() # Complete Guess + elif implementation == 'IronPython': + implementation_version = platform.python_version() # Complete Guess + else: + implementation_version = 'Unknown' + + return {'name': implementation, 'version': implementation_version} + + +def info(): + """Generate information for a bug report.""" + try: + platform_info = { + 'system': platform.system(), + 'release': platform.release(), + } + except IOError: + platform_info = { + 'system': 'Unknown', + 'release': 'Unknown', + } + + implementation_info = _implementation() + urllib3_info = {'version': urllib3.__version__} + chardet_info = {'version': chardet.__version__} + + pyopenssl_info = { + 'version': None, + 'openssl_version': '', + } + if OpenSSL: + pyopenssl_info = { + 'version': OpenSSL.__version__, + 'openssl_version': '%x' % OpenSSL.SSL.OPENSSL_VERSION_NUMBER, + } + cryptography_info = { + 'version': getattr(cryptography, '__version__', ''), + } + idna_info = { + 'version': getattr(idna, '__version__', ''), + } + + # OPENSSL_VERSION_NUMBER doesn't exist in the Python 2.6 ssl module. + system_ssl = getattr(ssl, 'OPENSSL_VERSION_NUMBER', None) + system_ssl_info = { + 'version': '%x' % system_ssl if system_ssl is not None else '' + } + + return { + 'platform': platform_info, + 'implementation': implementation_info, + 'system_ssl': system_ssl_info, + 'using_pyopenssl': pyopenssl is not None, + 'pyOpenSSL': pyopenssl_info, + 'urllib3': urllib3_info, + 'chardet': chardet_info, + 'cryptography': cryptography_info, + 'idna': idna_info, + 'requests': { + 'version': requests_version, + }, + } + + +def main(): + """Pretty-print the bug information as JSON.""" + print(json.dumps(info(), sort_keys=True, indent=2)) + + +if __name__ == '__main__': + main() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py new file mode 100644 index 0000000..32b32de --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/hooks.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +""" +requests.hooks +~~~~~~~~~~~~~~ + +This module provides the capabilities for the Requests hooks system. + +Available hooks: + +``response``: + The response generated from a Request. +""" +HOOKS = ['response'] + + +def default_hooks(): + return dict((event, []) for event in HOOKS) + +# TODO: response is the only one + + +def dispatch_hook(key, hooks, hook_data, **kwargs): + """Dispatches a hook dictionary on a given piece of data.""" + hooks = hooks or dict() + hooks = hooks.get(key) + if hooks: + if hasattr(hooks, '__call__'): + hooks = [hooks] + for hook in hooks: + _hook_data = hook(hook_data, **kwargs) + if _hook_data is not None: + hook_data = _hook_data + return hook_data diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/models.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/models.py new file mode 100644 index 0000000..4230535 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/models.py @@ -0,0 +1,952 @@ +# -*- coding: utf-8 -*- + +""" +requests.models +~~~~~~~~~~~~~~~ + +This module contains the primary objects that power Requests. +""" + +import datetime +import sys + +# Import encoding now, to avoid implicit import later. +# Implicit import within threads may cause LookupError when standard library is in a ZIP, +# such as in Embedded Python. See https://github.com/requests/requests/issues/3578. +import encodings.idna + +from pip._vendor.urllib3.fields import RequestField +from pip._vendor.urllib3.filepost import encode_multipart_formdata +from pip._vendor.urllib3.util import parse_url +from pip._vendor.urllib3.exceptions import ( + DecodeError, ReadTimeoutError, ProtocolError, LocationParseError) + +from io import UnsupportedOperation +from .hooks import default_hooks +from .structures import CaseInsensitiveDict + +from .auth import HTTPBasicAuth +from .cookies import cookiejar_from_dict, get_cookie_header, _copy_cookie_jar +from .exceptions import ( + HTTPError, MissingSchema, InvalidURL, ChunkedEncodingError, + ContentDecodingError, ConnectionError, StreamConsumedError) +from ._internal_utils import to_native_string, unicode_is_ascii +from .utils import ( + guess_filename, get_auth_from_url, requote_uri, + stream_decode_response_unicode, to_key_val_list, parse_header_links, + iter_slices, guess_json_utf, super_len, check_header_validity) +from .compat import ( + Callable, Mapping, + cookielib, urlunparse, urlsplit, urlencode, str, bytes, + is_py2, chardet, builtin_str, basestring) +from .compat import json as complexjson +from .status_codes import codes + +#: The set of HTTP status codes that indicate an automatically +#: processable redirect. +REDIRECT_STATI = ( + codes.moved, # 301 + codes.found, # 302 + codes.other, # 303 + codes.temporary_redirect, # 307 + codes.permanent_redirect, # 308 +) + +DEFAULT_REDIRECT_LIMIT = 30 +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + +class RequestEncodingMixin(object): + @property + def path_url(self): + """Build the path URL to use.""" + + url = [] + + p = urlsplit(self.url) + + path = p.path + if not path: + path = '/' + + url.append(path) + + query = p.query + if query: + url.append('?') + url.append(query) + + return ''.join(url) + + @staticmethod + def _encode_params(data): + """Encode parameters in a piece of data. + + Will successfully encode parameters when passed as a dict or a list of + 2-tuples. Order is retained if data is a list of 2-tuples but arbitrary + if parameters are supplied as a dict. + """ + + if isinstance(data, (str, bytes)): + return data + elif hasattr(data, 'read'): + return data + elif hasattr(data, '__iter__'): + result = [] + for k, vs in to_key_val_list(data): + if isinstance(vs, basestring) or not hasattr(vs, '__iter__'): + vs = [vs] + for v in vs: + if v is not None: + result.append( + (k.encode('utf-8') if isinstance(k, str) else k, + v.encode('utf-8') if isinstance(v, str) else v)) + return urlencode(result, doseq=True) + else: + return data + + @staticmethod + def _encode_files(files, data): + """Build the body for a multipart/form-data request. + + Will successfully encode files when passed as a dict or a list of + tuples. Order is retained if data is a list of tuples but arbitrary + if parameters are supplied as a dict. + The tuples may be 2-tuples (filename, fileobj), 3-tuples (filename, fileobj, contentype) + or 4-tuples (filename, fileobj, contentype, custom_headers). + """ + if (not files): + raise ValueError("Files must be provided.") + elif isinstance(data, basestring): + raise ValueError("Data must not be a string.") + + new_fields = [] + fields = to_key_val_list(data or {}) + files = to_key_val_list(files or {}) + + for field, val in fields: + if isinstance(val, basestring) or not hasattr(val, '__iter__'): + val = [val] + for v in val: + if v is not None: + # Don't call str() on bytestrings: in Py3 it all goes wrong. + if not isinstance(v, bytes): + v = str(v) + + new_fields.append( + (field.decode('utf-8') if isinstance(field, bytes) else field, + v.encode('utf-8') if isinstance(v, str) else v)) + + for (k, v) in files: + # support for explicit filename + ft = None + fh = None + if isinstance(v, (tuple, list)): + if len(v) == 2: + fn, fp = v + elif len(v) == 3: + fn, fp, ft = v + else: + fn, fp, ft, fh = v + else: + fn = guess_filename(v) or k + fp = v + + if isinstance(fp, (str, bytes, bytearray)): + fdata = fp + elif hasattr(fp, 'read'): + fdata = fp.read() + elif fp is None: + continue + else: + fdata = fp + + rf = RequestField(name=k, data=fdata, filename=fn, headers=fh) + rf.make_multipart(content_type=ft) + new_fields.append(rf) + + body, content_type = encode_multipart_formdata(new_fields) + + return body, content_type + + +class RequestHooksMixin(object): + def register_hook(self, event, hook): + """Properly register a hook.""" + + if event not in self.hooks: + raise ValueError('Unsupported event specified, with event name "%s"' % (event)) + + if isinstance(hook, Callable): + self.hooks[event].append(hook) + elif hasattr(hook, '__iter__'): + self.hooks[event].extend(h for h in hook if isinstance(h, Callable)) + + def deregister_hook(self, event, hook): + """Deregister a previously registered hook. + Returns True if the hook existed, False if not. + """ + + try: + self.hooks[event].remove(hook) + return True + except ValueError: + return False + + +class Request(RequestHooksMixin): + """A user-created :class:`Request <Request>` object. + + Used to prepare a :class:`PreparedRequest <PreparedRequest>`, which is sent to the server. + + :param method: HTTP method to use. + :param url: URL to send. + :param headers: dictionary of headers to send. + :param files: dictionary of {filename: fileobject} files to multipart upload. + :param data: the body to attach to the request. If a dictionary is provided, form-encoding will take place. + :param json: json for the body to attach to the request (if files or data is not specified). + :param params: dictionary of URL parameters to append to the URL. + :param auth: Auth handler or (user, pass) tuple. + :param cookies: dictionary or CookieJar of cookies to attach to this request. + :param hooks: dictionary of callback hooks, for internal usage. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> req.prepare() + <PreparedRequest [GET]> + """ + + def __init__(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + + # Default empty dicts for dict params. + data = [] if data is None else data + files = [] if files is None else files + headers = {} if headers is None else headers + params = {} if params is None else params + hooks = {} if hooks is None else hooks + + self.hooks = default_hooks() + for (k, v) in list(hooks.items()): + self.register_hook(event=k, hook=v) + + self.method = method + self.url = url + self.headers = headers + self.files = files + self.data = data + self.json = json + self.params = params + self.auth = auth + self.cookies = cookies + + def __repr__(self): + return '<Request [%s]>' % (self.method) + + def prepare(self): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for transmission and returns it.""" + p = PreparedRequest() + p.prepare( + method=self.method, + url=self.url, + headers=self.headers, + files=self.files, + data=self.data, + json=self.json, + params=self.params, + auth=self.auth, + cookies=self.cookies, + hooks=self.hooks, + ) + return p + + +class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): + """The fully mutable :class:`PreparedRequest <PreparedRequest>` object, + containing the exact bytes that will be sent to the server. + + Generated from either a :class:`Request <Request>` object or manually. + + Usage:: + + >>> import requests + >>> req = requests.Request('GET', 'http://httpbin.org/get') + >>> r = req.prepare() + <PreparedRequest [GET]> + + >>> s = requests.Session() + >>> s.send(r) + <Response [200]> + """ + + def __init__(self): + #: HTTP verb to send to the server. + self.method = None + #: HTTP URL to send the request to. + self.url = None + #: dictionary of HTTP headers. + self.headers = None + # The `CookieJar` used to create the Cookie header will be stored here + # after prepare_cookies is called + self._cookies = None + #: request body to send to the server. + self.body = None + #: dictionary of callback hooks, for internal usage. + self.hooks = default_hooks() + #: integer denoting starting position of a readable file-like body. + self._body_position = None + + def prepare(self, + method=None, url=None, headers=None, files=None, data=None, + params=None, auth=None, cookies=None, hooks=None, json=None): + """Prepares the entire request with the given parameters.""" + + self.prepare_method(method) + self.prepare_url(url, params) + self.prepare_headers(headers) + self.prepare_cookies(cookies) + self.prepare_body(data, files, json) + self.prepare_auth(auth, url) + + # Note that prepare_auth must be last to enable authentication schemes + # such as OAuth to work on a fully prepared request. + + # This MUST go after prepare_auth. Authenticators could add a hook + self.prepare_hooks(hooks) + + def __repr__(self): + return '<PreparedRequest [%s]>' % (self.method) + + def copy(self): + p = PreparedRequest() + p.method = self.method + p.url = self.url + p.headers = self.headers.copy() if self.headers is not None else None + p._cookies = _copy_cookie_jar(self._cookies) + p.body = self.body + p.hooks = self.hooks + p._body_position = self._body_position + return p + + def prepare_method(self, method): + """Prepares the given HTTP method.""" + self.method = method + if self.method is not None: + self.method = to_native_string(self.method.upper()) + + @staticmethod + def _get_idna_encoded_host(host): + from pip._vendor import idna + + try: + host = idna.encode(host, uts46=True).decode('utf-8') + except idna.IDNAError: + raise UnicodeError + return host + + def prepare_url(self, url, params): + """Prepares the given HTTP URL.""" + #: Accept objects that have string representations. + #: We're unable to blindly call unicode/str functions + #: as this will include the bytestring indicator (b'') + #: on python 3.x. + #: https://github.com/requests/requests/pull/2238 + if isinstance(url, bytes): + url = url.decode('utf8') + else: + url = unicode(url) if is_py2 else str(url) + + # Remove leading whitespaces from url + url = url.lstrip() + + # Don't do any URL preparation for non-HTTP schemes like `mailto`, + # `data` etc to work around exceptions from `url_parse`, which + # handles RFC 3986 only. + if ':' in url and not url.lower().startswith('http'): + self.url = url + return + + # Support for unicode domain names and paths. + try: + scheme, auth, host, port, path, query, fragment = parse_url(url) + except LocationParseError as e: + raise InvalidURL(*e.args) + + if not scheme: + error = ("Invalid URL {0!r}: No schema supplied. Perhaps you meant http://{0}?") + error = error.format(to_native_string(url, 'utf8')) + + raise MissingSchema(error) + + if not host: + raise InvalidURL("Invalid URL %r: No host supplied" % url) + + # In general, we want to try IDNA encoding the hostname if the string contains + # non-ASCII characters. This allows users to automatically get the correct IDNA + # behaviour. For strings containing only ASCII characters, we need to also verify + # it doesn't start with a wildcard (*), before allowing the unencoded hostname. + if not unicode_is_ascii(host): + try: + host = self._get_idna_encoded_host(host) + except UnicodeError: + raise InvalidURL('URL has an invalid label.') + elif host.startswith(u'*'): + raise InvalidURL('URL has an invalid label.') + + # Carefully reconstruct the network location + netloc = auth or '' + if netloc: + netloc += '@' + netloc += host + if port: + netloc += ':' + str(port) + + # Bare domains aren't valid URLs. + if not path: + path = '/' + + if is_py2: + if isinstance(scheme, str): + scheme = scheme.encode('utf-8') + if isinstance(netloc, str): + netloc = netloc.encode('utf-8') + if isinstance(path, str): + path = path.encode('utf-8') + if isinstance(query, str): + query = query.encode('utf-8') + if isinstance(fragment, str): + fragment = fragment.encode('utf-8') + + if isinstance(params, (str, bytes)): + params = to_native_string(params) + + enc_params = self._encode_params(params) + if enc_params: + if query: + query = '%s&%s' % (query, enc_params) + else: + query = enc_params + + url = requote_uri(urlunparse([scheme, netloc, path, None, query, fragment])) + self.url = url + + def prepare_headers(self, headers): + """Prepares the given HTTP headers.""" + + self.headers = CaseInsensitiveDict() + if headers: + for header in headers.items(): + # Raise exception on invalid header value. + check_header_validity(header) + name, value = header + self.headers[to_native_string(name)] = value + + def prepare_body(self, data, files, json=None): + """Prepares the given HTTP body data.""" + + # Check if file, fo, generator, iterator. + # If not, run through normal process. + + # Nottin' on you. + body = None + content_type = None + + if not data and json is not None: + # urllib3 requires a bytes-like body. Python 2's json.dumps + # provides this natively, but Python 3 gives a Unicode string. + content_type = 'application/json' + body = complexjson.dumps(json) + if not isinstance(body, bytes): + body = body.encode('utf-8') + + is_stream = all([ + hasattr(data, '__iter__'), + not isinstance(data, (basestring, list, tuple, Mapping)) + ]) + + try: + length = super_len(data) + except (TypeError, AttributeError, UnsupportedOperation): + length = None + + if is_stream: + body = data + + if getattr(body, 'tell', None) is not None: + # Record the current file position before reading. + # This will allow us to rewind a file in the event + # of a redirect. + try: + self._body_position = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body + self._body_position = object() + + if files: + raise NotImplementedError('Streamed bodies and files are mutually exclusive.') + + if length: + self.headers['Content-Length'] = builtin_str(length) + else: + self.headers['Transfer-Encoding'] = 'chunked' + else: + # Multi-part file uploads. + if files: + (body, content_type) = self._encode_files(files, data) + else: + if data: + body = self._encode_params(data) + if isinstance(data, basestring) or hasattr(data, 'read'): + content_type = None + else: + content_type = 'application/x-www-form-urlencoded' + + self.prepare_content_length(body) + + # Add content-type if it wasn't explicitly provided. + if content_type and ('content-type' not in self.headers): + self.headers['Content-Type'] = content_type + + self.body = body + + def prepare_content_length(self, body): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers['Content-Length'] = builtin_str(length) + elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) + self.headers['Content-Length'] = '0' + + def prepare_auth(self, auth, url=''): + """Prepares the given HTTP auth data.""" + + # If no Auth is explicitly provided, extract it from the URL first. + if auth is None: + url_auth = get_auth_from_url(self.url) + auth = url_auth if any(url_auth) else None + + if auth: + if isinstance(auth, tuple) and len(auth) == 2: + # special-case basic HTTP auth + auth = HTTPBasicAuth(*auth) + + # Allow auth to make its changes. + r = auth(self) + + # Update self to reflect the auth changes. + self.__dict__.update(r.__dict__) + + # Recompute Content-Length + self.prepare_content_length(self.body) + + def prepare_cookies(self, cookies): + """Prepares the given HTTP cookie data. + + This function eventually generates a ``Cookie`` header from the + given cookies using cookielib. Due to cookielib's design, the header + will not be regenerated if it already exists, meaning this function + can only be called once for the life of the + :class:`PreparedRequest <PreparedRequest>` object. Any subsequent calls + to ``prepare_cookies`` will have no actual effect, unless the "Cookie" + header is removed beforehand. + """ + if isinstance(cookies, cookielib.CookieJar): + self._cookies = cookies + else: + self._cookies = cookiejar_from_dict(cookies) + + cookie_header = get_cookie_header(self._cookies, self) + if cookie_header is not None: + self.headers['Cookie'] = cookie_header + + def prepare_hooks(self, hooks): + """Prepares the given hooks.""" + # hooks can be passed as None to the prepare method and to this + # method. To prevent iterating over None, simply use an empty list + # if hooks is False-y + hooks = hooks or [] + for event in hooks: + self.register_hook(event, hooks[event]) + + +class Response(object): + """The :class:`Response <Response>` object, which contains a + server's response to an HTTP request. + """ + + __attrs__ = [ + '_content', 'status_code', 'headers', 'url', 'history', + 'encoding', 'reason', 'cookies', 'elapsed', 'request' + ] + + def __init__(self): + self._content = False + self._content_consumed = False + self._next = None + + #: Integer Code of responded HTTP Status, e.g. 404 or 200. + self.status_code = None + + #: Case-insensitive Dictionary of Response Headers. + #: For example, ``headers['content-encoding']`` will return the + #: value of a ``'Content-Encoding'`` response header. + self.headers = CaseInsensitiveDict() + + #: File-like object representation of response (for advanced usage). + #: Use of ``raw`` requires that ``stream=True`` be set on the request. + # This requirement does not apply for use internally to Requests. + self.raw = None + + #: Final URL location of Response. + self.url = None + + #: Encoding to decode with when accessing r.text. + self.encoding = None + + #: A list of :class:`Response <Response>` objects from + #: the history of the Request. Any redirect responses will end + #: up here. The list is sorted from the oldest to the most recent request. + self.history = [] + + #: Textual reason of responded HTTP Status, e.g. "Not Found" or "OK". + self.reason = None + + #: A CookieJar of Cookies the server sent back. + self.cookies = cookiejar_from_dict({}) + + #: The amount of time elapsed between sending the request + #: and the arrival of the response (as a timedelta). + #: This property specifically measures the time taken between sending + #: the first byte of the request and finishing parsing the headers. It + #: is therefore unaffected by consuming the response content or the + #: value of the ``stream`` keyword argument. + self.elapsed = datetime.timedelta(0) + + #: The :class:`PreparedRequest <PreparedRequest>` object to which this + #: is a response. + self.request = None + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def __getstate__(self): + # Consume everything; accessing the content attribute makes + # sure the content has been fully read. + if not self._content_consumed: + self.content + + return dict( + (attr, getattr(self, attr, None)) + for attr in self.__attrs__ + ) + + def __setstate__(self, state): + for name, value in state.items(): + setattr(self, name, value) + + # pickled objects do not have .raw + setattr(self, '_content_consumed', True) + setattr(self, 'raw', None) + + def __repr__(self): + return '<Response [%s]>' % (self.status_code) + + def __bool__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __nonzero__(self): + """Returns True if :attr:`status_code` is less than 400. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code, is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + return self.ok + + def __iter__(self): + """Allows you to use a response as an iterator.""" + return self.iter_content(128) + + @property + def ok(self): + """Returns True if :attr:`status_code` is less than 400, False if not. + + This attribute checks if the status code of the response is between + 400 and 600 to see if there was a client error or a server error. If + the status code is between 200 and 400, this will return True. This + is **not** a check to see if the response code is ``200 OK``. + """ + try: + self.raise_for_status() + except HTTPError: + return False + return True + + @property + def is_redirect(self): + """True if this Response is a well-formed HTTP redirect that could have + been processed automatically (by :meth:`Session.resolve_redirects`). + """ + return ('location' in self.headers and self.status_code in REDIRECT_STATI) + + @property + def is_permanent_redirect(self): + """True if this Response one of the permanent versions of redirect.""" + return ('location' in self.headers and self.status_code in (codes.moved_permanently, codes.permanent_redirect)) + + @property + def next(self): + """Returns a PreparedRequest for the next request in a redirect chain, if there is one.""" + return self._next + + @property + def apparent_encoding(self): + """The apparent encoding, provided by the chardet library.""" + return chardet.detect(self.content)['encoding'] + + def iter_content(self, chunk_size=1, decode_unicode=False): + """Iterates over the response data. When stream=True is set on the + request, this avoids reading the content at once into memory for + large responses. The chunk size is the number of bytes it should + read into memory. This is not necessarily the length of each item + returned as decoding can take place. + + chunk_size must be of type int or None. A value of None will + function differently depending on the value of `stream`. + stream=True will read data as it arrives in whatever size the + chunks are received. If stream=False, data is returned as + a single chunk. + + If decode_unicode is True, content will be decoded using the best + available encoding based on the response. + """ + + def generate(): + # Special case for urllib3. + if hasattr(self.raw, 'stream'): + try: + for chunk in self.raw.stream(chunk_size, decode_content=True): + yield chunk + except ProtocolError as e: + raise ChunkedEncodingError(e) + except DecodeError as e: + raise ContentDecodingError(e) + except ReadTimeoutError as e: + raise ConnectionError(e) + else: + # Standard file-like object. + while True: + chunk = self.raw.read(chunk_size) + if not chunk: + break + yield chunk + + self._content_consumed = True + + if self._content_consumed and isinstance(self._content, bool): + raise StreamConsumedError() + elif chunk_size is not None and not isinstance(chunk_size, int): + raise TypeError("chunk_size must be an int, it is instead a %s." % type(chunk_size)) + # simulate reading small chunks of the content + reused_chunks = iter_slices(self._content, chunk_size) + + stream_chunks = generate() + + chunks = reused_chunks if self._content_consumed else stream_chunks + + if decode_unicode: + chunks = stream_decode_response_unicode(chunks, self) + + return chunks + + def iter_lines(self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=None, delimiter=None): + """Iterates over the response data, one line at a time. When + stream=True is set on the request, this avoids reading the + content at once into memory for large responses. + + .. note:: This method is not reentrant safe. + """ + + pending = None + + for chunk in self.iter_content(chunk_size=chunk_size, decode_unicode=decode_unicode): + + if pending is not None: + chunk = pending + chunk + + if delimiter: + lines = chunk.split(delimiter) + else: + lines = chunk.splitlines() + + if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]: + pending = lines.pop() + else: + pending = None + + for line in lines: + yield line + + if pending is not None: + yield pending + + @property + def content(self): + """Content of the response, in bytes.""" + + if self._content is False: + # Read the contents. + if self._content_consumed: + raise RuntimeError( + 'The content for this response was already consumed') + + if self.status_code == 0 or self.raw is None: + self._content = None + else: + self._content = b''.join(self.iter_content(CONTENT_CHUNK_SIZE)) or b'' + + self._content_consumed = True + # don't need to release the connection; that's been handled by urllib3 + # since we exhausted the data. + return self._content + + @property + def text(self): + """Content of the response, in unicode. + + If Response.encoding is None, encoding will be guessed using + ``chardet``. + + The encoding of the response content is determined based solely on HTTP + headers, following RFC 2616 to the letter. If you can take advantage of + non-HTTP knowledge to make a better guess at the encoding, you should + set ``r.encoding`` appropriately before accessing this property. + """ + + # Try charset from content-type + content = None + encoding = self.encoding + + if not self.content: + return str('') + + # Fallback to auto-detected encoding. + if self.encoding is None: + encoding = self.apparent_encoding + + # Decode unicode from given encoding. + try: + content = str(self.content, encoding, errors='replace') + except (LookupError, TypeError): + # A LookupError is raised if the encoding was not found which could + # indicate a misspelling or similar mistake. + # + # A TypeError can be raised if encoding is None + # + # So we try blindly encoding. + content = str(self.content, errors='replace') + + return content + + def json(self, **kwargs): + r"""Returns the json-encoded content of a response, if any. + + :param \*\*kwargs: Optional arguments that ``json.loads`` takes. + :raises ValueError: If the response body does not contain valid json. + """ + + if not self.encoding and self.content and len(self.content) > 3: + # No encoding set. JSON RFC 4627 section 3 states we should expect + # UTF-8, -16 or -32. Detect which one to use; If the detection or + # decoding fails, fall back to `self.text` (using chardet to make + # a best guess). + encoding = guess_json_utf(self.content) + if encoding is not None: + try: + return complexjson.loads( + self.content.decode(encoding), **kwargs + ) + except UnicodeDecodeError: + # Wrong UTF codec detected; usually because it's not UTF-8 + # but some other 8-bit codec. This is an RFC violation, + # and the server didn't bother to tell us what codec *was* + # used. + pass + return complexjson.loads(self.text, **kwargs) + + @property + def links(self): + """Returns the parsed header links of the response, if any.""" + + header = self.headers.get('link') + + # l = MultiDict() + l = {} + + if header: + links = parse_header_links(header) + + for link in links: + key = link.get('rel') or link.get('url') + l[key] = link + + return l + + def raise_for_status(self): + """Raises stored :class:`HTTPError`, if one occurred.""" + + http_error_msg = '' + if isinstance(self.reason, bytes): + # We attempt to decode utf-8 first because some servers + # choose to localize their reason strings. If the string + # isn't utf-8, we fall back to iso-8859-1 for all other + # encodings. (See PR #3538) + try: + reason = self.reason.decode('utf-8') + except UnicodeDecodeError: + reason = self.reason.decode('iso-8859-1') + else: + reason = self.reason + + if 400 <= self.status_code < 500: + http_error_msg = u'%s Client Error: %s for url: %s' % (self.status_code, reason, self.url) + + elif 500 <= self.status_code < 600: + http_error_msg = u'%s Server Error: %s for url: %s' % (self.status_code, reason, self.url) + + if http_error_msg: + raise HTTPError(http_error_msg, response=self) + + def close(self): + """Releases the connection back to the pool. Once this method has been + called the underlying ``raw`` object must not be accessed again. + + *Note: Should not normally need to be called explicitly.* + """ + if not self._content_consumed: + self.raw.close() + + release_conn = getattr(self.raw, 'release_conn', None) + if release_conn is not None: + release_conn() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/packages.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/packages.py new file mode 100644 index 0000000..9582fa7 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/packages.py @@ -0,0 +1,16 @@ +import sys + +# This code exists for backwards compatibility reasons. +# I don't like it either. Just look the other way. :) + +for package in ('urllib3', 'idna', 'chardet'): + vendored_package = "pip._vendor." + package + locals()[package] = __import__(vendored_package) + # This traversal is apparently necessary such that the identities are + # preserved (requests.packages.urllib3.* is urllib3.*) + for mod in list(sys.modules): + if mod == vendored_package or mod.startswith(vendored_package + '.'): + unprefixed_mod = mod[len("pip._vendor."):] + sys.modules['pip._vendor.requests.packages.' + unprefixed_mod] = sys.modules[mod] + +# Kinda cool, though, right? diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py new file mode 100644 index 0000000..ba13526 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/sessions.py @@ -0,0 +1,741 @@ +# -*- coding: utf-8 -*- + +""" +requests.session +~~~~~~~~~~~~~~~~ + +This module provides a Session object to manage and persist settings across +requests (cookies, auth, proxies). +""" +import os +import sys +import time +from datetime import timedelta + +from .auth import _basic_auth_str +from .compat import cookielib, is_py3, OrderedDict, urljoin, urlparse, Mapping +from .cookies import ( + cookiejar_from_dict, extract_cookies_to_jar, RequestsCookieJar, merge_cookies) +from .models import Request, PreparedRequest, DEFAULT_REDIRECT_LIMIT +from .hooks import default_hooks, dispatch_hook +from ._internal_utils import to_native_string +from .utils import to_key_val_list, default_headers +from .exceptions import ( + TooManyRedirects, InvalidSchema, ChunkedEncodingError, ContentDecodingError) + +from .structures import CaseInsensitiveDict +from .adapters import HTTPAdapter + +from .utils import ( + requote_uri, get_environ_proxies, get_netrc_auth, should_bypass_proxies, + get_auth_from_url, rewind_body +) + +from .status_codes import codes + +# formerly defined here, reexposed here for backward compatibility +from .models import REDIRECT_STATI + +# Preferred clock, based on which one is more accurate on a given system. +if sys.platform == 'win32': + try: # Python 3.4+ + preferred_clock = time.perf_counter + except AttributeError: # Earlier than Python 3. + preferred_clock = time.clock +else: + preferred_clock = time.time + + +def merge_setting(request_setting, session_setting, dict_class=OrderedDict): + """Determines appropriate setting for a given request, taking into account + the explicit setting on that request, and the setting in the session. If a + setting is a dictionary, they will be merged together using `dict_class` + """ + + if session_setting is None: + return request_setting + + if request_setting is None: + return session_setting + + # Bypass if not a dictionary (e.g. verify) + if not ( + isinstance(session_setting, Mapping) and + isinstance(request_setting, Mapping) + ): + return request_setting + + merged_setting = dict_class(to_key_val_list(session_setting)) + merged_setting.update(to_key_val_list(request_setting)) + + # Remove keys that are set to None. Extract keys first to avoid altering + # the dictionary during iteration. + none_keys = [k for (k, v) in merged_setting.items() if v is None] + for key in none_keys: + del merged_setting[key] + + return merged_setting + + +def merge_hooks(request_hooks, session_hooks, dict_class=OrderedDict): + """Properly merges both requests and session hooks. + + This is necessary because when request_hooks == {'response': []}, the + merge breaks Session hooks entirely. + """ + if session_hooks is None or session_hooks.get('response') == []: + return request_hooks + + if request_hooks is None or request_hooks.get('response') == []: + return session_hooks + + return merge_setting(request_hooks, session_hooks, dict_class) + + +class SessionRedirectMixin(object): + + def get_redirect_target(self, resp): + """Receives a Response. Returns a redirect URI or ``None``""" + # Due to the nature of how requests processes redirects this method will + # be called at least once upon the original response and at least twice + # on each subsequent redirect response (if any). + # If a custom mixin is used to handle this logic, it may be advantageous + # to cache the redirect location onto the response object as a private + # attribute. + if resp.is_redirect: + location = resp.headers['location'] + # Currently the underlying http module on py3 decode headers + # in latin1, but empirical evidence suggests that latin1 is very + # rarely used with non-ASCII characters in HTTP headers. + # It is more likely to get UTF8 header rather than latin1. + # This causes incorrect handling of UTF8 encoded location headers. + # To solve this, we re-encode the location in latin1. + if is_py3: + location = location.encode('latin1') + return to_native_string(location, 'utf8') + return None + + def resolve_redirects(self, resp, req, stream=False, timeout=None, + verify=True, cert=None, proxies=None, yield_requests=False, **adapter_kwargs): + """Receives a Response. Returns a generator of Responses or Requests.""" + + hist = [] # keep track of history + + url = self.get_redirect_target(resp) + previous_fragment = urlparse(req.url).fragment + while url: + prepared_request = req.copy() + + # Update history and keep track of redirects. + # resp.history must ignore the original request in this loop + hist.append(resp) + resp.history = hist[1:] + + try: + resp.content # Consume socket so it can be released + except (ChunkedEncodingError, ContentDecodingError, RuntimeError): + resp.raw.read(decode_content=False) + + if len(resp.history) >= self.max_redirects: + raise TooManyRedirects('Exceeded %s redirects.' % self.max_redirects, response=resp) + + # Release the connection back into the pool. + resp.close() + + # Handle redirection without scheme (see: RFC 1808 Section 4) + if url.startswith('//'): + parsed_rurl = urlparse(resp.url) + url = '%s:%s' % (to_native_string(parsed_rurl.scheme), url) + + # Normalize url case and attach previous fragment if needed (RFC 7231 7.1.2) + parsed = urlparse(url) + if parsed.fragment == '' and previous_fragment: + parsed = parsed._replace(fragment=previous_fragment) + elif parsed.fragment: + previous_fragment = parsed.fragment + url = parsed.geturl() + + # Facilitate relative 'location' headers, as allowed by RFC 7231. + # (e.g. '/path/to/resource' instead of 'http://domain.tld/path/to/resource') + # Compliant with RFC3986, we percent encode the url. + if not parsed.netloc: + url = urljoin(resp.url, requote_uri(url)) + else: + url = requote_uri(url) + + prepared_request.url = to_native_string(url) + + self.rebuild_method(prepared_request, resp) + + # https://github.com/requests/requests/issues/1084 + if resp.status_code not in (codes.temporary_redirect, codes.permanent_redirect): + # https://github.com/requests/requests/issues/3490 + purged_headers = ('Content-Length', 'Content-Type', 'Transfer-Encoding') + for header in purged_headers: + prepared_request.headers.pop(header, None) + prepared_request.body = None + + headers = prepared_request.headers + try: + del headers['Cookie'] + except KeyError: + pass + + # Extract any cookies sent on the response to the cookiejar + # in the new request. Because we've mutated our copied prepared + # request, use the old one that we haven't yet touched. + extract_cookies_to_jar(prepared_request._cookies, req, resp.raw) + merge_cookies(prepared_request._cookies, self.cookies) + prepared_request.prepare_cookies(prepared_request._cookies) + + # Rebuild auth and proxy information. + proxies = self.rebuild_proxies(prepared_request, proxies) + self.rebuild_auth(prepared_request, resp) + + # A failed tell() sets `_body_position` to `object()`. This non-None + # value ensures `rewindable` will be True, allowing us to raise an + # UnrewindableBodyError, instead of hanging the connection. + rewindable = ( + prepared_request._body_position is not None and + ('Content-Length' in headers or 'Transfer-Encoding' in headers) + ) + + # Attempt to rewind consumed file-like object. + if rewindable: + rewind_body(prepared_request) + + # Override the original request. + req = prepared_request + + if yield_requests: + yield req + else: + + resp = self.send( + req, + stream=stream, + timeout=timeout, + verify=verify, + cert=cert, + proxies=proxies, + allow_redirects=False, + **adapter_kwargs + ) + + extract_cookies_to_jar(self.cookies, prepared_request, resp.raw) + + # extract redirect url, if any, for the next loop + url = self.get_redirect_target(resp) + yield resp + + def rebuild_auth(self, prepared_request, response): + """When being redirected we may want to strip authentication from the + request to avoid leaking credentials. This method intelligently removes + and reapplies authentication where possible to avoid credential loss. + """ + headers = prepared_request.headers + url = prepared_request.url + + if 'Authorization' in headers: + # If we get redirected to a new host, we should strip out any + # authentication headers. + original_parsed = urlparse(response.request.url) + redirect_parsed = urlparse(url) + + if (original_parsed.hostname != redirect_parsed.hostname): + del headers['Authorization'] + + # .netrc might have more auth for us on our new host. + new_auth = get_netrc_auth(url) if self.trust_env else None + if new_auth is not None: + prepared_request.prepare_auth(new_auth) + + return + + def rebuild_proxies(self, prepared_request, proxies): + """This method re-evaluates the proxy configuration by considering the + environment variables. If we are redirected to a URL covered by + NO_PROXY, we strip the proxy configuration. Otherwise, we set missing + proxy keys for this URL (in case they were stripped by a previous + redirect). + + This method also replaces the Proxy-Authorization header where + necessary. + + :rtype: dict + """ + proxies = proxies if proxies is not None else {} + headers = prepared_request.headers + url = prepared_request.url + scheme = urlparse(url).scheme + new_proxies = proxies.copy() + no_proxy = proxies.get('no_proxy') + + bypass_proxy = should_bypass_proxies(url, no_proxy=no_proxy) + if self.trust_env and not bypass_proxy: + environ_proxies = get_environ_proxies(url, no_proxy=no_proxy) + + proxy = environ_proxies.get(scheme, environ_proxies.get('all')) + + if proxy: + new_proxies.setdefault(scheme, proxy) + + if 'Proxy-Authorization' in headers: + del headers['Proxy-Authorization'] + + try: + username, password = get_auth_from_url(new_proxies[scheme]) + except KeyError: + username, password = None, None + + if username and password: + headers['Proxy-Authorization'] = _basic_auth_str(username, password) + + return new_proxies + + def rebuild_method(self, prepared_request, response): + """When being redirected we may want to change the method of the request + based on certain specs or browser behavior. + """ + method = prepared_request.method + + # http://tools.ietf.org/html/rfc7231#section-6.4.4 + if response.status_code == codes.see_other and method != 'HEAD': + method = 'GET' + + # Do what the browsers do, despite standards... + # First, turn 302s into GETs. + if response.status_code == codes.found and method != 'HEAD': + method = 'GET' + + # Second, if a POST is responded to with a 301, turn it into a GET. + # This bizarre behaviour is explained in Issue 1704. + if response.status_code == codes.moved and method == 'POST': + method = 'GET' + + prepared_request.method = method + + +class Session(SessionRedirectMixin): + """A Requests session. + + Provides cookie persistence, connection-pooling, and configuration. + + Basic Usage:: + + >>> import requests + >>> s = requests.Session() + >>> s.get('http://httpbin.org/get') + <Response [200]> + + Or as a context manager:: + + >>> with requests.Session() as s: + >>> s.get('http://httpbin.org/get') + <Response [200]> + """ + + __attrs__ = [ + 'headers', 'cookies', 'auth', 'proxies', 'hooks', 'params', 'verify', + 'cert', 'prefetch', 'adapters', 'stream', 'trust_env', + 'max_redirects', + ] + + def __init__(self): + + #: A case-insensitive dictionary of headers to be sent on each + #: :class:`Request <Request>` sent from this + #: :class:`Session <Session>`. + self.headers = default_headers() + + #: Default Authentication tuple or object to attach to + #: :class:`Request <Request>`. + self.auth = None + + #: Dictionary mapping protocol or protocol and host to the URL of the proxy + #: (e.g. {'http': 'foo.bar:3128', 'http://host.name': 'foo.bar:4012'}) to + #: be used on each :class:`Request <Request>`. + self.proxies = {} + + #: Event-handling hooks. + self.hooks = default_hooks() + + #: Dictionary of querystring data to attach to each + #: :class:`Request <Request>`. The dictionary values may be lists for + #: representing multivalued query parameters. + self.params = {} + + #: Stream response content default. + self.stream = False + + #: SSL Verification default. + self.verify = True + + #: SSL client certificate default, if String, path to ssl client + #: cert file (.pem). If Tuple, ('cert', 'key') pair. + self.cert = None + + #: Maximum number of redirects allowed. If the request exceeds this + #: limit, a :class:`TooManyRedirects` exception is raised. + #: This defaults to requests.models.DEFAULT_REDIRECT_LIMIT, which is + #: 30. + self.max_redirects = DEFAULT_REDIRECT_LIMIT + + #: Trust environment settings for proxy configuration, default + #: authentication and similar. + self.trust_env = True + + #: A CookieJar containing all currently outstanding cookies set on this + #: session. By default it is a + #: :class:`RequestsCookieJar <requests.cookies.RequestsCookieJar>`, but + #: may be any other ``cookielib.CookieJar`` compatible object. + self.cookies = cookiejar_from_dict({}) + + # Default connection adapters. + self.adapters = OrderedDict() + self.mount('https://', HTTPAdapter()) + self.mount('http://', HTTPAdapter()) + + def __enter__(self): + return self + + def __exit__(self, *args): + self.close() + + def prepare_request(self, request): + """Constructs a :class:`PreparedRequest <PreparedRequest>` for + transmission and returns it. The :class:`PreparedRequest` has settings + merged from the :class:`Request <Request>` instance and those of the + :class:`Session`. + + :param request: :class:`Request` instance to prepare with this + session's settings. + :rtype: requests.PreparedRequest + """ + cookies = request.cookies or {} + + # Bootstrap CookieJar. + if not isinstance(cookies, cookielib.CookieJar): + cookies = cookiejar_from_dict(cookies) + + # Merge with session cookies + merged_cookies = merge_cookies( + merge_cookies(RequestsCookieJar(), self.cookies), cookies) + + # Set environment's basic authentication if not explicitly set. + auth = request.auth + if self.trust_env and not auth and not self.auth: + auth = get_netrc_auth(request.url) + + p = PreparedRequest() + p.prepare( + method=request.method.upper(), + url=request.url, + files=request.files, + data=request.data, + json=request.json, + headers=merge_setting(request.headers, self.headers, dict_class=CaseInsensitiveDict), + params=merge_setting(request.params, self.params), + auth=merge_setting(auth, self.auth), + cookies=merged_cookies, + hooks=merge_hooks(request.hooks, self.hooks), + ) + return p + + def request(self, method, url, + params=None, data=None, headers=None, cookies=None, files=None, + auth=None, timeout=None, allow_redirects=True, proxies=None, + hooks=None, stream=None, verify=None, cert=None, json=None): + """Constructs a :class:`Request <Request>`, prepares it and sends it. + Returns :class:`Response <Response>` object. + + :param method: method for the new :class:`Request` object. + :param url: URL for the new :class:`Request` object. + :param params: (optional) Dictionary or bytes to be sent in the query + string for the :class:`Request`. + :param data: (optional) Dictionary, bytes, or file-like object to send + in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the + :class:`Request`. + :param headers: (optional) Dictionary of HTTP Headers to send with the + :class:`Request`. + :param cookies: (optional) Dict or CookieJar object to send with the + :class:`Request`. + :param files: (optional) Dictionary of ``'filename': file-like-objects`` + for multipart encoding upload. + :param auth: (optional) Auth tuple or callable to enable + Basic/Digest/Custom HTTP Auth. + :param timeout: (optional) How long to wait for the server to send + data before giving up, as a float, or a :ref:`(connect timeout, + read timeout) <timeouts>` tuple. + :type timeout: float or tuple + :param allow_redirects: (optional) Set to True by default. + :type allow_redirects: bool + :param proxies: (optional) Dictionary mapping protocol or protocol and + hostname to the URL of the proxy. + :param stream: (optional) whether to immediately download the response + content. Defaults to ``False``. + :param verify: (optional) Either a boolean, in which case it controls whether we verify + the server's TLS certificate, or a string, in which case it must be a path + to a CA bundle to use. Defaults to ``True``. + :param cert: (optional) if String, path to ssl client cert file (.pem). + If Tuple, ('cert', 'key') pair. + :rtype: requests.Response + """ + # Create the Request. + req = Request( + method=method.upper(), + url=url, + headers=headers, + files=files, + data=data or {}, + json=json, + params=params or {}, + auth=auth, + cookies=cookies, + hooks=hooks, + ) + prep = self.prepare_request(req) + + proxies = proxies or {} + + settings = self.merge_environment_settings( + prep.url, proxies, stream, verify, cert + ) + + # Send the request. + send_kwargs = { + 'timeout': timeout, + 'allow_redirects': allow_redirects, + } + send_kwargs.update(settings) + resp = self.send(prep, **send_kwargs) + + return resp + + def get(self, url, **kwargs): + r"""Sends a GET request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('GET', url, **kwargs) + + def options(self, url, **kwargs): + r"""Sends a OPTIONS request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', True) + return self.request('OPTIONS', url, **kwargs) + + def head(self, url, **kwargs): + r"""Sends a HEAD request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + kwargs.setdefault('allow_redirects', False) + return self.request('HEAD', url, **kwargs) + + def post(self, url, data=None, json=None, **kwargs): + r"""Sends a POST request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param json: (optional) json to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('POST', url, data=data, json=json, **kwargs) + + def put(self, url, data=None, **kwargs): + r"""Sends a PUT request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PUT', url, data=data, **kwargs) + + def patch(self, url, data=None, **kwargs): + r"""Sends a PATCH request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param data: (optional) Dictionary, bytes, or file-like object to send in the body of the :class:`Request`. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('PATCH', url, data=data, **kwargs) + + def delete(self, url, **kwargs): + r"""Sends a DELETE request. Returns :class:`Response` object. + + :param url: URL for the new :class:`Request` object. + :param \*\*kwargs: Optional arguments that ``request`` takes. + :rtype: requests.Response + """ + + return self.request('DELETE', url, **kwargs) + + def send(self, request, **kwargs): + """Send a given PreparedRequest. + + :rtype: requests.Response + """ + # Set defaults that the hooks can utilize to ensure they always have + # the correct parameters to reproduce the previous request. + kwargs.setdefault('stream', self.stream) + kwargs.setdefault('verify', self.verify) + kwargs.setdefault('cert', self.cert) + kwargs.setdefault('proxies', self.proxies) + + # It's possible that users might accidentally send a Request object. + # Guard against that specific failure case. + if isinstance(request, Request): + raise ValueError('You can only send PreparedRequests.') + + # Set up variables needed for resolve_redirects and dispatching of hooks + allow_redirects = kwargs.pop('allow_redirects', True) + stream = kwargs.get('stream') + hooks = request.hooks + + # Get the appropriate adapter to use + adapter = self.get_adapter(url=request.url) + + # Start time (approximately) of the request + start = preferred_clock() + + # Send the request + r = adapter.send(request, **kwargs) + + # Total elapsed time of the request (approximately) + elapsed = preferred_clock() - start + r.elapsed = timedelta(seconds=elapsed) + + # Response manipulation hooks + r = dispatch_hook('response', hooks, r, **kwargs) + + # Persist cookies + if r.history: + + # If the hooks create history then we want those cookies too + for resp in r.history: + extract_cookies_to_jar(self.cookies, resp.request, resp.raw) + + extract_cookies_to_jar(self.cookies, request, r.raw) + + # Redirect resolving generator. + gen = self.resolve_redirects(r, request, **kwargs) + + # Resolve redirects if allowed. + history = [resp for resp in gen] if allow_redirects else [] + + # Shuffle things around if there's history. + if history: + # Insert the first (original) request at the start + history.insert(0, r) + # Get the last request made + r = history.pop() + r.history = history + + # If redirects aren't being followed, store the response on the Request for Response.next(). + if not allow_redirects: + try: + r._next = next(self.resolve_redirects(r, request, yield_requests=True, **kwargs)) + except StopIteration: + pass + + if not stream: + r.content + + return r + + def merge_environment_settings(self, url, proxies, stream, verify, cert): + """ + Check the environment and merge it with some settings. + + :rtype: dict + """ + # Gather clues from the surrounding environment. + if self.trust_env: + # Set environment's proxies. + no_proxy = proxies.get('no_proxy') if proxies is not None else None + env_proxies = get_environ_proxies(url, no_proxy=no_proxy) + for (k, v) in env_proxies.items(): + proxies.setdefault(k, v) + + # Look for requests environment configuration and be compatible + # with cURL. + if verify is True or verify is None: + verify = (os.environ.get('REQUESTS_CA_BUNDLE') or + os.environ.get('CURL_CA_BUNDLE')) + + # Merge all the kwargs. + proxies = merge_setting(proxies, self.proxies) + stream = merge_setting(stream, self.stream) + verify = merge_setting(verify, self.verify) + cert = merge_setting(cert, self.cert) + + return {'verify': verify, 'proxies': proxies, 'stream': stream, + 'cert': cert} + + def get_adapter(self, url): + """ + Returns the appropriate connection adapter for the given URL. + + :rtype: requests.adapters.BaseAdapter + """ + for (prefix, adapter) in self.adapters.items(): + + if url.lower().startswith(prefix.lower()): + return adapter + + # Nothing matches :-/ + raise InvalidSchema("No connection adapters were found for '%s'" % url) + + def close(self): + """Closes all adapters and as such the session""" + for v in self.adapters.values(): + v.close() + + def mount(self, prefix, adapter): + """Registers a connection adapter to a prefix. + + Adapters are sorted in descending order by prefix length. + """ + self.adapters[prefix] = adapter + keys_to_move = [k for k in self.adapters if len(k) < len(prefix)] + + for key in keys_to_move: + self.adapters[key] = self.adapters.pop(key) + + def __getstate__(self): + state = dict((attr, getattr(self, attr, None)) for attr in self.__attrs__) + return state + + def __setstate__(self, state): + for attr, value in state.items(): + setattr(self, attr, value) + + +def session(): + """ + Returns a :class:`Session` for context-management. + + :rtype: Session + """ + + return Session() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py new file mode 100644 index 0000000..ff462c6 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/status_codes.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- + +""" +The ``codes`` object defines a mapping from common names for HTTP statuses +to their numerical codes, accessible either as attributes or as dictionary +items. + +>>> requests.codes['temporary_redirect'] +307 +>>> requests.codes.teapot +418 +>>> requests.codes['\o/'] +200 + +Some codes have multiple names, and both upper- and lower-case versions of +the names are allowed. For example, ``codes.ok``, ``codes.OK``, and +``codes.okay`` all correspond to the HTTP status code 200. +""" + +from .structures import LookupDict + +_codes = { + + # Informational. + 100: ('continue',), + 101: ('switching_protocols',), + 102: ('processing',), + 103: ('checkpoint',), + 122: ('uri_too_long', 'request_uri_too_long'), + 200: ('ok', 'okay', 'all_ok', 'all_okay', 'all_good', '\\o/', '✓'), + 201: ('created',), + 202: ('accepted',), + 203: ('non_authoritative_info', 'non_authoritative_information'), + 204: ('no_content',), + 205: ('reset_content', 'reset'), + 206: ('partial_content', 'partial'), + 207: ('multi_status', 'multiple_status', 'multi_stati', 'multiple_stati'), + 208: ('already_reported',), + 226: ('im_used',), + + # Redirection. + 300: ('multiple_choices',), + 301: ('moved_permanently', 'moved', '\\o-'), + 302: ('found',), + 303: ('see_other', 'other'), + 304: ('not_modified',), + 305: ('use_proxy',), + 306: ('switch_proxy',), + 307: ('temporary_redirect', 'temporary_moved', 'temporary'), + 308: ('permanent_redirect', + 'resume_incomplete', 'resume',), # These 2 to be removed in 3.0 + + # Client Error. + 400: ('bad_request', 'bad'), + 401: ('unauthorized',), + 402: ('payment_required', 'payment'), + 403: ('forbidden',), + 404: ('not_found', '-o-'), + 405: ('method_not_allowed', 'not_allowed'), + 406: ('not_acceptable',), + 407: ('proxy_authentication_required', 'proxy_auth', 'proxy_authentication'), + 408: ('request_timeout', 'timeout'), + 409: ('conflict',), + 410: ('gone',), + 411: ('length_required',), + 412: ('precondition_failed', 'precondition'), + 413: ('request_entity_too_large',), + 414: ('request_uri_too_large',), + 415: ('unsupported_media_type', 'unsupported_media', 'media_type'), + 416: ('requested_range_not_satisfiable', 'requested_range', 'range_not_satisfiable'), + 417: ('expectation_failed',), + 418: ('im_a_teapot', 'teapot', 'i_am_a_teapot'), + 421: ('misdirected_request',), + 422: ('unprocessable_entity', 'unprocessable'), + 423: ('locked',), + 424: ('failed_dependency', 'dependency'), + 425: ('unordered_collection', 'unordered'), + 426: ('upgrade_required', 'upgrade'), + 428: ('precondition_required', 'precondition'), + 429: ('too_many_requests', 'too_many'), + 431: ('header_fields_too_large', 'fields_too_large'), + 444: ('no_response', 'none'), + 449: ('retry_with', 'retry'), + 450: ('blocked_by_windows_parental_controls', 'parental_controls'), + 451: ('unavailable_for_legal_reasons', 'legal_reasons'), + 499: ('client_closed_request',), + + # Server Error. + 500: ('internal_server_error', 'server_error', '/o\\', '✗'), + 501: ('not_implemented',), + 502: ('bad_gateway',), + 503: ('service_unavailable', 'unavailable'), + 504: ('gateway_timeout',), + 505: ('http_version_not_supported', 'http_version'), + 506: ('variant_also_negotiates',), + 507: ('insufficient_storage',), + 509: ('bandwidth_limit_exceeded', 'bandwidth'), + 510: ('not_extended',), + 511: ('network_authentication_required', 'network_auth', 'network_authentication'), +} + +codes = LookupDict(name='status_codes') + +def _init(): + for code, titles in _codes.items(): + for title in titles: + setattr(codes, title, code) + if not title.startswith(('\\', '/')): + setattr(codes, title.upper(), code) + + def doc(code): + names = ', '.join('``%s``' % n for n in _codes[code]) + return '* %d: %s' % (code, names) + + global __doc__ + __doc__ = (__doc__ + '\n' + + '\n'.join(doc(code) for code in sorted(_codes)) + if __doc__ is not None else None) + +_init() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/structures.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/structures.py new file mode 100644 index 0000000..da930e2 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/structures.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- + +""" +requests.structures +~~~~~~~~~~~~~~~~~~~ + +Data structures that power Requests. +""" + +from .compat import OrderedDict, Mapping, MutableMapping + + +class CaseInsensitiveDict(MutableMapping): + """A case-insensitive ``dict``-like object. + + Implements all methods and operations of + ``MutableMapping`` as well as dict's ``copy``. Also + provides ``lower_items``. + + All keys are expected to be strings. The structure remembers the + case of the last key to be set, and ``iter(instance)``, + ``keys()``, ``items()``, ``iterkeys()``, and ``iteritems()`` + will contain case-sensitive keys. However, querying and contains + testing is case insensitive:: + + cid = CaseInsensitiveDict() + cid['Accept'] = 'application/json' + cid['aCCEPT'] == 'application/json' # True + list(cid) == ['Accept'] # True + + For example, ``headers['content-encoding']`` will return the + value of a ``'Content-Encoding'`` response header, regardless + of how the header name was originally stored. + + If the constructor, ``.update``, or equality comparison + operations are given keys that have equal ``.lower()``s, the + behavior is undefined. + """ + + def __init__(self, data=None, **kwargs): + self._store = OrderedDict() + if data is None: + data = {} + self.update(data, **kwargs) + + def __setitem__(self, key, value): + # Use the lowercased key for lookups, but store the actual + # key alongside the value. + self._store[key.lower()] = (key, value) + + def __getitem__(self, key): + return self._store[key.lower()][1] + + def __delitem__(self, key): + del self._store[key.lower()] + + def __iter__(self): + return (casedkey for casedkey, mappedvalue in self._store.values()) + + def __len__(self): + return len(self._store) + + def lower_items(self): + """Like iteritems(), but with all lowercase keys.""" + return ( + (lowerkey, keyval[1]) + for (lowerkey, keyval) + in self._store.items() + ) + + def __eq__(self, other): + if isinstance(other, Mapping): + other = CaseInsensitiveDict(other) + else: + return NotImplemented + # Compare insensitively + return dict(self.lower_items()) == dict(other.lower_items()) + + # Copy is required + def copy(self): + return CaseInsensitiveDict(self._store.values()) + + def __repr__(self): + return str(dict(self.items())) + + +class LookupDict(dict): + """Dictionary lookup object.""" + + def __init__(self, name=None): + self.name = name + super(LookupDict, self).__init__() + + def __repr__(self): + return '<lookup \'%s\'>' % (self.name) + + def __getitem__(self, key): + # We allow fall-through here, so values default to None + + return self.__dict__.get(key, None) + + def get(self, key, default=None): + return self.__dict__.get(key, default) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/requests/utils.py b/env/lib/python3.7/site-packages/pip/_vendor/requests/utils.py new file mode 100644 index 0000000..431f6be --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/requests/utils.py @@ -0,0 +1,976 @@ +# -*- coding: utf-8 -*- + +""" +requests.utils +~~~~~~~~~~~~~~ + +This module provides utility functions that are used within Requests +that are also useful for external consumption. +""" + +import codecs +import contextlib +import io +import os +import re +import socket +import struct +import sys +import tempfile +import warnings +import zipfile + +from .__version__ import __version__ +from . import certs +# to_native_string is unused here, but imported here for backwards compatibility +from ._internal_utils import to_native_string +from .compat import parse_http_list as _parse_list_header +from .compat import ( + quote, urlparse, bytes, str, OrderedDict, unquote, getproxies, + proxy_bypass, urlunparse, basestring, integer_types, is_py3, + proxy_bypass_environment, getproxies_environment, Mapping) +from .cookies import cookiejar_from_dict +from .structures import CaseInsensitiveDict +from .exceptions import ( + InvalidURL, InvalidHeader, FileModeWarning, UnrewindableBodyError) + +NETRC_FILES = ('.netrc', '_netrc') + +DEFAULT_CA_BUNDLE_PATH = certs.where() + + +if sys.platform == 'win32': + # provide a proxy_bypass version on Windows without DNS lookups + + def proxy_bypass_registry(host): + try: + if is_py3: + import winreg + else: + import _winreg as winreg + except ImportError: + return False + + try: + internetSettings = winreg.OpenKey(winreg.HKEY_CURRENT_USER, + r'Software\Microsoft\Windows\CurrentVersion\Internet Settings') + # ProxyEnable could be REG_SZ or REG_DWORD, normalizing it + proxyEnable = int(winreg.QueryValueEx(internetSettings, + 'ProxyEnable')[0]) + # ProxyOverride is almost always a string + proxyOverride = winreg.QueryValueEx(internetSettings, + 'ProxyOverride')[0] + except OSError: + return False + if not proxyEnable or not proxyOverride: + return False + + # make a check value list from the registry entry: replace the + # '<local>' string by the localhost entry and the corresponding + # canonical entry. + proxyOverride = proxyOverride.split(';') + # now check if we match one of the registry values. + for test in proxyOverride: + if test == '<local>': + if '.' not in host: + return True + test = test.replace(".", r"\.") # mask dots + test = test.replace("*", r".*") # change glob sequence + test = test.replace("?", r".") # change glob char + if re.match(test, host, re.I): + return True + return False + + def proxy_bypass(host): # noqa + """Return True, if the host should be bypassed. + + Checks proxy settings gathered from the environment, if specified, + or the registry. + """ + if getproxies_environment(): + return proxy_bypass_environment(host) + else: + return proxy_bypass_registry(host) + + +def dict_to_sequence(d): + """Returns an internal sequence dictionary update.""" + + if hasattr(d, 'items'): + d = d.items() + + return d + + +def super_len(o): + total_length = None + current_position = 0 + + if hasattr(o, '__len__'): + total_length = len(o) + + elif hasattr(o, 'len'): + total_length = o.len + + elif hasattr(o, 'fileno'): + try: + fileno = o.fileno() + except io.UnsupportedOperation: + pass + else: + total_length = os.fstat(fileno).st_size + + # Having used fstat to determine the file length, we need to + # confirm that this file was opened up in binary mode. + if 'b' not in o.mode: + warnings.warn(( + "Requests has determined the content-length for this " + "request using the binary size of the file: however, the " + "file has been opened in text mode (i.e. without the 'b' " + "flag in the mode). This may lead to an incorrect " + "content-length. In Requests 3.0, support will be removed " + "for files in text mode."), + FileModeWarning + ) + + if hasattr(o, 'tell'): + try: + current_position = o.tell() + except (OSError, IOError): + # This can happen in some weird situations, such as when the file + # is actually a special file descriptor like stdin. In this + # instance, we don't know what the length is, so set it to zero and + # let requests chunk it instead. + if total_length is not None: + current_position = total_length + else: + if hasattr(o, 'seek') and total_length is None: + # StringIO and BytesIO have seek but no useable fileno + try: + # seek to end of file + o.seek(0, 2) + total_length = o.tell() + + # seek back to current position to support + # partially read file-like objects + o.seek(current_position or 0) + except (OSError, IOError): + total_length = 0 + + if total_length is None: + total_length = 0 + + return max(0, total_length - current_position) + + +def get_netrc_auth(url, raise_errors=False): + """Returns the Requests tuple auth for a given url from netrc.""" + + try: + from netrc import netrc, NetrcParseError + + netrc_path = None + + for f in NETRC_FILES: + try: + loc = os.path.expanduser('~/{0}'.format(f)) + except KeyError: + # os.path.expanduser can fail when $HOME is undefined and + # getpwuid fails. See http://bugs.python.org/issue20164 & + # https://github.com/requests/requests/issues/1846 + return + + if os.path.exists(loc): + netrc_path = loc + break + + # Abort early if there isn't one. + if netrc_path is None: + return + + ri = urlparse(url) + + # Strip port numbers from netloc. This weird `if...encode`` dance is + # used for Python 3.2, which doesn't support unicode literals. + splitstr = b':' + if isinstance(url, str): + splitstr = splitstr.decode('ascii') + host = ri.netloc.split(splitstr)[0] + + try: + _netrc = netrc(netrc_path).authenticators(host) + if _netrc: + # Return with login / password + login_i = (0 if _netrc[0] else 1) + return (_netrc[login_i], _netrc[2]) + except (NetrcParseError, IOError): + # If there was a parsing error or a permissions issue reading the file, + # we'll just skip netrc auth unless explicitly asked to raise errors. + if raise_errors: + raise + + # AppEngine hackiness. + except (ImportError, AttributeError): + pass + + +def guess_filename(obj): + """Tries to guess the filename of the given object.""" + name = getattr(obj, 'name', None) + if (name and isinstance(name, basestring) and name[0] != '<' and + name[-1] != '>'): + return os.path.basename(name) + + +def extract_zipped_paths(path): + """Replace nonexistent paths that look like they refer to a member of a zip + archive with the location of an extracted copy of the target, or else + just return the provided path unchanged. + """ + if os.path.exists(path): + # this is already a valid path, no need to do anything further + return path + + # find the first valid part of the provided path and treat that as a zip archive + # assume the rest of the path is the name of a member in the archive + archive, member = os.path.split(path) + while archive and not os.path.exists(archive): + archive, prefix = os.path.split(archive) + member = '/'.join([prefix, member]) + + if not zipfile.is_zipfile(archive): + return path + + zip_file = zipfile.ZipFile(archive) + if member not in zip_file.namelist(): + return path + + # we have a valid zip archive and a valid member of that archive + tmp = tempfile.gettempdir() + extracted_path = os.path.join(tmp, *member.split('/')) + if not os.path.exists(extracted_path): + extracted_path = zip_file.extract(member, path=tmp) + + return extracted_path + + +def from_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. Unless it can not be represented as such, return an + OrderedDict, e.g., + + :: + + >>> from_key_val_list([('key', 'val')]) + OrderedDict([('key', 'val')]) + >>> from_key_val_list('string') + ValueError: need more than 1 value to unpack + >>> from_key_val_list({'key': 'val'}) + OrderedDict([('key', 'val')]) + + :rtype: OrderedDict + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + return OrderedDict(value) + + +def to_key_val_list(value): + """Take an object and test to see if it can be represented as a + dictionary. If it can be, return a list of tuples, e.g., + + :: + + >>> to_key_val_list([('key', 'val')]) + [('key', 'val')] + >>> to_key_val_list({'key': 'val'}) + [('key', 'val')] + >>> to_key_val_list('string') + ValueError: cannot encode objects that are not 2-tuples. + + :rtype: list + """ + if value is None: + return None + + if isinstance(value, (str, bytes, bool, int)): + raise ValueError('cannot encode objects that are not 2-tuples') + + if isinstance(value, Mapping): + value = value.items() + + return list(value) + + +# From mitsuhiko/werkzeug (used with permission). +def parse_list_header(value): + """Parse lists as described by RFC 2068 Section 2. + + In particular, parse comma-separated lists where the elements of + the list may include quoted-strings. A quoted-string could + contain a comma. A non-quoted string could have quotes in the + middle. Quotes are removed automatically after parsing. + + It basically works like :func:`parse_set_header` just that items + may appear multiple times and case sensitivity is preserved. + + The return value is a standard :class:`list`: + + >>> parse_list_header('token, "quoted value"') + ['token', 'quoted value'] + + To create a header from the :class:`list` again, use the + :func:`dump_header` function. + + :param value: a string with a list header. + :return: :class:`list` + :rtype: list + """ + result = [] + for item in _parse_list_header(value): + if item[:1] == item[-1:] == '"': + item = unquote_header_value(item[1:-1]) + result.append(item) + return result + + +# From mitsuhiko/werkzeug (used with permission). +def parse_dict_header(value): + """Parse lists of key, value pairs as described by RFC 2068 Section 2 and + convert them into a python dict: + + >>> d = parse_dict_header('foo="is a fish", bar="as well"') + >>> type(d) is dict + True + >>> sorted(d.items()) + [('bar', 'as well'), ('foo', 'is a fish')] + + If there is no value for a key it will be `None`: + + >>> parse_dict_header('key_without_value') + {'key_without_value': None} + + To create a header from the :class:`dict` again, use the + :func:`dump_header` function. + + :param value: a string with a dict header. + :return: :class:`dict` + :rtype: dict + """ + result = {} + for item in _parse_list_header(value): + if '=' not in item: + result[item] = None + continue + name, value = item.split('=', 1) + if value[:1] == value[-1:] == '"': + value = unquote_header_value(value[1:-1]) + result[name] = value + return result + + +# From mitsuhiko/werkzeug (used with permission). +def unquote_header_value(value, is_filename=False): + r"""Unquotes a header value. (Reversal of :func:`quote_header_value`). + This does not use the real unquoting but what browsers are actually + using for quoting. + + :param value: the header value to unquote. + :rtype: str + """ + if value and value[0] == value[-1] == '"': + # this is not the real unquoting, but fixing this so that the + # RFC is met will result in bugs with internet explorer and + # probably some other browsers as well. IE for example is + # uploading files with "C:\foo\bar.txt" as filename + value = value[1:-1] + + # if this is a filename and the starting characters look like + # a UNC path, then just return the value without quotes. Using the + # replace sequence below on a UNC path has the effect of turning + # the leading double slash into a single slash and then + # _fix_ie_filename() doesn't work correctly. See #458. + if not is_filename or value[:2] != '\\\\': + return value.replace('\\\\', '\\').replace('\\"', '"') + return value + + +def dict_from_cookiejar(cj): + """Returns a key/value dictionary from a CookieJar. + + :param cj: CookieJar object to extract cookies from. + :rtype: dict + """ + + cookie_dict = {} + + for cookie in cj: + cookie_dict[cookie.name] = cookie.value + + return cookie_dict + + +def add_dict_to_cookiejar(cj, cookie_dict): + """Returns a CookieJar from a key/value dictionary. + + :param cj: CookieJar to insert cookies into. + :param cookie_dict: Dict of key/values to insert into CookieJar. + :rtype: CookieJar + """ + + return cookiejar_from_dict(cookie_dict, cj) + + +def get_encodings_from_content(content): + """Returns encodings from given content string. + + :param content: bytestring to extract encodings from. + """ + warnings.warn(( + 'In requests 3.0, get_encodings_from_content will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + charset_re = re.compile(r'<meta.*?charset=["\']*(.+?)["\'>]', flags=re.I) + pragma_re = re.compile(r'<meta.*?content=["\']*;?charset=(.+?)["\'>]', flags=re.I) + xml_re = re.compile(r'^<\?xml.*?encoding=["\']*(.+?)["\'>]') + + return (charset_re.findall(content) + + pragma_re.findall(content) + + xml_re.findall(content)) + + +def _parse_content_type_header(header): + """Returns content type and parameters from given header + + :param header: string + :return: tuple containing content type and dictionary of + parameters + """ + + tokens = header.split(';') + content_type, params = tokens[0].strip(), tokens[1:] + params_dict = {} + items_to_strip = "\"' " + + for param in params: + param = param.strip() + if param: + key, value = param, True + index_of_equals = param.find("=") + if index_of_equals != -1: + key = param[:index_of_equals].strip(items_to_strip) + value = param[index_of_equals + 1:].strip(items_to_strip) + params_dict[key] = value + return content_type, params_dict + + +def get_encoding_from_headers(headers): + """Returns encodings from given HTTP Header Dict. + + :param headers: dictionary to extract encoding from. + :rtype: str + """ + + content_type = headers.get('content-type') + + if not content_type: + return None + + content_type, params = _parse_content_type_header(content_type) + + if 'charset' in params: + return params['charset'].strip("'\"") + + if 'text' in content_type: + return 'ISO-8859-1' + + +def stream_decode_response_unicode(iterator, r): + """Stream decodes a iterator.""" + + if r.encoding is None: + for item in iterator: + yield item + return + + decoder = codecs.getincrementaldecoder(r.encoding)(errors='replace') + for chunk in iterator: + rv = decoder.decode(chunk) + if rv: + yield rv + rv = decoder.decode(b'', final=True) + if rv: + yield rv + + +def iter_slices(string, slice_length): + """Iterate over slices of a string.""" + pos = 0 + if slice_length is None or slice_length <= 0: + slice_length = len(string) + while pos < len(string): + yield string[pos:pos + slice_length] + pos += slice_length + + +def get_unicode_from_response(r): + """Returns the requested content back in unicode. + + :param r: Response object to get unicode content from. + + Tried: + + 1. charset from content-type + 2. fall back and replace all unicode characters + + :rtype: str + """ + warnings.warn(( + 'In requests 3.0, get_unicode_from_response will be removed. For ' + 'more information, please see the discussion on issue #2266. (This' + ' warning should only appear once.)'), + DeprecationWarning) + + tried_encodings = [] + + # Try charset from content-type + encoding = get_encoding_from_headers(r.headers) + + if encoding: + try: + return str(r.content, encoding) + except UnicodeError: + tried_encodings.append(encoding) + + # Fall back: + try: + return str(r.content, encoding, errors='replace') + except TypeError: + return r.content + + +# The unreserved URI characters (RFC 3986) +UNRESERVED_SET = frozenset( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + "0123456789-._~") + + +def unquote_unreserved(uri): + """Un-escape any percent-escape sequences in a URI that are unreserved + characters. This leaves all reserved, illegal and non-ASCII bytes encoded. + + :rtype: str + """ + parts = uri.split('%') + for i in range(1, len(parts)): + h = parts[i][0:2] + if len(h) == 2 and h.isalnum(): + try: + c = chr(int(h, 16)) + except ValueError: + raise InvalidURL("Invalid percent-escape sequence: '%s'" % h) + + if c in UNRESERVED_SET: + parts[i] = c + parts[i][2:] + else: + parts[i] = '%' + parts[i] + else: + parts[i] = '%' + parts[i] + return ''.join(parts) + + +def requote_uri(uri): + """Re-quote the given URI. + + This function passes the given URI through an unquote/quote cycle to + ensure that it is fully and consistently quoted. + + :rtype: str + """ + safe_with_percent = "!#$%&'()*+,/:;=?@[]~" + safe_without_percent = "!#$&'()*+,/:;=?@[]~" + try: + # Unquote only the unreserved characters + # Then quote only illegal characters (do not quote reserved, + # unreserved, or '%') + return quote(unquote_unreserved(uri), safe=safe_with_percent) + except InvalidURL: + # We couldn't unquote the given URI, so let's try quoting it, but + # there may be unquoted '%'s in the URI. We need to make sure they're + # properly quoted so they do not cause issues elsewhere. + return quote(uri, safe=safe_without_percent) + + +def address_in_network(ip, net): + """This function allows you to check if an IP belongs to a network subnet + + Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24 + returns False if ip = 192.168.1.1 and net = 192.168.100.0/24 + + :rtype: bool + """ + ipaddr = struct.unpack('=L', socket.inet_aton(ip))[0] + netaddr, bits = net.split('/') + netmask = struct.unpack('=L', socket.inet_aton(dotted_netmask(int(bits))))[0] + network = struct.unpack('=L', socket.inet_aton(netaddr))[0] & netmask + return (ipaddr & netmask) == (network & netmask) + + +def dotted_netmask(mask): + """Converts mask from /xx format to xxx.xxx.xxx.xxx + + Example: if mask is 24 function returns 255.255.255.0 + + :rtype: str + """ + bits = 0xffffffff ^ (1 << 32 - mask) - 1 + return socket.inet_ntoa(struct.pack('>I', bits)) + + +def is_ipv4_address(string_ip): + """ + :rtype: bool + """ + try: + socket.inet_aton(string_ip) + except socket.error: + return False + return True + + +def is_valid_cidr(string_network): + """ + Very simple check of the cidr format in no_proxy variable. + + :rtype: bool + """ + if string_network.count('/') == 1: + try: + mask = int(string_network.split('/')[1]) + except ValueError: + return False + + if mask < 1 or mask > 32: + return False + + try: + socket.inet_aton(string_network.split('/')[0]) + except socket.error: + return False + else: + return False + return True + + +@contextlib.contextmanager +def set_environ(env_name, value): + """Set the environment variable 'env_name' to 'value' + + Save previous value, yield, and then restore the previous value stored in + the environment variable 'env_name'. + + If 'value' is None, do nothing""" + value_changed = value is not None + if value_changed: + old_value = os.environ.get(env_name) + os.environ[env_name] = value + try: + yield + finally: + if value_changed: + if old_value is None: + del os.environ[env_name] + else: + os.environ[env_name] = old_value + + +def should_bypass_proxies(url, no_proxy): + """ + Returns whether we should bypass proxies or not. + + :rtype: bool + """ + # Prioritize lowercase environment variables over uppercase + # to keep a consistent behaviour with other http projects (curl, wget). + get_proxy = lambda k: os.environ.get(k) or os.environ.get(k.upper()) + + # First check whether no_proxy is defined. If it is, check that the URL + # we're getting isn't in the no_proxy list. + no_proxy_arg = no_proxy + if no_proxy is None: + no_proxy = get_proxy('no_proxy') + parsed = urlparse(url) + + if no_proxy: + # We need to check whether we match here. We need to see if we match + # the end of the hostname, both with and without the port. + no_proxy = ( + host for host in no_proxy.replace(' ', '').split(',') if host + ) + + if is_ipv4_address(parsed.hostname): + for proxy_ip in no_proxy: + if is_valid_cidr(proxy_ip): + if address_in_network(parsed.hostname, proxy_ip): + return True + elif parsed.hostname == proxy_ip: + # If no_proxy ip was defined in plain IP notation instead of cidr notation & + # matches the IP of the index + return True + else: + host_with_port = parsed.hostname + if parsed.port: + host_with_port += ':{0}'.format(parsed.port) + + for host in no_proxy: + if parsed.hostname.endswith(host) or host_with_port.endswith(host): + # The URL does match something in no_proxy, so we don't want + # to apply the proxies on this URL. + return True + + # If the system proxy settings indicate that this URL should be bypassed, + # don't proxy. + # The proxy_bypass function is incredibly buggy on OS X in early versions + # of Python 2.6, so allow this call to fail. Only catch the specific + # exceptions we've seen, though: this call failing in other ways can reveal + # legitimate problems. + with set_environ('no_proxy', no_proxy_arg): + try: + bypass = proxy_bypass(parsed.hostname) + except (TypeError, socket.gaierror): + bypass = False + + if bypass: + return True + + return False + + +def get_environ_proxies(url, no_proxy=None): + """ + Return a dict of environment proxies. + + :rtype: dict + """ + if should_bypass_proxies(url, no_proxy=no_proxy): + return {} + else: + return getproxies() + + +def select_proxy(url, proxies): + """Select a proxy for the url, if applicable. + + :param url: The url being for the request + :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs + """ + proxies = proxies or {} + urlparts = urlparse(url) + if urlparts.hostname is None: + return proxies.get(urlparts.scheme, proxies.get('all')) + + proxy_keys = [ + urlparts.scheme + '://' + urlparts.hostname, + urlparts.scheme, + 'all://' + urlparts.hostname, + 'all', + ] + proxy = None + for proxy_key in proxy_keys: + if proxy_key in proxies: + proxy = proxies[proxy_key] + break + + return proxy + + +def default_user_agent(name="python-requests"): + """ + Return a string representing the default user agent. + + :rtype: str + """ + return '%s/%s' % (name, __version__) + + +def default_headers(): + """ + :rtype: requests.structures.CaseInsensitiveDict + """ + return CaseInsensitiveDict({ + 'User-Agent': default_user_agent(), + 'Accept-Encoding': ', '.join(('gzip', 'deflate')), + 'Accept': '*/*', + 'Connection': 'keep-alive', + }) + + +def parse_header_links(value): + """Return a list of parsed link headers proxies. + + i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg" + + :rtype: list + """ + + links = [] + + replace_chars = ' \'"' + + value = value.strip(replace_chars) + if not value: + return links + + for val in re.split(', *<', value): + try: + url, params = val.split(';', 1) + except ValueError: + url, params = val, '' + + link = {'url': url.strip('<> \'"')} + + for param in params.split(';'): + try: + key, value = param.split('=') + except ValueError: + break + + link[key.strip(replace_chars)] = value.strip(replace_chars) + + links.append(link) + + return links + + +# Null bytes; no need to recreate these on each call to guess_json_utf +_null = '\x00'.encode('ascii') # encoding to ASCII for Python 3 +_null2 = _null * 2 +_null3 = _null * 3 + + +def guess_json_utf(data): + """ + :rtype: str + """ + # JSON always starts with two ASCII characters, so detection is as + # easy as counting the nulls and from their location and count + # determine the encoding. Also detect a BOM, if present. + sample = data[:4] + if sample in (codecs.BOM_UTF32_LE, codecs.BOM_UTF32_BE): + return 'utf-32' # BOM included + if sample[:3] == codecs.BOM_UTF8: + return 'utf-8-sig' # BOM included, MS style (discouraged) + if sample[:2] in (codecs.BOM_UTF16_LE, codecs.BOM_UTF16_BE): + return 'utf-16' # BOM included + nullcount = sample.count(_null) + if nullcount == 0: + return 'utf-8' + if nullcount == 2: + if sample[::2] == _null2: # 1st and 3rd are null + return 'utf-16-be' + if sample[1::2] == _null2: # 2nd and 4th are null + return 'utf-16-le' + # Did not detect 2 valid UTF-16 ascii-range characters + if nullcount == 3: + if sample[:3] == _null3: + return 'utf-32-be' + if sample[1:] == _null3: + return 'utf-32-le' + # Did not detect a valid UTF-32 ascii-range character + return None + + +def prepend_scheme_if_needed(url, new_scheme): + """Given a URL that may or may not have a scheme, prepend the given scheme. + Does not replace a present scheme with the one provided as an argument. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url, new_scheme) + + # urlparse is a finicky beast, and sometimes decides that there isn't a + # netloc present. Assume that it's being over-cautious, and switch netloc + # and path if urlparse decided there was no netloc. + if not netloc: + netloc, path = path, netloc + + return urlunparse((scheme, netloc, path, params, query, fragment)) + + +def get_auth_from_url(url): + """Given a url with authentication components, extract them into a tuple of + username,password. + + :rtype: (str,str) + """ + parsed = urlparse(url) + + try: + auth = (unquote(parsed.username), unquote(parsed.password)) + except (AttributeError, TypeError): + auth = ('', '') + + return auth + + +# Moved outside of function to avoid recompile every call +_CLEAN_HEADER_REGEX_BYTE = re.compile(b'^\\S[^\\r\\n]*$|^$') +_CLEAN_HEADER_REGEX_STR = re.compile(r'^\S[^\r\n]*$|^$') + + +def check_header_validity(header): + """Verifies that header value is a string which doesn't contain + leading whitespace or return characters. This prevents unintended + header injection. + + :param header: tuple, in the format (name, value). + """ + name, value = header + + if isinstance(value, bytes): + pat = _CLEAN_HEADER_REGEX_BYTE + else: + pat = _CLEAN_HEADER_REGEX_STR + try: + if not pat.match(value): + raise InvalidHeader("Invalid return character or leading space in header: %s" % name) + except TypeError: + raise InvalidHeader("Value for header {%s: %s} must be of type str or " + "bytes, not %s" % (name, value, type(value))) + + +def urldefragauth(url): + """ + Given a url remove the fragment and the authentication part. + + :rtype: str + """ + scheme, netloc, path, params, query, fragment = urlparse(url) + + # see func:`prepend_scheme_if_needed` + if not netloc: + netloc, path = path, netloc + + netloc = netloc.rsplit('@', 1)[-1] + + return urlunparse((scheme, netloc, path, params, query, '')) + + +def rewind_body(prepared_request): + """Move file pointer back to its recorded starting position + so it can be read again on redirect. + """ + body_seek = getattr(prepared_request.body, 'seek', None) + if body_seek is not None and isinstance(prepared_request._body_position, integer_types): + try: + body_seek(prepared_request._body_position) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect.") + else: + raise UnrewindableBodyError("Unable to rewind request body for redirect.") diff --git a/env/lib/python3.7/site-packages/pip/_vendor/retrying.py b/env/lib/python3.7/site-packages/pip/_vendor/retrying.py new file mode 100644 index 0000000..6d1e627 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/retrying.py @@ -0,0 +1,267 @@ +## Copyright 2013-2014 Ray Holder +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. + +import random +from pip._vendor import six +import sys +import time +import traceback + + +# sys.maxint / 2, since Python 3.2 doesn't have a sys.maxint... +MAX_WAIT = 1073741823 + + +def retry(*dargs, **dkw): + """ + Decorator function that instantiates the Retrying object + @param *dargs: positional arguments passed to Retrying object + @param **dkw: keyword arguments passed to the Retrying object + """ + # support both @retry and @retry() as valid syntax + if len(dargs) == 1 and callable(dargs[0]): + def wrap_simple(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying().call(f, *args, **kw) + + return wrapped_f + + return wrap_simple(dargs[0]) + + else: + def wrap(f): + + @six.wraps(f) + def wrapped_f(*args, **kw): + return Retrying(*dargs, **dkw).call(f, *args, **kw) + + return wrapped_f + + return wrap + + +class Retrying(object): + + def __init__(self, + stop=None, wait=None, + stop_max_attempt_number=None, + stop_max_delay=None, + wait_fixed=None, + wait_random_min=None, wait_random_max=None, + wait_incrementing_start=None, wait_incrementing_increment=None, + wait_exponential_multiplier=None, wait_exponential_max=None, + retry_on_exception=None, + retry_on_result=None, + wrap_exception=False, + stop_func=None, + wait_func=None, + wait_jitter_max=None): + + self._stop_max_attempt_number = 5 if stop_max_attempt_number is None else stop_max_attempt_number + self._stop_max_delay = 100 if stop_max_delay is None else stop_max_delay + self._wait_fixed = 1000 if wait_fixed is None else wait_fixed + self._wait_random_min = 0 if wait_random_min is None else wait_random_min + self._wait_random_max = 1000 if wait_random_max is None else wait_random_max + self._wait_incrementing_start = 0 if wait_incrementing_start is None else wait_incrementing_start + self._wait_incrementing_increment = 100 if wait_incrementing_increment is None else wait_incrementing_increment + self._wait_exponential_multiplier = 1 if wait_exponential_multiplier is None else wait_exponential_multiplier + self._wait_exponential_max = MAX_WAIT if wait_exponential_max is None else wait_exponential_max + self._wait_jitter_max = 0 if wait_jitter_max is None else wait_jitter_max + + # TODO add chaining of stop behaviors + # stop behavior + stop_funcs = [] + if stop_max_attempt_number is not None: + stop_funcs.append(self.stop_after_attempt) + + if stop_max_delay is not None: + stop_funcs.append(self.stop_after_delay) + + if stop_func is not None: + self.stop = stop_func + + elif stop is None: + self.stop = lambda attempts, delay: any(f(attempts, delay) for f in stop_funcs) + + else: + self.stop = getattr(self, stop) + + # TODO add chaining of wait behaviors + # wait behavior + wait_funcs = [lambda *args, **kwargs: 0] + if wait_fixed is not None: + wait_funcs.append(self.fixed_sleep) + + if wait_random_min is not None or wait_random_max is not None: + wait_funcs.append(self.random_sleep) + + if wait_incrementing_start is not None or wait_incrementing_increment is not None: + wait_funcs.append(self.incrementing_sleep) + + if wait_exponential_multiplier is not None or wait_exponential_max is not None: + wait_funcs.append(self.exponential_sleep) + + if wait_func is not None: + self.wait = wait_func + + elif wait is None: + self.wait = lambda attempts, delay: max(f(attempts, delay) for f in wait_funcs) + + else: + self.wait = getattr(self, wait) + + # retry on exception filter + if retry_on_exception is None: + self._retry_on_exception = self.always_reject + else: + self._retry_on_exception = retry_on_exception + + # TODO simplify retrying by Exception types + # retry on result filter + if retry_on_result is None: + self._retry_on_result = self.never_reject + else: + self._retry_on_result = retry_on_result + + self._wrap_exception = wrap_exception + + def stop_after_attempt(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the previous attempt >= stop_max_attempt_number.""" + return previous_attempt_number >= self._stop_max_attempt_number + + def stop_after_delay(self, previous_attempt_number, delay_since_first_attempt_ms): + """Stop after the time from the first attempt >= stop_max_delay.""" + return delay_since_first_attempt_ms >= self._stop_max_delay + + def no_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Don't sleep at all before retrying.""" + return 0 + + def fixed_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a fixed amount of time between each retry.""" + return self._wait_fixed + + def random_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """Sleep a random amount of time between wait_random_min and wait_random_max""" + return random.randint(self._wait_random_min, self._wait_random_max) + + def incrementing_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + """ + Sleep an incremental amount of time after each attempt, starting at + wait_incrementing_start and incrementing by wait_incrementing_increment + """ + result = self._wait_incrementing_start + (self._wait_incrementing_increment * (previous_attempt_number - 1)) + if result < 0: + result = 0 + return result + + def exponential_sleep(self, previous_attempt_number, delay_since_first_attempt_ms): + exp = 2 ** previous_attempt_number + result = self._wait_exponential_multiplier * exp + if result > self._wait_exponential_max: + result = self._wait_exponential_max + if result < 0: + result = 0 + return result + + def never_reject(self, result): + return False + + def always_reject(self, result): + return True + + def should_reject(self, attempt): + reject = False + if attempt.has_exception: + reject |= self._retry_on_exception(attempt.value[1]) + else: + reject |= self._retry_on_result(attempt.value) + + return reject + + def call(self, fn, *args, **kwargs): + start_time = int(round(time.time() * 1000)) + attempt_number = 1 + while True: + try: + attempt = Attempt(fn(*args, **kwargs), attempt_number, False) + except: + tb = sys.exc_info() + attempt = Attempt(tb, attempt_number, True) + + if not self.should_reject(attempt): + return attempt.get(self._wrap_exception) + + delay_since_first_attempt_ms = int(round(time.time() * 1000)) - start_time + if self.stop(attempt_number, delay_since_first_attempt_ms): + if not self._wrap_exception and attempt.has_exception: + # get() on an attempt with an exception should cause it to be raised, but raise just in case + raise attempt.get() + else: + raise RetryError(attempt) + else: + sleep = self.wait(attempt_number, delay_since_first_attempt_ms) + if self._wait_jitter_max: + jitter = random.random() * self._wait_jitter_max + sleep = sleep + max(0, jitter) + time.sleep(sleep / 1000.0) + + attempt_number += 1 + + +class Attempt(object): + """ + An Attempt encapsulates a call to a target function that may end as a + normal return value from the function or an Exception depending on what + occurred during the execution. + """ + + def __init__(self, value, attempt_number, has_exception): + self.value = value + self.attempt_number = attempt_number + self.has_exception = has_exception + + def get(self, wrap_exception=False): + """ + Return the return value of this Attempt instance or raise an Exception. + If wrap_exception is true, this Attempt is wrapped inside of a + RetryError before being raised. + """ + if self.has_exception: + if wrap_exception: + raise RetryError(self) + else: + six.reraise(self.value[0], self.value[1], self.value[2]) + else: + return self.value + + def __repr__(self): + if self.has_exception: + return "Attempts: {0}, Error:\n{1}".format(self.attempt_number, "".join(traceback.format_tb(self.value[2]))) + else: + return "Attempts: {0}, Value: {1}".format(self.attempt_number, self.value) + + +class RetryError(Exception): + """ + A RetryError encapsulates the last Attempt instance right before giving up. + """ + + def __init__(self, last_attempt): + self.last_attempt = last_attempt + + def __str__(self): + return "RetryError[{0}]".format(self.last_attempt) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/six.py b/env/lib/python3.7/site-packages/pip/_vendor/six.py new file mode 100644 index 0000000..6bf4fd3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/six.py @@ -0,0 +1,891 @@ +# Copyright (c) 2010-2017 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +"""Utilities for writing code that runs on Python 2 and 3""" + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.11.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("getoutput", "commands", "subprocess"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("email_mime_image", "email.MIMEImage", "email.mime.image"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote_to_bytes", "urllib", "urllib.parse", "unquote", "unquote_to_bytes"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("splitvalue", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), + MovedAttribute("parse_http_list", "urllib2", "urllib.request"), + MovedAttribute("parse_keqv_list", "urllib2", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + try: + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + finally: + value = None + tb = None + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + try: + raise tp, value, tb + finally: + tb = None +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + try: + if from_value is None: + raise value + raise value from from_value + finally: + value = None +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + try: + raise value from from_value + finally: + value = None +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(type): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + + @classmethod + def __prepare__(cls, name, this_bases): + return meta.__prepare__(name, bases) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py new file mode 100644 index 0000000..4bd533b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__init__.py @@ -0,0 +1,97 @@ +""" +urllib3 - Thread-safe connection pooling and re-using. +""" + +from __future__ import absolute_import +import warnings + +from .connectionpool import ( + HTTPConnectionPool, + HTTPSConnectionPool, + connection_from_url +) + +from . import exceptions +from .filepost import encode_multipart_formdata +from .poolmanager import PoolManager, ProxyManager, proxy_from_url +from .response import HTTPResponse +from .util.request import make_headers +from .util.url import get_host +from .util.timeout import Timeout +from .util.retry import Retry + + +# Set default logging handler to avoid "No handler found" warnings. +import logging +try: # Python 2.7+ + from logging import NullHandler +except ImportError: + class NullHandler(logging.Handler): + def emit(self, record): + pass + +__author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' +__license__ = 'MIT' +__version__ = '1.23' + +__all__ = ( + 'HTTPConnectionPool', + 'HTTPSConnectionPool', + 'PoolManager', + 'ProxyManager', + 'HTTPResponse', + 'Retry', + 'Timeout', + 'add_stderr_logger', + 'connection_from_url', + 'disable_warnings', + 'encode_multipart_formdata', + 'get_host', + 'make_headers', + 'proxy_from_url', +) + +logging.getLogger(__name__).addHandler(NullHandler()) + + +def add_stderr_logger(level=logging.DEBUG): + """ + Helper for quickly adding a StreamHandler to the logger. Useful for + debugging. + + Returns the handler after adding it. + """ + # This method needs to be in this __init__.py to get the __name__ correct + # even if urllib3 is vendored within another package. + logger = logging.getLogger(__name__) + handler = logging.StreamHandler() + handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) + logger.addHandler(handler) + logger.setLevel(level) + logger.debug('Added a stderr logging handler to logger: %s', __name__) + return handler + + +# ... Clean up. +del NullHandler + + +# All warning filters *must* be appended unless you're really certain that they +# shouldn't be: otherwise, it's very hard for users to use most Python +# mechanisms to silence them. +# SecurityWarning's always go off by default. +warnings.simplefilter('always', exceptions.SecurityWarning, append=True) +# SubjectAltNameWarning's should go off once per host +warnings.simplefilter('default', exceptions.SubjectAltNameWarning, append=True) +# InsecurePlatformWarning's don't vary between requests, so we keep it default. +warnings.simplefilter('default', exceptions.InsecurePlatformWarning, + append=True) +# SNIMissingWarnings should go off only once. +warnings.simplefilter('default', exceptions.SNIMissingWarning, append=True) + + +def disable_warnings(category=exceptions.HTTPWarning): + """ + Helper for quickly disabling all urllib3 warnings. + """ + warnings.simplefilter('ignore', category) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b6737a3f5e6680302dd85f8521819f1b2abc94d GIT binary patch literal 2379 zcmZ`)OLH4V5Z>8cNvnrtS+?WYPQns!uppKT!U0l&%7Z*ymAG87Q-K9)S!+h}I<pVY z&f1a6IVHu7-++DO?{J(er~Cy@bk9n$3B{_W)!j2Y)6?DGw|A$eY6d*s@7I1>sT;;$ zXiOdll-n?}Ux;B)!!szMCMS{UnFMu<Tb@O2TH<z8@=8(JD@PTt0&_Mkb0?~LRjpTe zEvkEUtvkFCO?gvM(`!c4-n8~rc`KUnX0%@8?P%7U)q0)JMf2Xg)*JjnwBRjheTrX< z7QIE#F@_~?Y1jg-$(N#KZ<!d+jrf{vuuCs$;!k4W@1a4bY3q$aTWo3n@@vam{=taN z?+rTRU7>C713K%ubk6&bEuCCtADxnukJ<8T<CG8s*01ylou?Px5bxTL%goyUgf6h^ z{wlpl7k{&01$vgi)A^6*)Bkurd*`X{Ux$5{=_S~Ajau7A=kn;QS}r&bcW=0B?#`ZI z0bR?2K686X9J8Jblh{p@gop9K4PxpFww7mLbZc+1VjZHUgWW9QxnzDArHPQ6Z=rBT z$5QP_J3CwV-fgo5yQo?8ZNKk4JIn8jB=R95*to`C_E?G$WMD0_xR+4oM>&^a8VKq4 z6A{rs25?jzH-8eu!GH<X*b>Rh;lygDXr14;fiXN~Sqd97*trn}FPOgvH)jG*at2KL zdr2liuk3^oOLA08Pni@$Q0kjG=Z_#6oQWPLVe*)u+=h|OfnbJ5pnXkj-!}%dET-EQ zGceV|h4|n<ChH!I%mzUXSVT7eFgm8PGsgR>ELblQRJ37Mi@(2Fmr=T&hUr=uXENY? zt#>qt_vOKt=+whMWHC*|`na;|z8}V+^!;u+R5pu3c?A#DQIJvV+;zG*x!JLm<NI+C zG2d4;-;WZSbJQEYe~<^fm=PByA)N&$=Fx|DygWI<A=)0T-ifJTLw5_Zm>jyRkUucH zsWxwCd%-9<>c&iVl=Wm|XJmig{o+QaDKIOdgrbT9c|$Z%v`|cgP%{CgekP%M!sp2V zT0oT1-=bj_>_Xs2frz1HGlAS9nkc4F0QDF>%s)OB3_M5I;sGeqI3dzJC9eo*)~WHz zJT^~k&`Xq@!jBlo<fMEIE3{TQ*4PD~Lrr)O*y`AXYFeXTYc4#G7*CmSp=sTNJnX&T zLl@%KuyVI0;4T`slq(Zg?lHHxO4ogsv3}0+MZFJYyZK<C5vXnG%3Q>mer2y{N;l|B zIBL9oD7$*$Xk}$J$N<q1>tycADrbjGmr`31%Q8SuCmUVALn)(f;1(&>abTE}%^|!Z zw43fq)~TurTChM>0XL6}{4YTM)YQMOr5YKN4*;@(gy2;5Oszqn<GU*d7CpwmR7qbH zuwBxDs&a9ts*K}!zv-6Y$gg2!SYM-BBMxbi8vGhW;G8N4{3sY^JAmMFkfwkTRiUgO z0H3^T0&E8CINb!;Vb}zeKxy&gQ<U@8|CO_7H(gQA-3hBsny)B=Du;tO5o{9x?o6g2 zH9(!5^+OJ+f%u$WAlV=h!}l+F2}1fAMuA;hpxx=Jitp2;SAeyjLq7mm1;Sfg2cep0 z{EAe54pSN@hN$2w2aabc(4K~gs^ikApwx5NL(C{gjM-B|(QD)~<XyoIat3cBv^+<< zAO{+5;}zI?z@-|sUTypmaB6{NWDHFes=lE=B=?0#gsMzh1BfWd<z6D-o^{{nVUGcS z7seqlH+(0+fK&h_!u65j1ool03PP2>yMOoDL){5t4IR_lte1;W4xbn7pys#p-F^7t z-QjW*sBhw4*nm@DCEMbG1Q14(iJ9%qjVED-AH#{Oj$f9sp=)!lewx6M9+h*eAk=S> wa<ZEsY_mZebFSQgW}SmE{@D&Op^2O1qHPoSS$3;!HD}FA+iaWA;AY$U2UC=W#Q*>R literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/_collections.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d4d54d0575a8e25f9918c67a7dee7f0c925b92f2 GIT binary patch literal 10703 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connection.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0d32310141f0149774a6f369d8905d4a752a428a GIT binary patch literal 10224 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/connectionpool.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..92640c1bd6794eb6d7739a9233b037b4c33d878b GIT binary patch literal 23758 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/exceptions.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3efb3a84a8b5f8d9241cf41898a09b181af5e4c9 GIT binary patch literal 10357 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 E4`qP#bN~PV literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/fields.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..62f5a01286bf1badbefa160b5f104d4275fa310e GIT binary patch literal 5825 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 E|2cIpG5`Po literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/filepost.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6f281bb2fdc49f756469406b31887c9f2a20130d GIT binary patch literal 2717 zcmbtWTW{P%6!wh0j^k`D-G)LDgrRCH7G*b}B7~N-pwc4cp(#*A#j0iF^~@$teA zlWgSh(g^XyUm$tpKk!TZ%2WPApEzf{xe!1q!mBwxGoH(t@0|0Uy+1weTkv#$z5VQP z(z5=*&go-=@;Nm1GYD>R5?cxB5`sF7X_uO}-L=iz={oSX<67c&U6|wWT0D_>UC-!l zJel}i-{=$ZR8sHOi6!i#Y3>~pK6%~h&TyYk9a`O4Ugy*Bp5rro7T#BQgU|6Rhosx! z^oiBHdIHv1O;XMVeU-(z7QHALW>T-h*u?#j7HZ}33907TD%yi#(g#uhMr`Lo=`SM@ z^Zi<`2dz&|@QxvFhz~BRLHh!lx(PyCM?}*jo0DVs9a!4gtVvc_M=qz>FDx*~-e2_@ zJdbn9MA8qW43vt}^?1}$U|B4f6vH?OMIuto2AO0@ln9+=v1*4KS*Ap<pXDhJ<fv^n zI+=r`%UYnqC~8iWUO!5WUQTR?y*L_-N}8#1B9}qRvqYlBrTx|ScS@IwFyjL5>YeWR zn<X3Y{pH;yoeY<T(XbVzN(XV=3U}AjO}+gQ4w}~65wM?J%4Hl!{X0v8C>Fy^>Gp6` z&R#Nf7WPyg2+NrxF7b(+2R%dp@j+A_Xo##@1)%{dO<quW4dE;-0FR`eb_(kSXnXG$ z<bn14#sP(SRM%i$r=Z_~Kelh`+NN93U#zP46rvCyr~5w{q*k<$ffg*=5t0qiud3~v zFHiCz#)M*Vq%_M0?7gi;w$o%f2ZtyI$T1#;S}htCCn=a^mUhAz9N1a=aSTLzyz#~G zSsNd-3jXmU@HSwYhN5(E)5;^05f}$8QKf^boB$lkse#OrUS&noF5PPHl0;?AsK#5B zxQg=|xU^?J^|Jn^0F$pHs52le&nI>2Q6KR4sC*kn&OCsgKo6KuUIgXL0}GsRdT5>c z;Q@Hy3FIw~6;{=2IzbCIFle;fjEkWZA>hnA9rj`S;|k%Gf5raW4Z#A=BOPTaLjOvD zvLx67$LNhnu|b}OxY!twVU`Om+H3_-76D&mxe}~{lR9gEhi7e(?QTTj24tPiWvX7? zr)&)He+;22Y0r?y*vF=@y$PbQo;RM+19CtMQqVya*T9_+$7I#G8Ulf~KPbsoNp>y; zz{|<yb&-m_p}g0@4Jio6+Fv-ow`woPSs29XUi)n7|1(A|z#;M-6buCt$azT0ccHrs zZEQ=^k+0!|YbcP5<m(`sMB?2qtu3c6*xiEf$^~K7eKJqw4bVcoA3iva&BX8TplIub zg$Q!8<;i*A5({{v&=eU2xMO%=7r-pq;V|bKj2%Or(zSxVAiy{Fk$ViBL#)EyoH%f_ zS2%hSSmp=q7Y;B`H8QnXhq3*$RSvF5ecZP&I%?d;(d~t&z*Ocu=fZhDuT{MRIQeM$ z*eYrRtXXdG^=UpmOp&5lVCV;899SQ7WNoctg0(e>ZYUm*2!bVftfOHd^%7K#q{Rar zutzJ89%2zm0zHn?4$KIWG5vK+xHEVj027_>U+vDI_?#1>7%je9ZZ`jV(rIluKWk;c z(o8co6k!A>L5hO;DO|EDQS5XD+l}Iw^##M2M&{<#ZO@DzXZ1Prj!V#`@&ojXS6tn9 zTdiAa+Bcy%?eBZoZM8uAC+t2wv*Ye9)tr%-rKWBf>MU!!NY@ghu5>HCoRLryfq*xF zcZ38cM<1AYFYPGRrLD9a)4djZx~E4&QF`k_?*wr!nr@W@S8z+GpYf4=3(vfb{d$<C z8vYTOHJ9_`x-enVJBxrGx*QMx4Av?J!kTi4M_f8X8ngj#tO0d0M}0a&8?;U(<`*zb z^J?k$dV?IuQ1p5d6HHElC|wN1P|0cR&?qx_l-@81w}N${%(c4p({3C7Nf~UaE16>E z##y$N4<-IpItS7uvN`?2tqg~lismgR8P8*J4@;DK14JF}0Y9+0PT)spY|r=Ry~dv} CIlL7B literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/poolmanager.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0670dc8489ee7a873fea408dd22d34c3833feba8 GIT binary patch literal 12656 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%0D+glI~`gtyHx3^4%O*SQn$O^b&w+L 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 AmjD0& literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/request.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8916a608f46230b4ad68bba4b73b4e4364e48477 GIT binary patch literal 5548 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 OQP;i<j=o%}RsIP_VO+id literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/__pycache__/response.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4ea3e896a95f86facf32ac856f37ff96b172805b GIT binary patch literal 17374 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py new file mode 100644 index 0000000..6e36b84 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/_collections.py @@ -0,0 +1,332 @@ +from __future__ import absolute_import +try: + from collections.abc import Mapping, MutableMapping +except ImportError: + from collections import Mapping, MutableMapping +try: + from threading import RLock +except ImportError: # Platform-specific: No threads available + class RLock: + def __enter__(self): + pass + + def __exit__(self, exc_type, exc_value, traceback): + pass + + +try: # Python 2.7+ + from collections import OrderedDict +except ImportError: + from .packages.ordered_dict import OrderedDict +from .exceptions import InvalidHeader +from .packages.six import iterkeys, itervalues, PY3 + + +__all__ = ['RecentlyUsedContainer', 'HTTPHeaderDict'] + + +_Null = object() + + +class RecentlyUsedContainer(MutableMapping): + """ + Provides a thread-safe dict-like container which maintains up to + ``maxsize`` keys while throwing away the least-recently-used keys beyond + ``maxsize``. + + :param maxsize: + Maximum number of recent elements to retain. + + :param dispose_func: + Every time an item is evicted from the container, + ``dispose_func(value)`` is called. Callback which will get called + """ + + ContainerCls = OrderedDict + + def __init__(self, maxsize=10, dispose_func=None): + self._maxsize = maxsize + self.dispose_func = dispose_func + + self._container = self.ContainerCls() + self.lock = RLock() + + def __getitem__(self, key): + # Re-insert the item, moving it to the end of the eviction line. + with self.lock: + item = self._container.pop(key) + self._container[key] = item + return item + + def __setitem__(self, key, value): + evicted_value = _Null + with self.lock: + # Possibly evict the existing value of 'key' + evicted_value = self._container.get(key, _Null) + self._container[key] = value + + # If we didn't evict an existing value, we might have to evict the + # least recently used item from the beginning of the container. + if len(self._container) > self._maxsize: + _key, evicted_value = self._container.popitem(last=False) + + if self.dispose_func and evicted_value is not _Null: + self.dispose_func(evicted_value) + + def __delitem__(self, key): + with self.lock: + value = self._container.pop(key) + + if self.dispose_func: + self.dispose_func(value) + + def __len__(self): + with self.lock: + return len(self._container) + + def __iter__(self): + raise NotImplementedError('Iteration over this class is unlikely to be threadsafe.') + + def clear(self): + with self.lock: + # Copy pointers to all values, then wipe the mapping + values = list(itervalues(self._container)) + self._container.clear() + + if self.dispose_func: + for value in values: + self.dispose_func(value) + + def keys(self): + with self.lock: + return list(iterkeys(self._container)) + + +class HTTPHeaderDict(MutableMapping): + """ + :param headers: + An iterable of field-value pairs. Must not contain multiple field names + when compared case-insensitively. + + :param kwargs: + Additional field-value pairs to pass in to ``dict.update``. + + A ``dict`` like container for storing HTTP Headers. + + Field names are stored and compared case-insensitively in compliance with + RFC 7230. Iteration provides the first case-sensitive key seen for each + case-insensitive pair. + + Using ``__setitem__`` syntax overwrites fields that compare equal + case-insensitively in order to maintain ``dict``'s api. For fields that + compare equal, instead create a new ``HTTPHeaderDict`` and use ``.add`` + in a loop. + + If multiple fields that are equal case-insensitively are passed to the + constructor or ``.update``, the behavior is undefined and some will be + lost. + + >>> headers = HTTPHeaderDict() + >>> headers.add('Set-Cookie', 'foo=bar') + >>> headers.add('set-cookie', 'baz=quxx') + >>> headers['content-length'] = '7' + >>> headers['SET-cookie'] + 'foo=bar, baz=quxx' + >>> headers['Content-Length'] + '7' + """ + + def __init__(self, headers=None, **kwargs): + super(HTTPHeaderDict, self).__init__() + self._container = OrderedDict() + if headers is not None: + if isinstance(headers, HTTPHeaderDict): + self._copy_from(headers) + else: + self.extend(headers) + if kwargs: + self.extend(kwargs) + + def __setitem__(self, key, val): + self._container[key.lower()] = [key, val] + return self._container[key.lower()] + + def __getitem__(self, key): + val = self._container[key.lower()] + return ', '.join(val[1:]) + + def __delitem__(self, key): + del self._container[key.lower()] + + def __contains__(self, key): + return key.lower() in self._container + + def __eq__(self, other): + if not isinstance(other, Mapping) and not hasattr(other, 'keys'): + return False + if not isinstance(other, type(self)): + other = type(self)(other) + return (dict((k.lower(), v) for k, v in self.itermerged()) == + dict((k.lower(), v) for k, v in other.itermerged())) + + def __ne__(self, other): + return not self.__eq__(other) + + if not PY3: # Python 2 + iterkeys = MutableMapping.iterkeys + itervalues = MutableMapping.itervalues + + __marker = object() + + def __len__(self): + return len(self._container) + + def __iter__(self): + # Only provide the originally cased names + for vals in self._container.values(): + yield vals[0] + + def pop(self, key, default=__marker): + '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + ''' + # Using the MutableMapping function directly fails due to the private marker. + # Using ordinary dict.pop would expose the internal structures. + # So let's reinvent the wheel. + try: + value = self[key] + except KeyError: + if default is self.__marker: + raise + return default + else: + del self[key] + return value + + def discard(self, key): + try: + del self[key] + except KeyError: + pass + + def add(self, key, val): + """Adds a (name, value) pair, doesn't overwrite the value if it already + exists. + + >>> headers = HTTPHeaderDict(foo='bar') + >>> headers.add('Foo', 'baz') + >>> headers['foo'] + 'bar, baz' + """ + key_lower = key.lower() + new_vals = [key, val] + # Keep the common case aka no item present as fast as possible + vals = self._container.setdefault(key_lower, new_vals) + if new_vals is not vals: + vals.append(val) + + def extend(self, *args, **kwargs): + """Generic import function for any type of header-like object. + Adapted version of MutableMapping.update in order to insert items + with self.add instead of self.__setitem__ + """ + if len(args) > 1: + raise TypeError("extend() takes at most 1 positional " + "arguments ({0} given)".format(len(args))) + other = args[0] if len(args) >= 1 else () + + if isinstance(other, HTTPHeaderDict): + for key, val in other.iteritems(): + self.add(key, val) + elif isinstance(other, Mapping): + for key in other: + self.add(key, other[key]) + elif hasattr(other, "keys"): + for key in other.keys(): + self.add(key, other[key]) + else: + for key, value in other: + self.add(key, value) + + for key, value in kwargs.items(): + self.add(key, value) + + def getlist(self, key, default=__marker): + """Returns a list of all the values for the named field. Returns an + empty list if the key doesn't exist.""" + try: + vals = self._container[key.lower()] + except KeyError: + if default is self.__marker: + return [] + return default + else: + return vals[1:] + + # Backwards compatibility for httplib + getheaders = getlist + getallmatchingheaders = getlist + iget = getlist + + # Backwards compatibility for http.cookiejar + get_all = getlist + + def __repr__(self): + return "%s(%s)" % (type(self).__name__, dict(self.itermerged())) + + def _copy_from(self, other): + for key in other: + val = other.getlist(key) + if isinstance(val, list): + # Don't need to convert tuples + val = list(val) + self._container[key.lower()] = [key] + val + + def copy(self): + clone = type(self)() + clone._copy_from(self) + return clone + + def iteritems(self): + """Iterate over all header lines, including duplicate ones.""" + for key in self: + vals = self._container[key.lower()] + for val in vals[1:]: + yield vals[0], val + + def itermerged(self): + """Iterate over all headers, merging duplicate ones together.""" + for key in self: + val = self._container[key.lower()] + yield val[0], ', '.join(val[1:]) + + def items(self): + return list(self.iteritems()) + + @classmethod + def from_httplib(cls, message): # Python 2 + """Read headers from a Python 2 httplib message object.""" + # python2.7 does not expose a proper API for exporting multiheaders + # efficiently. This function re-reads raw lines from the message + # object and extracts the multiheaders properly. + obs_fold_continued_leaders = (' ', '\t') + headers = [] + + for line in message.headers: + if line.startswith(obs_fold_continued_leaders): + if not headers: + # We received a header line that starts with OWS as described + # in RFC-7230 S3.2.4. This indicates a multiline header, but + # there exists no previous header to which we can attach it. + raise InvalidHeader( + 'Header continuation with no previous header: %s' % line + ) + else: + key, value = headers[-1] + headers[-1] = (key, value + ' ' + line.strip()) + continue + + key, value = line.split(':', 1) + headers.append((key, value.strip())) + + return cls(headers) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py new file mode 100644 index 0000000..a03b573 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/connection.py @@ -0,0 +1,403 @@ +from __future__ import absolute_import +import datetime +import logging +import os +import sys +import socket +from socket import error as SocketError, timeout as SocketTimeout +import warnings +from .packages import six +from .packages.six.moves.http_client import HTTPConnection as _HTTPConnection +from .packages.six.moves.http_client import HTTPException # noqa: F401 + +try: # Compiled with SSL? + import ssl + BaseSSLError = ssl.SSLError +except (ImportError, AttributeError): # Platform-specific: No SSL. + ssl = None + + class BaseSSLError(BaseException): + pass + + +try: # Python 3: + # Not a no-op, we're adding this to the namespace so it can be imported. + ConnectionError = ConnectionError +except NameError: # Python 2: + class ConnectionError(Exception): + pass + + +from .exceptions import ( + NewConnectionError, + ConnectTimeoutError, + SubjectAltNameWarning, + SystemTimeWarning, +) +from .packages.ssl_match_hostname import match_hostname, CertificateError + +from .util.ssl_ import ( + resolve_cert_reqs, + resolve_ssl_version, + assert_fingerprint, + create_urllib3_context, + ssl_wrap_socket +) + + +from .util import connection + +from ._collections import HTTPHeaderDict + +log = logging.getLogger(__name__) + +port_by_scheme = { + 'http': 80, + 'https': 443, +} + +# When updating RECENT_DATE, move it to within two years of the current date, +# and not less than 6 months ago. +# Example: if Today is 2018-01-01, then RECENT_DATE should be any date on or +# after 2016-01-01 (today - 2 years) AND before 2017-07-01 (today - 6 months) +RECENT_DATE = datetime.date(2017, 6, 30) + + +class DummyConnection(object): + """Used to detect a failed ConnectionCls import.""" + pass + + +class HTTPConnection(_HTTPConnection, object): + """ + Based on httplib.HTTPConnection but provides an extra constructor + backwards-compatibility layer between older and newer Pythons. + + Additional keyword parameters are used to configure attributes of the connection. + Accepted parameters include: + + - ``strict``: See the documentation on :class:`urllib3.connectionpool.HTTPConnectionPool` + - ``source_address``: Set the source address for the current connection. + + .. note:: This is ignored for Python 2.6. It is only applied for 2.7 and 3.x + + - ``socket_options``: Set specific options on the underlying socket. If not specified, then + defaults are loaded from ``HTTPConnection.default_socket_options`` which includes disabling + Nagle's algorithm (sets TCP_NODELAY to 1) unless the connection is behind a proxy. + + For example, if you wish to enable TCP Keep Alive in addition to the defaults, + you might pass:: + + HTTPConnection.default_socket_options + [ + (socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1), + ] + + Or you may want to disable the defaults by passing an empty list (e.g., ``[]``). + """ + + default_port = port_by_scheme['http'] + + #: Disable Nagle's algorithm by default. + #: ``[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)]`` + default_socket_options = [(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)] + + #: Whether this connection verifies the host's certificate. + is_verified = False + + def __init__(self, *args, **kw): + if six.PY3: # Python 3 + kw.pop('strict', None) + + # Pre-set source_address in case we have an older Python like 2.6. + self.source_address = kw.get('source_address') + + if sys.version_info < (2, 7): # Python 2.6 + # _HTTPConnection on Python 2.6 will balk at this keyword arg, but + # not newer versions. We can still use it when creating a + # connection though, so we pop it *after* we have saved it as + # self.source_address. + kw.pop('source_address', None) + + #: The socket options provided by the user. If no options are + #: provided, we use the default options. + self.socket_options = kw.pop('socket_options', self.default_socket_options) + + # Superclass also sets self.source_address in Python 2.7+. + _HTTPConnection.__init__(self, *args, **kw) + + @property + def host(self): + """ + Getter method to remove any trailing dots that indicate the hostname is an FQDN. + + In general, SSL certificates don't include the trailing dot indicating a + fully-qualified domain name, and thus, they don't validate properly when + checked against a domain name that includes the dot. In addition, some + servers may not expect to receive the trailing dot when provided. + + However, the hostname with trailing dot is critical to DNS resolution; doing a + lookup with the trailing dot will properly only resolve the appropriate FQDN, + whereas a lookup without a trailing dot will search the system's search domain + list. Thus, it's important to keep the original host around for use only in + those cases where it's appropriate (i.e., when doing DNS lookup to establish the + actual TCP connection across which we're going to send HTTP requests). + """ + return self._dns_host.rstrip('.') + + @host.setter + def host(self, value): + """ + Setter for the `host` property. + + We assume that only urllib3 uses the _dns_host attribute; httplib itself + only uses `host`, and it seems reasonable that other libraries follow suit. + """ + self._dns_host = value + + def _new_conn(self): + """ Establish a socket connection and set nodelay settings on it. + + :return: New socket connection. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = connection.create_connection( + (self._dns_host, self.port), self.timeout, **extra_kw) + + except SocketTimeout as e: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + + except SocketError as e: + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e) + + return conn + + def _prepare_conn(self, conn): + self.sock = conn + # the _tunnel_host attribute was added in python 2.6.3 (via + # http://hg.python.org/cpython/rev/0f57b30a152f) so pythons 2.6(0-2) do + # not have them. + if getattr(self, '_tunnel_host', None): + # TODO: Fix tunnel so it doesn't depend on self.sock state. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + def request_chunked(self, method, url, body=None, headers=None): + """ + Alternative to the common request method, which sends the + body with chunked encoding and not as one block + """ + headers = HTTPHeaderDict(headers if headers is not None else {}) + skip_accept_encoding = 'accept-encoding' in headers + skip_host = 'host' in headers + self.putrequest( + method, + url, + skip_accept_encoding=skip_accept_encoding, + skip_host=skip_host + ) + for header, value in headers.items(): + self.putheader(header, value) + if 'transfer-encoding' not in headers: + self.putheader('Transfer-Encoding', 'chunked') + self.endheaders() + + if body is not None: + stringish_types = six.string_types + (six.binary_type,) + if isinstance(body, stringish_types): + body = (body,) + for chunk in body: + if not chunk: + continue + if not isinstance(chunk, six.binary_type): + chunk = chunk.encode('utf8') + len_str = hex(len(chunk))[2:] + self.send(len_str.encode('utf-8')) + self.send(b'\r\n') + self.send(chunk) + self.send(b'\r\n') + + # After the if clause, to always have a closed body + self.send(b'0\r\n\r\n') + + +class HTTPSConnection(HTTPConnection): + default_port = port_by_scheme['https'] + + ssl_version = None + + def __init__(self, host, port=None, key_file=None, cert_file=None, + strict=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + ssl_context=None, **kw): + + HTTPConnection.__init__(self, host, port, strict=strict, + timeout=timeout, **kw) + + self.key_file = key_file + self.cert_file = cert_file + self.ssl_context = ssl_context + + # Required property for Google AppEngine 1.9.0 which otherwise causes + # HTTPS requests to go out as HTTP. (See Issue #356) + self._protocol = 'https' + + def connect(self): + conn = self._new_conn() + self._prepare_conn(conn) + + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(None), + cert_reqs=resolve_cert_reqs(None), + ) + + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ssl_context=self.ssl_context, + ) + + +class VerifiedHTTPSConnection(HTTPSConnection): + """ + Based on httplib.HTTPSConnection but wraps the socket with + SSL certification. + """ + cert_reqs = None + ca_certs = None + ca_cert_dir = None + ssl_version = None + assert_fingerprint = None + + def set_cert(self, key_file=None, cert_file=None, + cert_reqs=None, ca_certs=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None): + """ + This method should only be called once, before the connection is used. + """ + # If cert_reqs is not provided, we can try to guess. If the user gave + # us a cert database, we assume they want to use it: otherwise, if + # they gave us an SSL Context object we should use whatever is set for + # it. + if cert_reqs is None: + if ca_certs or ca_cert_dir: + cert_reqs = 'CERT_REQUIRED' + elif self.ssl_context is not None: + cert_reqs = self.ssl_context.verify_mode + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + self.ca_certs = ca_certs and os.path.expanduser(ca_certs) + self.ca_cert_dir = ca_cert_dir and os.path.expanduser(ca_cert_dir) + + def connect(self): + # Add certificate verification + conn = self._new_conn() + + hostname = self.host + if getattr(self, '_tunnel_host', None): + # _tunnel_host was added in Python 2.6.3 + # (See: http://hg.python.org/cpython/rev/0f57b30a152f) + + self.sock = conn + # Calls self._set_hostport(), so self.host is + # self._tunnel_host below. + self._tunnel() + # Mark this connection as not reusable + self.auto_open = 0 + + # Override the host with the one we're requesting data from. + hostname = self._tunnel_host + + is_time_off = datetime.date.today() < RECENT_DATE + if is_time_off: + warnings.warn(( + 'System time is way off (before {0}). This will probably ' + 'lead to SSL verification errors').format(RECENT_DATE), + SystemTimeWarning + ) + + # Wrap socket using verification with the root certs in + # trusted_root_certs + if self.ssl_context is None: + self.ssl_context = create_urllib3_context( + ssl_version=resolve_ssl_version(self.ssl_version), + cert_reqs=resolve_cert_reqs(self.cert_reqs), + ) + + context = self.ssl_context + context.verify_mode = resolve_cert_reqs(self.cert_reqs) + self.sock = ssl_wrap_socket( + sock=conn, + keyfile=self.key_file, + certfile=self.cert_file, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + server_hostname=hostname, + ssl_context=context) + + if self.assert_fingerprint: + assert_fingerprint(self.sock.getpeercert(binary_form=True), + self.assert_fingerprint) + elif context.verify_mode != ssl.CERT_NONE \ + and not getattr(context, 'check_hostname', False) \ + and self.assert_hostname is not False: + # While urllib3 attempts to always turn off hostname matching from + # the TLS library, this cannot always be done. So we check whether + # the TLS Library still thinks it's matching hostnames. + cert = self.sock.getpeercert() + if not cert.get('subjectAltName', ()): + warnings.warn(( + 'Certificate for {0} has no `subjectAltName`, falling back to check for a ' + '`commonName` for now. This feature is being removed by major browsers and ' + 'deprecated by RFC 2818. (See https://github.com/shazow/urllib3/issues/497 ' + 'for details.)'.format(hostname)), + SubjectAltNameWarning + ) + _match_hostname(cert, self.assert_hostname or hostname) + + self.is_verified = ( + context.verify_mode == ssl.CERT_REQUIRED or + self.assert_fingerprint is not None + ) + + +def _match_hostname(cert, asserted_hostname): + try: + match_hostname(cert, asserted_hostname) + except CertificateError as e: + log.error( + 'Certificate did not match expected hostname: %s. ' + 'Certificate: %s', asserted_hostname, cert + ) + # Add cert to exception and reraise so client code can inspect + # the cert when catching the exception, if they want to + e._peer_cert = cert + raise + + +if ssl: + # Make a copy for testing. + UnverifiedHTTPSConnection = HTTPSConnection + HTTPSConnection = VerifiedHTTPSConnection +else: + HTTPSConnection = DummyConnection diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py new file mode 100644 index 0000000..8fcb0bc --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/connectionpool.py @@ -0,0 +1,906 @@ +from __future__ import absolute_import +import errno +import logging +import sys +import warnings + +from socket import error as SocketError, timeout as SocketTimeout +import socket + + +from .exceptions import ( + ClosedPoolError, + ProtocolError, + EmptyPoolError, + HeaderParsingError, + HostChangedError, + LocationValueError, + MaxRetryError, + ProxyError, + ReadTimeoutError, + SSLError, + TimeoutError, + InsecureRequestWarning, + NewConnectionError, +) +from .packages.ssl_match_hostname import CertificateError +from .packages import six +from .packages.six.moves import queue +from .connection import ( + port_by_scheme, + DummyConnection, + HTTPConnection, HTTPSConnection, VerifiedHTTPSConnection, + HTTPException, BaseSSLError, +) +from .request import RequestMethods +from .response import HTTPResponse + +from .util.connection import is_connection_dropped +from .util.request import set_file_position +from .util.response import assert_header_parsing +from .util.retry import Retry +from .util.timeout import Timeout +from .util.url import get_host, Url, NORMALIZABLE_SCHEMES +from .util.queue import LifoQueue + + +xrange = six.moves.xrange + +log = logging.getLogger(__name__) + +_Default = object() + + +# Pool objects +class ConnectionPool(object): + """ + Base class for all connection pools, such as + :class:`.HTTPConnectionPool` and :class:`.HTTPSConnectionPool`. + """ + + scheme = None + QueueCls = LifoQueue + + def __init__(self, host, port=None): + if not host: + raise LocationValueError("No host specified.") + + self.host = _ipv6_host(host, self.scheme) + self._proxy_host = host.lower() + self.port = port + + def __str__(self): + return '%s(host=%r, port=%r)' % (type(self).__name__, + self.host, self.port) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.close() + # Return False to re-raise any potential exceptions + return False + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + pass + + +# This is taken from http://hg.python.org/cpython/file/7aaba721ebc0/Lib/socket.py#l252 +_blocking_errnos = set([errno.EAGAIN, errno.EWOULDBLOCK]) + + +class HTTPConnectionPool(ConnectionPool, RequestMethods): + """ + Thread-safe connection pool for one host. + + :param host: + Host used for this HTTP Connection (e.g. "localhost"), passed into + :class:`httplib.HTTPConnection`. + + :param port: + Port used for this HTTP Connection (None is equivalent to 80), passed + into :class:`httplib.HTTPConnection`. + + :param strict: + Causes BadStatusLine to be raised if the status line can't be parsed + as a valid HTTP/1.0 or 1.1 status line, passed into + :class:`httplib.HTTPConnection`. + + .. note:: + Only works in Python 2. This parameter is ignored in Python 3. + + :param timeout: + Socket timeout in seconds for each individual connection. This can + be a float or integer, which sets the timeout for the HTTP request, + or an instance of :class:`urllib3.util.Timeout` which gives you more + fine-grained control over request timeouts. After the constructor has + been parsed, this is always a `urllib3.util.Timeout` object. + + :param maxsize: + Number of connections to save that can be reused. More than 1 is useful + in multithreaded situations. If ``block`` is set to False, more + connections will be created but they will not be saved once they've + been used. + + :param block: + If set to True, no more than ``maxsize`` connections will be used at + a time. When no free connections are available, the call will block + until a connection has been released. This is a useful side effect for + particular multithreaded situations where one does not want to use more + than maxsize connections per host to prevent flooding. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param retries: + Retry configuration to use by default with requests in this pool. + + :param _proxy: + Parsed proxy URL, should not be used directly, instead, see + :class:`urllib3.connectionpool.ProxyManager`" + + :param _proxy_headers: + A dictionary with proxy headers, should not be used directly, + instead, see :class:`urllib3.connectionpool.ProxyManager`" + + :param \\**conn_kw: + Additional parameters are used to create fresh :class:`urllib3.connection.HTTPConnection`, + :class:`urllib3.connection.HTTPSConnection` instances. + """ + + scheme = 'http' + ConnectionCls = HTTPConnection + ResponseCls = HTTPResponse + + def __init__(self, host, port=None, strict=False, + timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, block=False, + headers=None, retries=None, + _proxy=None, _proxy_headers=None, + **conn_kw): + ConnectionPool.__init__(self, host, port) + RequestMethods.__init__(self, headers) + + self.strict = strict + + if not isinstance(timeout, Timeout): + timeout = Timeout.from_float(timeout) + + if retries is None: + retries = Retry.DEFAULT + + self.timeout = timeout + self.retries = retries + + self.pool = self.QueueCls(maxsize) + self.block = block + + self.proxy = _proxy + self.proxy_headers = _proxy_headers or {} + + # Fill the queue up so that doing get() on it will block properly + for _ in xrange(maxsize): + self.pool.put(None) + + # These are mostly for testing and debugging purposes. + self.num_connections = 0 + self.num_requests = 0 + self.conn_kw = conn_kw + + if self.proxy: + # Enable Nagle's algorithm for proxies, to avoid packet fragmentation. + # We cannot know if the user has added default socket options, so we cannot replace the + # list. + self.conn_kw.setdefault('socket_options', []) + + def _new_conn(self): + """ + Return a fresh :class:`HTTPConnection`. + """ + self.num_connections += 1 + log.debug("Starting new HTTP connection (%d): %s:%s", + self.num_connections, self.host, self.port or "80") + + conn = self.ConnectionCls(host=self.host, port=self.port, + timeout=self.timeout.connect_timeout, + strict=self.strict, **self.conn_kw) + return conn + + def _get_conn(self, timeout=None): + """ + Get a connection. Will return a pooled connection if one is available. + + If no connections are available and :prop:`.block` is ``False``, then a + fresh connection is returned. + + :param timeout: + Seconds to wait before giving up and raising + :class:`urllib3.exceptions.EmptyPoolError` if the pool is empty and + :prop:`.block` is ``True``. + """ + conn = None + try: + conn = self.pool.get(block=self.block, timeout=timeout) + + except AttributeError: # self.pool is None + raise ClosedPoolError(self, "Pool is closed.") + + except queue.Empty: + if self.block: + raise EmptyPoolError(self, + "Pool reached maximum size and no more " + "connections are allowed.") + pass # Oh well, we'll create a new connection then + + # If this is a persistent connection, check if it got disconnected + if conn and is_connection_dropped(conn): + log.debug("Resetting dropped connection: %s", self.host) + conn.close() + if getattr(conn, 'auto_open', 1) == 0: + # This is a proxied connection that has been mutated by + # httplib._tunnel() and cannot be reused (since it would + # attempt to bypass the proxy) + conn = None + + return conn or self._new_conn() + + def _put_conn(self, conn): + """ + Put a connection back into the pool. + + :param conn: + Connection object for the current host and port as returned by + :meth:`._new_conn` or :meth:`._get_conn`. + + If the pool is already full, the connection is closed and discarded + because we exceeded maxsize. If connections are discarded frequently, + then maxsize should be increased. + + If the pool is closed, then the connection will be closed and discarded. + """ + try: + self.pool.put(conn, block=False) + return # Everything is dandy, done. + except AttributeError: + # self.pool is None. + pass + except queue.Full: + # This should never happen if self.block == True + log.warning( + "Connection pool is full, discarding connection: %s", + self.host) + + # Connection never got put back into the pool, close it. + if conn: + conn.close() + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + pass + + def _prepare_proxy(self, conn): + # Nothing to do for HTTP connections. + pass + + def _get_timeout(self, timeout): + """ Helper that always returns a :class:`urllib3.util.Timeout` """ + if timeout is _Default: + return self.timeout.clone() + + if isinstance(timeout, Timeout): + return timeout.clone() + else: + # User passed us an int/float. This is for backwards compatibility, + # can be removed later + return Timeout.from_float(timeout) + + def _raise_timeout(self, err, url, timeout_value): + """Is the error actually a timeout? Will raise a ReadTimeout or pass""" + + if isinstance(err, SocketTimeout): + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # See the above comment about EAGAIN in Python 3. In Python 2 we have + # to specifically catch it and throw the timeout error + if hasattr(err, 'errno') and err.errno in _blocking_errnos: + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + # Catch possible read timeouts thrown as SSL errors. If not the + # case, rethrow the original. We need to do this because of: + # http://bugs.python.org/issue10272 + if 'timed out' in str(err) or 'did not complete (read)' in str(err): # Python 2.6 + raise ReadTimeoutError(self, url, "Read timed out. (read timeout=%s)" % timeout_value) + + def _make_request(self, conn, method, url, timeout=_Default, chunked=False, + **httplib_request_kw): + """ + Perform a request on a given urllib connection object taken from our + pool. + + :param conn: + a connection from one of our connection pools + + :param timeout: + Socket timeout in seconds for the request. This can be a + float or integer, which will set the same timeout value for + the socket connect and the socket read, or an instance of + :class:`urllib3.util.Timeout`, which gives you more fine-grained + control over your timeouts. + """ + self.num_requests += 1 + + timeout_obj = self._get_timeout(timeout) + timeout_obj.start_connect() + conn.timeout = timeout_obj.connect_timeout + + # Trigger any extra validation we need to do. + try: + self._validate_conn(conn) + except (SocketTimeout, BaseSSLError) as e: + # Py2 raises this as a BaseSSLError, Py3 raises it as socket timeout. + self._raise_timeout(err=e, url=url, timeout_value=conn.timeout) + raise + + # conn.request() calls httplib.*.request, not the method in + # urllib3.request. It also calls makefile (recv) on the socket. + if chunked: + conn.request_chunked(method, url, **httplib_request_kw) + else: + conn.request(method, url, **httplib_request_kw) + + # Reset the timeout for the recv() on the socket + read_timeout = timeout_obj.read_timeout + + # App Engine doesn't have a sock attr + if getattr(conn, 'sock', None): + # In Python 3 socket.py will catch EAGAIN and return None when you + # try and read into the file pointer created by http.client, which + # instead raises a BadStatusLine exception. Instead of catching + # the exception and assuming all BadStatusLine exceptions are read + # timeouts, check for a zero timeout before making the request. + if read_timeout == 0: + raise ReadTimeoutError( + self, url, "Read timed out. (read timeout=%s)" % read_timeout) + if read_timeout is Timeout.DEFAULT_TIMEOUT: + conn.sock.settimeout(socket.getdefaulttimeout()) + else: # None or a value + conn.sock.settimeout(read_timeout) + + # Receive the response from the server + try: + try: # Python 2.7, use buffering of HTTP responses + httplib_response = conn.getresponse(buffering=True) + except TypeError: # Python 2.6 and older, Python 3 + try: + httplib_response = conn.getresponse() + except Exception as e: + # Remove the TypeError from the exception chain in Python 3; + # otherwise it looks like a programming error was the cause. + six.raise_from(e, None) + except (SocketTimeout, BaseSSLError, SocketError) as e: + self._raise_timeout(err=e, url=url, timeout_value=read_timeout) + raise + + # AppEngine doesn't have a version attr. + http_version = getattr(conn, '_http_vsn_str', 'HTTP/?') + log.debug("%s://%s:%s \"%s %s %s\" %s %s", self.scheme, self.host, self.port, + method, url, http_version, httplib_response.status, + httplib_response.length) + + try: + assert_header_parsing(httplib_response.msg) + except (HeaderParsingError, TypeError) as hpe: # Platform-specific: Python 3 + log.warning( + 'Failed to parse headers (url=%s): %s', + self._absolute_url(url), hpe, exc_info=True) + + return httplib_response + + def _absolute_url(self, path): + return Url(scheme=self.scheme, host=self.host, port=self.port, path=path).url + + def close(self): + """ + Close all pooled connections and disable the pool. + """ + if self.pool is None: + return + # Disable access to the pool + old_pool, self.pool = self.pool, None + + try: + while True: + conn = old_pool.get(block=False) + if conn: + conn.close() + + except queue.Empty: + pass # Done. + + def is_same_host(self, url): + """ + Check if the given ``url`` is a member of the same host as this + connection pool. + """ + if url.startswith('/'): + return True + + # TODO: Add optional support for socket.gethostbyname checking. + scheme, host, port = get_host(url) + + host = _ipv6_host(host, self.scheme) + + # Use explicit default port for comparison when none is given + if self.port and not port: + port = port_by_scheme.get(scheme) + elif not self.port and port == port_by_scheme.get(scheme): + port = None + + return (scheme, host, port) == (self.scheme, self.host, self.port) + + def urlopen(self, method, url, body=None, headers=None, retries=None, + redirect=True, assert_same_host=True, timeout=_Default, + pool_timeout=None, release_conn=None, chunked=False, + body_pos=None, **response_kw): + """ + Get a connection from the pool and perform an HTTP request. This is the + lowest level call for making a request, so you'll need to specify all + the raw details. + + .. note:: + + More commonly, it's appropriate to use a convenience method provided + by :class:`.RequestMethods`, such as :meth:`request`. + + .. note:: + + `release_conn` will only behave as expected if + `preload_content=False` because we want to make + `preload_content=False` the default behaviour someday soon without + breaking backwards compatibility. + + :param method: + HTTP request method (such as GET, POST, PUT, etc.) + + :param body: + Data to send in the request body (useful for creating + POST requests, see HTTPConnectionPool.post_url for + more convenience). + + :param headers: + Dictionary of custom headers to send, such as User-Agent, + If-None-Match, etc. If None, pool headers are used. If provided, + these headers completely replace any pool-specific headers. + + :param retries: + Configure the number of retries to allow before raising a + :class:`~urllib3.exceptions.MaxRetryError` exception. + + Pass ``None`` to retry until you receive a response. Pass a + :class:`~urllib3.util.retry.Retry` object for fine-grained control + over different types of retries. + Pass an integer number to retry connection errors that many times, + but no other types of errors. Pass zero to never retry. + + If ``False``, then retries are disabled and any exception is raised + immediately. Also, instead of raising a MaxRetryError on redirects, + the redirect response will be returned. + + :type retries: :class:`~urllib3.util.retry.Retry`, False, or an int. + + :param redirect: + If True, automatically handle redirects (status codes 301, 302, + 303, 307, 308). Each redirect counts as a retry. Disabling retries + will disable redirect, too. + + :param assert_same_host: + If ``True``, will make sure that the host of the pool requests is + consistent else will raise HostChangedError. When False, you can + use the pool on an HTTP proxy and request foreign hosts. + + :param timeout: + If specified, overrides the default timeout for this one + request. It may be a float (in seconds) or an instance of + :class:`urllib3.util.Timeout`. + + :param pool_timeout: + If set and the pool is set to block=True, then this method will + block for ``pool_timeout`` seconds and raise EmptyPoolError if no + connection is available within the time period. + + :param release_conn: + If False, then the urlopen call will not release the connection + back into the pool once a response is received (but will release if + you read the entire contents of the response such as when + `preload_content=True`). This is useful if you're not preloading + the response's content immediately. You will need to call + ``r.release_conn()`` on the response ``r`` to return the connection + back into the pool. If None, it takes the value of + ``response_kw.get('preload_content', True)``. + + :param chunked: + If True, urllib3 will send the body using chunked transfer + encoding. Otherwise, urllib3 will send the body using the standard + content-length form. Defaults to False. + + :param int body_pos: + Position to seek to in file-like body in the event of a retry or + redirect. Typically this won't need to be set because urllib3 will + auto-populate the value when needed. + + :param \\**response_kw: + Additional parameters are passed to + :meth:`urllib3.response.HTTPResponse.from_httplib` + """ + if headers is None: + headers = self.headers + + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect, default=self.retries) + + if release_conn is None: + release_conn = response_kw.get('preload_content', True) + + # Check host + if assert_same_host and not self.is_same_host(url): + raise HostChangedError(self, url, retries) + + conn = None + + # Track whether `conn` needs to be released before + # returning/raising/recursing. Update this variable if necessary, and + # leave `release_conn` constant throughout the function. That way, if + # the function recurses, the original value of `release_conn` will be + # passed down into the recursive call, and its value will be respected. + # + # See issue #651 [1] for details. + # + # [1] <https://github.com/shazow/urllib3/issues/651> + release_this_conn = release_conn + + # Merge the proxy headers. Only do this in HTTP. We have to copy the + # headers dict so we can safely change it without those changes being + # reflected in anyone else's copy. + if self.scheme == 'http': + headers = headers.copy() + headers.update(self.proxy_headers) + + # Must keep the exception bound to a separate variable or else Python 3 + # complains about UnboundLocalError. + err = None + + # Keep track of whether we cleanly exited the except block. This + # ensures we do proper cleanup in finally. + clean_exit = False + + # Rewind body position, if needed. Record current position + # for future rewinds in the event of a redirect/retry. + body_pos = set_file_position(body, body_pos) + + try: + # Request a connection from the queue. + timeout_obj = self._get_timeout(timeout) + conn = self._get_conn(timeout=pool_timeout) + + conn.timeout = timeout_obj.connect_timeout + + is_new_proxy_conn = self.proxy is not None and not getattr(conn, 'sock', None) + if is_new_proxy_conn: + self._prepare_proxy(conn) + + # Make the request on the httplib connection object. + httplib_response = self._make_request(conn, method, url, + timeout=timeout_obj, + body=body, headers=headers, + chunked=chunked) + + # If we're going to release the connection in ``finally:``, then + # the response doesn't need to know about the connection. Otherwise + # it will also try to release it and we'll have a double-release + # mess. + response_conn = conn if not release_conn else None + + # Pass method to Response for length checking + response_kw['request_method'] = method + + # Import httplib's response into our own wrapper object + response = self.ResponseCls.from_httplib(httplib_response, + pool=self, + connection=response_conn, + retries=retries, + **response_kw) + + # Everything went great! + clean_exit = True + + except queue.Empty: + # Timed out by queue. + raise EmptyPoolError(self, "No pool connections are available.") + + except (TimeoutError, HTTPException, SocketError, ProtocolError, + BaseSSLError, SSLError, CertificateError) as e: + # Discard the connection for these exceptions. It will be + # replaced during the next _get_conn() call. + clean_exit = False + if isinstance(e, (BaseSSLError, CertificateError)): + e = SSLError(e) + elif isinstance(e, (SocketError, NewConnectionError)) and self.proxy: + e = ProxyError('Cannot connect to proxy.', e) + elif isinstance(e, (SocketError, HTTPException)): + e = ProtocolError('Connection aborted.', e) + + retries = retries.increment(method, url, error=e, _pool=self, + _stacktrace=sys.exc_info()[2]) + retries.sleep() + + # Keep track of the error for the retry warning. + err = e + + finally: + if not clean_exit: + # We hit some kind of exception, handled or otherwise. We need + # to throw the connection away unless explicitly told not to. + # Close the connection, set the variable to None, and make sure + # we put the None back in the pool to avoid leaking it. + conn = conn and conn.close() + release_this_conn = True + + if release_this_conn: + # Put the connection back to be reused. If the connection is + # expired then it will be None, which will get replaced with a + # fresh connection during _get_conn. + self._put_conn(conn) + + if not conn: + # Try again + log.warning("Retrying (%r) after connection " + "broken by '%r': %s", retries, err, url) + return self.urlopen(method, url, body, headers, retries, + redirect, assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + def drain_and_release_conn(response): + try: + # discard any remaining response body, the connection will be + # released back to the pool once the entire response is read + response.read() + except (TimeoutError, HTTPException, SocketError, ProtocolError, + BaseSSLError, SSLError) as e: + pass + + # Handle redirect? + redirect_location = redirect and response.get_redirect_location() + if redirect_location: + if response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + # Drain and release the connection for this response, since + # we're not returning it to be released manually. + drain_and_release_conn(response) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep_for_retry(response) + log.debug("Redirecting %s -> %s", url, redirect_location) + return self.urlopen( + method, redirect_location, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, body_pos=body_pos, + **response_kw) + + # Check if we should retry the HTTP response. + has_retry_after = bool(response.getheader('Retry-After')) + if retries.is_retry(method, response.status, has_retry_after): + try: + retries = retries.increment(method, url, response=response, _pool=self) + except MaxRetryError: + if retries.raise_on_status: + # Drain and release the connection for this response, since + # we're not returning it to be released manually. + drain_and_release_conn(response) + raise + return response + + # drain and return the connection to the pool before recursing + drain_and_release_conn(response) + + retries.sleep(response) + log.debug("Retry: %s", url) + return self.urlopen( + method, url, body, headers, + retries=retries, redirect=redirect, + assert_same_host=assert_same_host, + timeout=timeout, pool_timeout=pool_timeout, + release_conn=release_conn, + body_pos=body_pos, **response_kw) + + return response + + +class HTTPSConnectionPool(HTTPConnectionPool): + """ + Same as :class:`.HTTPConnectionPool`, but HTTPS. + + When Python is compiled with the :mod:`ssl` module, then + :class:`.VerifiedHTTPSConnection` is used, which *can* verify certificates, + instead of :class:`.HTTPSConnection`. + + :class:`.VerifiedHTTPSConnection` uses one of ``assert_fingerprint``, + ``assert_hostname`` and ``host`` in this order to verify connections. + If ``assert_hostname`` is False, no verification is done. + + The ``key_file``, ``cert_file``, ``cert_reqs``, ``ca_certs``, + ``ca_cert_dir``, and ``ssl_version`` are only used if :mod:`ssl` is + available and are fed into :meth:`urllib3.util.ssl_wrap_socket` to upgrade + the connection socket into an SSL socket. + """ + + scheme = 'https' + ConnectionCls = HTTPSConnection + + def __init__(self, host, port=None, + strict=False, timeout=Timeout.DEFAULT_TIMEOUT, maxsize=1, + block=False, headers=None, retries=None, + _proxy=None, _proxy_headers=None, + key_file=None, cert_file=None, cert_reqs=None, + ca_certs=None, ssl_version=None, + assert_hostname=None, assert_fingerprint=None, + ca_cert_dir=None, **conn_kw): + + HTTPConnectionPool.__init__(self, host, port, strict, timeout, maxsize, + block, headers, retries, _proxy, _proxy_headers, + **conn_kw) + + if ca_certs and cert_reqs is None: + cert_reqs = 'CERT_REQUIRED' + + self.key_file = key_file + self.cert_file = cert_file + self.cert_reqs = cert_reqs + self.ca_certs = ca_certs + self.ca_cert_dir = ca_cert_dir + self.ssl_version = ssl_version + self.assert_hostname = assert_hostname + self.assert_fingerprint = assert_fingerprint + + def _prepare_conn(self, conn): + """ + Prepare the ``connection`` for :meth:`urllib3.util.ssl_wrap_socket` + and establish the tunnel if proxy is used. + """ + + if isinstance(conn, VerifiedHTTPSConnection): + conn.set_cert(key_file=self.key_file, + cert_file=self.cert_file, + cert_reqs=self.cert_reqs, + ca_certs=self.ca_certs, + ca_cert_dir=self.ca_cert_dir, + assert_hostname=self.assert_hostname, + assert_fingerprint=self.assert_fingerprint) + conn.ssl_version = self.ssl_version + return conn + + def _prepare_proxy(self, conn): + """ + Establish tunnel connection early, because otherwise httplib + would improperly set Host: header to proxy's IP:port. + """ + # Python 2.7+ + try: + set_tunnel = conn.set_tunnel + except AttributeError: # Platform-specific: Python 2.6 + set_tunnel = conn._set_tunnel + + if sys.version_info <= (2, 6, 4) and not self.proxy_headers: # Python 2.6.4 and older + set_tunnel(self._proxy_host, self.port) + else: + set_tunnel(self._proxy_host, self.port, self.proxy_headers) + + conn.connect() + + def _new_conn(self): + """ + Return a fresh :class:`httplib.HTTPSConnection`. + """ + self.num_connections += 1 + log.debug("Starting new HTTPS connection (%d): %s:%s", + self.num_connections, self.host, self.port or "443") + + if not self.ConnectionCls or self.ConnectionCls is DummyConnection: + raise SSLError("Can't connect to HTTPS URL because the SSL " + "module is not available.") + + actual_host = self.host + actual_port = self.port + if self.proxy is not None: + actual_host = self.proxy.host + actual_port = self.proxy.port + + conn = self.ConnectionCls(host=actual_host, port=actual_port, + timeout=self.timeout.connect_timeout, + strict=self.strict, **self.conn_kw) + + return self._prepare_conn(conn) + + def _validate_conn(self, conn): + """ + Called right before a request is made, after the socket is created. + """ + super(HTTPSConnectionPool, self)._validate_conn(conn) + + # Force connect early to allow us to validate the connection. + if not getattr(conn, 'sock', None): # AppEngine might not have `.sock` + conn.connect() + + if not conn.is_verified: + warnings.warn(( + 'Unverified HTTPS request is being made. ' + 'Adding certificate verification is strongly advised. See: ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings'), + InsecureRequestWarning) + + +def connection_from_url(url, **kw): + """ + Given a url, return an :class:`.ConnectionPool` instance of its host. + + This is a shortcut for not having to parse out the scheme, host, and port + of the url before creating an :class:`.ConnectionPool` instance. + + :param url: + Absolute URL string that must include the scheme. Port is optional. + + :param \\**kw: + Passes additional parameters to the constructor of the appropriate + :class:`.ConnectionPool`. Useful for specifying things like + timeout, maxsize, headers, etc. + + Example:: + + >>> conn = connection_from_url('http://google.com/') + >>> r = conn.request('GET', '/') + """ + scheme, host, port = get_host(url) + port = port or port_by_scheme.get(scheme, 80) + if scheme == 'https': + return HTTPSConnectionPool(host, port=port, **kw) + else: + return HTTPConnectionPool(host, port=port, **kw) + + +def _ipv6_host(host, scheme): + """ + Process IPv6 address literals + """ + + # httplib doesn't like it when we include brackets in IPv6 addresses + # Specifically, if we include brackets but also pass the port then + # httplib crazily doubles up the square brackets on the Host header. + # Instead, we need to make sure we never pass ``None`` as the port. + # However, for backward compatibility reasons we can't actually + # *assert* that. See http://bugs.python.org/issue28539 + # + # Also if an IPv6 address literal has a zone identifier, the + # percent sign might be URIencoded, convert it back into ASCII + if host.startswith('[') and host.endswith(']'): + host = host.replace('%25', '%').strip('[]') + if scheme in NORMALIZABLE_SCHEMES: + host = host.lower() + return host diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..37e36be0e28dc263a0cef1324dae9bcd1d836309 GIT binary patch literal 156 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd<h9ZzKg81dCUy@s(Uyxa# zo0(T!l9-dDn_QlrmsL_|0ult{__EZzl>8$7(xRN4%p_y|<ovvnqRb@y`1s7c%#!$c Xy@JYH95%W6DWy57b|B-6ftUdRVPPgr literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/appengine.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..88abbbbcaeddf2a0d1b3431b5b6bd5c1ac83e89d GIT binary patch literal 8904 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 Oz4EMFEF0xQx%fYcZm4Mh literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/ntlmpool.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0dbf249eefb1342649b6741336d6b0fd3657787d GIT binary patch literal 3204 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 O>S|p>oKdM*m2UwD>uz5F literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/pyopenssl.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9e2d45955a31578daf9a9f98ccb735da439ace2c GIT binary patch literal 14231 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 AbpQYW literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/securetransport.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ab99354f010a7066e2ac9e81fe22c37df8a4bed GIT binary patch literal 17853 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 Jw3W@K{tvmpOtAm} literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/__pycache__/socks.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..930a350d27c93e539746e3308e2e05e5b9839f63 GIT binary patch literal 4862 zcmb7ITW=f372X@k<&vUgO15m}Hcjf(ENm)G>@;xQG`1V3Mp8wHmD*keSg*K4bEUn| zGfOKHr~-{$1bt}Hw*ZBKCO}{M*5A-y(C2;alY#cFK!H5<JF~l_tvF~aVrOU0T+W$u z`OaBgSy*s1{JDR8^^<>})U?0Tp!&1Xc?XX?qib5AxmutHMx@7vYv|g38zVC^UGt`v zylH9N+I7T7x<)@WQ*ϋ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 F`wxB?5pw_l literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..329bd6cdc3e57c3baad902df8940b1f5c4a2fb5f GIT binary patch literal 173 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd<h9ZzKg7_7tUy@s(Uyxa# zo0(T!l9-dDn_QlrmsL_|0ult{__EZzl>8$7(xRN4%p_y|<ovvnqRb@y_~O*$(xTLo oqQt!7g8ZTq{rLFIyv&mLc)fzkTO2mI`6;D2sdgayih-B`0CR>dUjP6A literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/bindings.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..16c22be74f53312cfb1ad10b04fb2a4c04856dfb GIT binary patch literal 10268 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/__pycache__/low_level.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8974672091fa50fab747f00b0233bb41e2aabb97 GIT binary patch literal 7449 zcmbVROLH98b?(>9^fZ702!fO-OH9jEwmB{mv>ioJBv~;z1Z0#bkRc$FZp)eKnZ5%w z(9=D<eFu-J!G=__bSmqlDuYT@Dyb}^$}&G7+f-%I<(*gBrQ)5+i+tzYc>%H)@u0f< z_U-#TkMDfv;{MW-XW$q7!*@S_dDk$0O)rz5gTha6<zM0!8G#X*k(HQ%$xkb=_-O|= zKb^qgXDKN0vmBK9SqUnU9XW~Htp?Su7kJ%;V8JwmGg^#F!Z}zvw}M(!jw)Xm!E)qA zRXkTBFIvF!O7upw7%hEa2CGpmT1L&)XeGLW=UTKHUB&ZSv=&{%^LlhWdJWIlqSvDv zc)lK4J4XFm;Xj#%;XTZb?<C?#B>uigdP3%YCzHO~7ygcD_odjCVVd_csr*))Msd2A zuY2C^zQ~0iO5r~~Rr^`$clv2t#aWu8XQ=o~nkheurD&_<)R!U&m56+m@zDG6-u`&j zdyltruhk#-5p9v@p**FAdqPp;E|rfndAROl+EYJH+etsd?Edk7mI%LvsrUV?<0q4y zc#TYo&8(kBA+5>pVoWUD4_g_{lSZiNW|*WKrs1CGid6B~emhIsLShqfikaiw?`Bay z5gu(cOuAXFe6+=$up>Q~lBYB>Ru~>-@pRxsgoioL)RWm!Ok(rG9?Cr#Lk|3<pNmdE z@k6XFS0N^z7mko)@wBr@tb1R<$c*i;pf96t7cOfiR;NYn;!cZ7W3vGzsQd%8yhFeH z8y|0N`;Cn!yIY%EjeENrT<hIh|NfuXJuYu-KlsM?HqAsodX{lDaOG>bDPv?R<G>mk z${rf8%yS#2WDbrzAHR>|BauQety3j(C9&(<ep?FOvESHy5USA6S_d!*zaz7*AG6#c z=ZoLE{ao>QErBmj1f-e6c3Q9sm}NUm5+T>QLEVw$h{d8Fpuuw$R}UMT_mU)Qhbof~ zL?`Sgs<0E0*3H11t?ge7Sw-ispWRj6-rZi@yAwln82wKBcrQIrFW#X_zM9xql*zk& znIv)RkMF`zu)WsZX3jpMCO&c(HrQluTJN0}SDWol6E+w&X}3+D`CBANTC-7dOu2yP zRMsSC7Z=MqKtUNK;WLJmFHn9!Zx#T<n!ee}gf7fAV`%--ICG|NHr`6g9MN}Y=nP9k z6D8Cfl+Vl1m^1j~g2ocqAo<YPomIb=h<v6zC^gTsHrZ}O%8J?9;ip;+(=Aw7wT&yM z>pE^j;}^9vb7)4!4dW@S=>>2R(_4}ZYn$a?w+d_h2ZgElP2UK2zpj3`CsJ|JlONrt z;b?5f7~El@P8Xm>tJk~!A?ZBHKU$ym`~y}-^GsGI7x5yO=tib8Tb!)n^$xD_vg#E{ zs?*k3ZEWtI_QVs>30CKYrOi`T&@gxlHcE|VqWnahHeh`B!}ehw{Lwc)KMj+<m^P>* zg6K^nF3g0H#{*F~hvGCZ%16{84=S)hstBqm=(<aLDc<<~BK;0+@paq`$F*xF|5=Xd zm=^!RgjexxD&-Phrf`wsh2R2EVT>$*hJ9|HTW6+nMr4lVg9_fPAuQt1mCw<}jjVI? z%*OZX&>X_dxs7uM1J0i)FS1{mFHwK6Fz!{A2SW>y(m^kb1G_2>{+Z2MOBx95f0o7s zp}vMA4Lc!Bc!%L>j7IDJX9O@)Y^Mk)q|77_CIy8*fEfZGq1?~NGhzxPX?BVjA^aEp zm_Qv7h$0r^9|w;~O!NV8T+z<DaH|vTGutt&*%*9pgXTfx>2V-wTv+I2nXsfmsjoVB z-m5Pa<+g&|<b~4?b5&FxKib;f-FQ;C?IuN_W{+(!xHjqgu}}@Y*~dysQc!RW#-*z^ zQV0h-`)qgfy<$y6byJI~+3I&XLXrjRwzGkX%A*}#c2Q!3D$0={A=gXt293YWwaqXe zuc#>NA&asevnWfE1CuY?;We_u@$4#V_O<FLl;z*X&8V!w^eof0T+^GHpo==!EaUP_ zc@wSL<iPYJl%<RD^m7!3AZdq|TqOFV4HE_j6I3uBAgitHku!t|ng$u)p_{*tr;Q%> zBWGw_H_mJT8S3R@RXQjWtPR;DnNF1kKi8(WFW|r&siaVSnL@Y3R=_&czRZq^7Wm?% zEqcsN;tn+hzkrd@2et;4%^999GF}$OVByiujtW&j_rH?^bO>yN8{h*C7!d2^QzB4% zLhFnLG6kh^BrWVbPe3Ae9&(4eQ<QkxV0pT%W;+4k2g}e0e;RA0D1$)t`rlC83Ur+d zshVk~+ds#$m@XJ4*L18!(vG#lnk!q9KxGOU7oy&;SW6=&)6k4T<oF8%aSVLp+~oKN zspspYsi<@gI8dcg8QQ2sW#x{lD0u)Go8Tbd<yIAHbsC-g<q-XU@f2EKAgwW|9L-v& z#nBRtGjuR-38U6fB1<Ucf6uMl@odXOYgjtBOoQ8C4G3zVKQo>g=}pH_D~F!^ZxexT z{GF}oXGUs0M}!7IRR=FwpHrp;k_rxs$P41Bn0P+k_>?GkH&nNMvLCi3aHW(;CXnl% zl;P>L2am>>(}wwgFo9Mw&4v%g;2s1^G_>E|593rr567$}?>A&q-c%9fHWZq6aOH2} zwnx!>4R}o$4i!XD!MXXj)(Zz4F(tJJ87;R!&fa~esJ7mHN5eo-+LKwohagYUvnXLF z?fpx>{<ZfZQ4T`HkB(?U8m(*&ZZ&DK&5-t}Lwiqj=i>Ub)8OWI=F1F#OC91)46-M3 zKktb)UPQzMWAMgjY1o2%NpzYJiZS<pd+_G$TdN-@krtDtr*GG<6cylp61GLL)Pzc! zM4@+@Pc{m-LwS&bU%ZVq%Wu<-V5V3b>qZBkPy33d=4dak()Uv9REkbP=u45G^*9aa zOa-+&ze(;q+ms&eS*-SnKTDs60w{C$d%Yfr=~IgIMRj8WDj)|Q#0CT>;|i*gkSx|b z@MhB0)yzo)m#T@VBB-ErNms?%?@~$^>&V~1%_uM0WwQnt_QuRWmn{G?oS&iEvk0&~ z0KuwRb5<<*C+K&<@(9QpxR^DP#hn|lJZpp`;~ds^NX}ype$3|ngmE?ZcV!>A*@1=c zapEzhT@0r4hB3_+Xqw=)ivmVqBYkW=&}v+0Y))&yO&zGZTe#q%NLyf67kOaeHshSd z^LMm(vI8(BQ~nvAf584e_<!s#_2Y;biyD(~<U+i=HSBI{{AIck-kN+DtAbnpDIW4Y zx?S4LB5h_e>OZ2vY(wwkt&NL+1QSHj8@Ten#*Gvf0UXW@t+EJN%3oPGpgQ0*aCD+d z%3X9lqArjdO141^D<gM^*m`b_s@&R9-e>{eN_Z{~9koR98AP!JN?02$1Aoo)@>yA} z49l+=qlb2f45S?X8!(M!xJ&8#l!0kxLwpd*1e>E1hEKz`4`R%?h!_mkc1+1-N(eeR za`2Dgc03+NV3{JlptAxDKJAP4G;)@TJ1Pbn>>(K9ydvV5KR;t9W+>wEa-^o12Kg-c z-MarwfE194(bW6l5n@6rW^>?R#zz8nD8?rhnp%j6$AZE?8E*tk(Wms8B0)!r%ULsc zE1#Z#@^K!G=j9O|Al+6ta^U)jr(qYA5mMBlC109Qa~s;Y+MgU^Oy$hu=yM=Ca?zm* z=`*4c!kyBd`PD5L(e_uALXC;;CJ@-l@}km5ZXIP^`8|9?kon=ef;g*?Z_v9-(~ww; zO7}3Lm%^b{6wW~wr$u?()<)Z)c5&6gmAQ9~u{wn#td>8Z8}XESC0Nue(D^&TKTZ<D zt|;7zqJt%xdAi47X<`~pUW+?<B_2%F?XuflZBC^{sTy14zhds3=&W(YGhYX6y4IRa zaB6|;>f~$Da&5VV7E{Jc@s=+3O9!s7XPjBMa0rRB0fX4<E9-A+XQg3@0k-@MOzSU< zC&qJQ@bBcg%ED;@_!RjSSX2dd<fD!v53S(HlKwCnQo8EMBZhSDp1ELDF8Lu^!&~9) z)sqN5TYW{0>-m|7da$XX2WGW^e#^rJ%(KF8SB49(O!*&Zu{vBJE`@~dsxG~Fsn+=G z%ek-i>??6Dti+N3gYVZgTjLTKpNSm-Q7lFUXYikFgcHt1XMwO~(&KHUY+(fNO%gV2 zCCPU*2LOENGpaH5B1%FWUHcrl!9-WuhJS~z5L?OL=aD<H#K?TiLQG$m;7((-jVY(Z zn7q&&*%Z=+StAO{ICk~%+b%5GVscZzUN{-Tf8pTNE7AZ@WLh&0a;3m)Xqo_2(6M0& zHopa9+aeHDOiN~_9xRWWQ>KU0Q&p5;`FkR`KC5S{aZhcfkvNfSG}|)WDBJ}uoz;<F z7iFAvf|p1N8cbN~i}GVC-^Z<3r0q-?Tj9+l08it*P}9G{?2zjnH%U<hk^#FOmE>DA z-=uY0uNABeYvR~;DXd*<l9rnk$a769X~_S=82L|eGb(hTL0QVGWl;(K<srwU=lmc1 zt?c0l1o@^_;~bRp8uVgnW62$iH4XaYhZG}e-}(RIHuFV3zZ+*WgD+3kIWze#d#EvV zURj?b134=XZP0GcFW?jAuuN9{;^s5hb^c4(xedQ0|3qer$Y|f7e55>t?Za<fRnZ=a zG2pk<ll|2iEktw(qu&=*^<XKosUJ!;?pZzY)$(YCeCOPP_pZQutD`H!DtRyF{}S_8 zcZ`#p7h2WWuf4I~7SG^)5hV$w!Ef1UA42@|bd22yr|+kTQgEWNr-gpn@3s)=;1;AH z1lpg5I+KPm`FmNI@M!p~!yiSlSw=)>vM@fXq|iy0K4w8M|Jxjl;b5sh5Hj;|<bwYI zXm>-)#>^rqf{p>;wx8o*hZ6`o5h7lI^@M&qi9x*PH{>&L@apFBtf?(fazj^6*Zi@l z#M$lmSQL3z-Mo12NZxWOR`9vwkAUpsbH~B=wQcJqX`ZfE@XfPOedbzUWjjS|JW=GM zHYVZNI47-OUV5|qV@^t!phIrcQi=VtyBBs3|LMTL%*J5!LzIdt<xDEelDsJK66KFj zJw}G2M4>X5kEqXMZcZk^0W_$k;&?(!0hB?N-Wd~v#ko(XlDs)sU|lrz6a)u_4Simc zWAWPWkz0*qOFY@|fdqC9h~NPQ7LmZz96D*z5g1rtdd`Zi(V}Lp+AEf0t(x-Z=m|a6 zZxoegGs@b{CNmc;ucx#cOA7g86m<Id6O;mX@~<`4hL$6p)D;y<kRgYn{NT~<y@wAa z9Xab%k<MN9@ea`xPN*1$HRuv8U_JAK<~GmJNVrtEAL{>ZeMD9HE!=2(bAQ$vHtadB S=U#W;@~*k-F8yw~AN(IR+v86F literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py new file mode 100644 index 0000000..bcf41c0 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/bindings.py @@ -0,0 +1,593 @@ +""" +This module uses ctypes to bind a whole bunch of functions and constants from +SecureTransport. The goal here is to provide the low-level API to +SecureTransport. These are essentially the C-level functions and constants, and +they're pretty gross to work with. + +This code is a bastardised version of the code found in Will Bond's oscrypto +library. An enormous debt is owed to him for blazing this trail for us. For +that reason, this code should be considered to be covered both by urllib3's +license and by oscrypto's: + + Copyright (c) 2015-2016 Will Bond <will@wbond.net> + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +""" +from __future__ import absolute_import + +import platform +from ctypes.util import find_library +from ctypes import ( + c_void_p, c_int32, c_char_p, c_size_t, c_byte, c_uint32, c_ulong, c_long, + c_bool +) +from ctypes import CDLL, POINTER, CFUNCTYPE + + +security_path = find_library('Security') +if not security_path: + raise ImportError('The library Security could not be found') + + +core_foundation_path = find_library('CoreFoundation') +if not core_foundation_path: + raise ImportError('The library CoreFoundation could not be found') + + +version = platform.mac_ver()[0] +version_info = tuple(map(int, version.split('.'))) +if version_info < (10, 8): + raise OSError( + 'Only OS X 10.8 and newer are supported, not %s.%s' % ( + version_info[0], version_info[1] + ) + ) + +Security = CDLL(security_path, use_errno=True) +CoreFoundation = CDLL(core_foundation_path, use_errno=True) + +Boolean = c_bool +CFIndex = c_long +CFStringEncoding = c_uint32 +CFData = c_void_p +CFString = c_void_p +CFArray = c_void_p +CFMutableArray = c_void_p +CFDictionary = c_void_p +CFError = c_void_p +CFType = c_void_p +CFTypeID = c_ulong + +CFTypeRef = POINTER(CFType) +CFAllocatorRef = c_void_p + +OSStatus = c_int32 + +CFDataRef = POINTER(CFData) +CFStringRef = POINTER(CFString) +CFArrayRef = POINTER(CFArray) +CFMutableArrayRef = POINTER(CFMutableArray) +CFDictionaryRef = POINTER(CFDictionary) +CFArrayCallBacks = c_void_p +CFDictionaryKeyCallBacks = c_void_p +CFDictionaryValueCallBacks = c_void_p + +SecCertificateRef = POINTER(c_void_p) +SecExternalFormat = c_uint32 +SecExternalItemType = c_uint32 +SecIdentityRef = POINTER(c_void_p) +SecItemImportExportFlags = c_uint32 +SecItemImportExportKeyParameters = c_void_p +SecKeychainRef = POINTER(c_void_p) +SSLProtocol = c_uint32 +SSLCipherSuite = c_uint32 +SSLContextRef = POINTER(c_void_p) +SecTrustRef = POINTER(c_void_p) +SSLConnectionRef = c_uint32 +SecTrustResultType = c_uint32 +SecTrustOptionFlags = c_uint32 +SSLProtocolSide = c_uint32 +SSLConnectionType = c_uint32 +SSLSessionOption = c_uint32 + + +try: + Security.SecItemImport.argtypes = [ + CFDataRef, + CFStringRef, + POINTER(SecExternalFormat), + POINTER(SecExternalItemType), + SecItemImportExportFlags, + POINTER(SecItemImportExportKeyParameters), + SecKeychainRef, + POINTER(CFArrayRef), + ] + Security.SecItemImport.restype = OSStatus + + Security.SecCertificateGetTypeID.argtypes = [] + Security.SecCertificateGetTypeID.restype = CFTypeID + + Security.SecIdentityGetTypeID.argtypes = [] + Security.SecIdentityGetTypeID.restype = CFTypeID + + Security.SecKeyGetTypeID.argtypes = [] + Security.SecKeyGetTypeID.restype = CFTypeID + + Security.SecCertificateCreateWithData.argtypes = [ + CFAllocatorRef, + CFDataRef + ] + Security.SecCertificateCreateWithData.restype = SecCertificateRef + + Security.SecCertificateCopyData.argtypes = [ + SecCertificateRef + ] + Security.SecCertificateCopyData.restype = CFDataRef + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SecIdentityCreateWithCertificate.argtypes = [ + CFTypeRef, + SecCertificateRef, + POINTER(SecIdentityRef) + ] + Security.SecIdentityCreateWithCertificate.restype = OSStatus + + Security.SecKeychainCreate.argtypes = [ + c_char_p, + c_uint32, + c_void_p, + Boolean, + c_void_p, + POINTER(SecKeychainRef) + ] + Security.SecKeychainCreate.restype = OSStatus + + Security.SecKeychainDelete.argtypes = [ + SecKeychainRef + ] + Security.SecKeychainDelete.restype = OSStatus + + Security.SecPKCS12Import.argtypes = [ + CFDataRef, + CFDictionaryRef, + POINTER(CFArrayRef) + ] + Security.SecPKCS12Import.restype = OSStatus + + SSLReadFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, c_void_p, POINTER(c_size_t)) + SSLWriteFunc = CFUNCTYPE(OSStatus, SSLConnectionRef, POINTER(c_byte), POINTER(c_size_t)) + + Security.SSLSetIOFuncs.argtypes = [ + SSLContextRef, + SSLReadFunc, + SSLWriteFunc + ] + Security.SSLSetIOFuncs.restype = OSStatus + + Security.SSLSetPeerID.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerID.restype = OSStatus + + Security.SSLSetCertificate.argtypes = [ + SSLContextRef, + CFArrayRef + ] + Security.SSLSetCertificate.restype = OSStatus + + Security.SSLSetCertificateAuthorities.argtypes = [ + SSLContextRef, + CFTypeRef, + Boolean + ] + Security.SSLSetCertificateAuthorities.restype = OSStatus + + Security.SSLSetConnection.argtypes = [ + SSLContextRef, + SSLConnectionRef + ] + Security.SSLSetConnection.restype = OSStatus + + Security.SSLSetPeerDomainName.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t + ] + Security.SSLSetPeerDomainName.restype = OSStatus + + Security.SSLHandshake.argtypes = [ + SSLContextRef + ] + Security.SSLHandshake.restype = OSStatus + + Security.SSLRead.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t, + POINTER(c_size_t) + ] + Security.SSLRead.restype = OSStatus + + Security.SSLWrite.argtypes = [ + SSLContextRef, + c_char_p, + c_size_t, + POINTER(c_size_t) + ] + Security.SSLWrite.restype = OSStatus + + Security.SSLClose.argtypes = [ + SSLContextRef + ] + Security.SSLClose.restype = OSStatus + + Security.SSLGetNumberSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberSupportedCiphers.restype = OSStatus + + Security.SSLGetSupportedCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetSupportedCiphers.restype = OSStatus + + Security.SSLSetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + c_size_t + ] + Security.SSLSetEnabledCiphers.restype = OSStatus + + Security.SSLGetNumberEnabledCiphers.argtype = [ + SSLContextRef, + POINTER(c_size_t) + ] + Security.SSLGetNumberEnabledCiphers.restype = OSStatus + + Security.SSLGetEnabledCiphers.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite), + POINTER(c_size_t) + ] + Security.SSLGetEnabledCiphers.restype = OSStatus + + Security.SSLGetNegotiatedCipher.argtypes = [ + SSLContextRef, + POINTER(SSLCipherSuite) + ] + Security.SSLGetNegotiatedCipher.restype = OSStatus + + Security.SSLGetNegotiatedProtocolVersion.argtypes = [ + SSLContextRef, + POINTER(SSLProtocol) + ] + Security.SSLGetNegotiatedProtocolVersion.restype = OSStatus + + Security.SSLCopyPeerTrust.argtypes = [ + SSLContextRef, + POINTER(SecTrustRef) + ] + Security.SSLCopyPeerTrust.restype = OSStatus + + Security.SecTrustSetAnchorCertificates.argtypes = [ + SecTrustRef, + CFArrayRef + ] + Security.SecTrustSetAnchorCertificates.restype = OSStatus + + Security.SecTrustSetAnchorCertificatesOnly.argstypes = [ + SecTrustRef, + Boolean + ] + Security.SecTrustSetAnchorCertificatesOnly.restype = OSStatus + + Security.SecTrustEvaluate.argtypes = [ + SecTrustRef, + POINTER(SecTrustResultType) + ] + Security.SecTrustEvaluate.restype = OSStatus + + Security.SecTrustGetCertificateCount.argtypes = [ + SecTrustRef + ] + Security.SecTrustGetCertificateCount.restype = CFIndex + + Security.SecTrustGetCertificateAtIndex.argtypes = [ + SecTrustRef, + CFIndex + ] + Security.SecTrustGetCertificateAtIndex.restype = SecCertificateRef + + Security.SSLCreateContext.argtypes = [ + CFAllocatorRef, + SSLProtocolSide, + SSLConnectionType + ] + Security.SSLCreateContext.restype = SSLContextRef + + Security.SSLSetSessionOption.argtypes = [ + SSLContextRef, + SSLSessionOption, + Boolean + ] + Security.SSLSetSessionOption.restype = OSStatus + + Security.SSLSetProtocolVersionMin.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMin.restype = OSStatus + + Security.SSLSetProtocolVersionMax.argtypes = [ + SSLContextRef, + SSLProtocol + ] + Security.SSLSetProtocolVersionMax.restype = OSStatus + + Security.SecCopyErrorMessageString.argtypes = [ + OSStatus, + c_void_p + ] + Security.SecCopyErrorMessageString.restype = CFStringRef + + Security.SSLReadFunc = SSLReadFunc + Security.SSLWriteFunc = SSLWriteFunc + Security.SSLContextRef = SSLContextRef + Security.SSLProtocol = SSLProtocol + Security.SSLCipherSuite = SSLCipherSuite + Security.SecIdentityRef = SecIdentityRef + Security.SecKeychainRef = SecKeychainRef + Security.SecTrustRef = SecTrustRef + Security.SecTrustResultType = SecTrustResultType + Security.SecExternalFormat = SecExternalFormat + Security.OSStatus = OSStatus + + Security.kSecImportExportPassphrase = CFStringRef.in_dll( + Security, 'kSecImportExportPassphrase' + ) + Security.kSecImportItemIdentity = CFStringRef.in_dll( + Security, 'kSecImportItemIdentity' + ) + + # CoreFoundation time! + CoreFoundation.CFRetain.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRetain.restype = CFTypeRef + + CoreFoundation.CFRelease.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFRelease.restype = None + + CoreFoundation.CFGetTypeID.argtypes = [ + CFTypeRef + ] + CoreFoundation.CFGetTypeID.restype = CFTypeID + + CoreFoundation.CFStringCreateWithCString.argtypes = [ + CFAllocatorRef, + c_char_p, + CFStringEncoding + ] + CoreFoundation.CFStringCreateWithCString.restype = CFStringRef + + CoreFoundation.CFStringGetCStringPtr.argtypes = [ + CFStringRef, + CFStringEncoding + ] + CoreFoundation.CFStringGetCStringPtr.restype = c_char_p + + CoreFoundation.CFStringGetCString.argtypes = [ + CFStringRef, + c_char_p, + CFIndex, + CFStringEncoding + ] + CoreFoundation.CFStringGetCString.restype = c_bool + + CoreFoundation.CFDataCreate.argtypes = [ + CFAllocatorRef, + c_char_p, + CFIndex + ] + CoreFoundation.CFDataCreate.restype = CFDataRef + + CoreFoundation.CFDataGetLength.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetLength.restype = CFIndex + + CoreFoundation.CFDataGetBytePtr.argtypes = [ + CFDataRef + ] + CoreFoundation.CFDataGetBytePtr.restype = c_void_p + + CoreFoundation.CFDictionaryCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + POINTER(CFTypeRef), + CFIndex, + CFDictionaryKeyCallBacks, + CFDictionaryValueCallBacks + ] + CoreFoundation.CFDictionaryCreate.restype = CFDictionaryRef + + CoreFoundation.CFDictionaryGetValue.argtypes = [ + CFDictionaryRef, + CFTypeRef + ] + CoreFoundation.CFDictionaryGetValue.restype = CFTypeRef + + CoreFoundation.CFArrayCreate.argtypes = [ + CFAllocatorRef, + POINTER(CFTypeRef), + CFIndex, + CFArrayCallBacks, + ] + CoreFoundation.CFArrayCreate.restype = CFArrayRef + + CoreFoundation.CFArrayCreateMutable.argtypes = [ + CFAllocatorRef, + CFIndex, + CFArrayCallBacks + ] + CoreFoundation.CFArrayCreateMutable.restype = CFMutableArrayRef + + CoreFoundation.CFArrayAppendValue.argtypes = [ + CFMutableArrayRef, + c_void_p + ] + CoreFoundation.CFArrayAppendValue.restype = None + + CoreFoundation.CFArrayGetCount.argtypes = [ + CFArrayRef + ] + CoreFoundation.CFArrayGetCount.restype = CFIndex + + CoreFoundation.CFArrayGetValueAtIndex.argtypes = [ + CFArrayRef, + CFIndex + ] + CoreFoundation.CFArrayGetValueAtIndex.restype = c_void_p + + CoreFoundation.kCFAllocatorDefault = CFAllocatorRef.in_dll( + CoreFoundation, 'kCFAllocatorDefault' + ) + CoreFoundation.kCFTypeArrayCallBacks = c_void_p.in_dll(CoreFoundation, 'kCFTypeArrayCallBacks') + CoreFoundation.kCFTypeDictionaryKeyCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryKeyCallBacks' + ) + CoreFoundation.kCFTypeDictionaryValueCallBacks = c_void_p.in_dll( + CoreFoundation, 'kCFTypeDictionaryValueCallBacks' + ) + + CoreFoundation.CFTypeRef = CFTypeRef + CoreFoundation.CFArrayRef = CFArrayRef + CoreFoundation.CFStringRef = CFStringRef + CoreFoundation.CFDictionaryRef = CFDictionaryRef + +except (AttributeError): + raise ImportError('Error initializing ctypes') + + +class CFConst(object): + """ + A class object that acts as essentially a namespace for CoreFoundation + constants. + """ + kCFStringEncodingUTF8 = CFStringEncoding(0x08000100) + + +class SecurityConst(object): + """ + A class object that acts as essentially a namespace for Security constants. + """ + kSSLSessionOptionBreakOnServerAuth = 0 + + kSSLProtocol2 = 1 + kSSLProtocol3 = 2 + kTLSProtocol1 = 4 + kTLSProtocol11 = 7 + kTLSProtocol12 = 8 + + kSSLClientSide = 1 + kSSLStreamType = 0 + + kSecFormatPEMSequence = 10 + + kSecTrustResultInvalid = 0 + kSecTrustResultProceed = 1 + # This gap is present on purpose: this was kSecTrustResultConfirm, which + # is deprecated. + kSecTrustResultDeny = 3 + kSecTrustResultUnspecified = 4 + kSecTrustResultRecoverableTrustFailure = 5 + kSecTrustResultFatalTrustFailure = 6 + kSecTrustResultOtherError = 7 + + errSSLProtocol = -9800 + errSSLWouldBlock = -9803 + errSSLClosedGraceful = -9805 + errSSLClosedNoNotify = -9816 + errSSLClosedAbort = -9806 + + errSSLXCertChainInvalid = -9807 + errSSLCrypto = -9809 + errSSLInternal = -9810 + errSSLCertExpired = -9814 + errSSLCertNotYetValid = -9815 + errSSLUnknownRootCert = -9812 + errSSLNoRootCert = -9813 + errSSLHostNameMismatch = -9843 + errSSLPeerHandshakeFail = -9824 + errSSLPeerUserCancelled = -9839 + errSSLWeakPeerEphemeralDHKey = -9850 + errSSLServerAuthCompleted = -9841 + errSSLRecordOverflow = -9847 + + errSecVerifyFailed = -67808 + errSecNoTrustSettings = -25263 + errSecItemNotFound = -25300 + errSecInvalidTrustSettings = -25262 + + # Cipher suites. We only pick the ones our default cipher string allows. + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030 + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F + TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3 + TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F + TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2 + TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024 + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028 + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A + TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014 + TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B + TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A + TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039 + TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027 + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009 + TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040 + TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033 + TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032 + TLS_RSA_WITH_AES_256_GCM_SHA384 = 0x009D + TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C + TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D + TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C + TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035 + TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F + TLS_AES_128_GCM_SHA256 = 0x1301 + TLS_AES_256_GCM_SHA384 = 0x1302 + TLS_CHACHA20_POLY1305_SHA256 = 0x1303 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py new file mode 100644 index 0000000..b13cd9e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/_securetransport/low_level.py @@ -0,0 +1,346 @@ +""" +Low-level helpers for the SecureTransport bindings. + +These are Python functions that are not directly related to the high-level APIs +but are necessary to get them to work. They include a whole bunch of low-level +CoreFoundation messing about and memory management. The concerns in this module +are almost entirely about trying to avoid memory leaks and providing +appropriate and useful assistance to the higher-level code. +""" +import base64 +import ctypes +import itertools +import re +import os +import ssl +import tempfile + +from .bindings import Security, CoreFoundation, CFConst + + +# This regular expression is used to grab PEM data out of a PEM bundle. +_PEM_CERTS_RE = re.compile( + b"-----BEGIN CERTIFICATE-----\n(.*?)\n-----END CERTIFICATE-----", re.DOTALL +) + + +def _cf_data_from_bytes(bytestring): + """ + Given a bytestring, create a CFData object from it. This CFData object must + be CFReleased by the caller. + """ + return CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, bytestring, len(bytestring) + ) + + +def _cf_dictionary_from_tuples(tuples): + """ + Given a list of Python tuples, create an associated CFDictionary. + """ + dictionary_size = len(tuples) + + # We need to get the dictionary keys and values out in the same order. + keys = (t[0] for t in tuples) + values = (t[1] for t in tuples) + cf_keys = (CoreFoundation.CFTypeRef * dictionary_size)(*keys) + cf_values = (CoreFoundation.CFTypeRef * dictionary_size)(*values) + + return CoreFoundation.CFDictionaryCreate( + CoreFoundation.kCFAllocatorDefault, + cf_keys, + cf_values, + dictionary_size, + CoreFoundation.kCFTypeDictionaryKeyCallBacks, + CoreFoundation.kCFTypeDictionaryValueCallBacks, + ) + + +def _cf_string_to_unicode(value): + """ + Creates a Unicode string from a CFString object. Used entirely for error + reporting. + + Yes, it annoys me quite a lot that this function is this complex. + """ + value_as_void_p = ctypes.cast(value, ctypes.POINTER(ctypes.c_void_p)) + + string = CoreFoundation.CFStringGetCStringPtr( + value_as_void_p, + CFConst.kCFStringEncodingUTF8 + ) + if string is None: + buffer = ctypes.create_string_buffer(1024) + result = CoreFoundation.CFStringGetCString( + value_as_void_p, + buffer, + 1024, + CFConst.kCFStringEncodingUTF8 + ) + if not result: + raise OSError('Error copying C string from CFStringRef') + string = buffer.value + if string is not None: + string = string.decode('utf-8') + return string + + +def _assert_no_error(error, exception_class=None): + """ + Checks the return code and throws an exception if there is an error to + report + """ + if error == 0: + return + + cf_error_string = Security.SecCopyErrorMessageString(error, None) + output = _cf_string_to_unicode(cf_error_string) + CoreFoundation.CFRelease(cf_error_string) + + if output is None or output == u'': + output = u'OSStatus %s' % error + + if exception_class is None: + exception_class = ssl.SSLError + + raise exception_class(output) + + +def _cert_array_from_pem(pem_bundle): + """ + Given a bundle of certs in PEM format, turns them into a CFArray of certs + that can be used to validate a cert chain. + """ + # Normalize the PEM bundle's line endings. + pem_bundle = pem_bundle.replace(b"\r\n", b"\n") + + der_certs = [ + base64.b64decode(match.group(1)) + for match in _PEM_CERTS_RE.finditer(pem_bundle) + ] + if not der_certs: + raise ssl.SSLError("No root certificates specified") + + cert_array = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks) + ) + if not cert_array: + raise ssl.SSLError("Unable to allocate memory!") + + try: + for der_bytes in der_certs: + certdata = _cf_data_from_bytes(der_bytes) + if not certdata: + raise ssl.SSLError("Unable to allocate memory!") + cert = Security.SecCertificateCreateWithData( + CoreFoundation.kCFAllocatorDefault, certdata + ) + CoreFoundation.CFRelease(certdata) + if not cert: + raise ssl.SSLError("Unable to build cert object!") + + CoreFoundation.CFArrayAppendValue(cert_array, cert) + CoreFoundation.CFRelease(cert) + except Exception: + # We need to free the array before the exception bubbles further. + # We only want to do that if an error occurs: otherwise, the caller + # should free. + CoreFoundation.CFRelease(cert_array) + + return cert_array + + +def _is_cert(item): + """ + Returns True if a given CFTypeRef is a certificate. + """ + expected = Security.SecCertificateGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _is_identity(item): + """ + Returns True if a given CFTypeRef is an identity. + """ + expected = Security.SecIdentityGetTypeID() + return CoreFoundation.CFGetTypeID(item) == expected + + +def _temporary_keychain(): + """ + This function creates a temporary Mac keychain that we can use to work with + credentials. This keychain uses a one-time password and a temporary file to + store the data. We expect to have one keychain per socket. The returned + SecKeychainRef must be freed by the caller, including calling + SecKeychainDelete. + + Returns a tuple of the SecKeychainRef and the path to the temporary + directory that contains it. + """ + # Unfortunately, SecKeychainCreate requires a path to a keychain. This + # means we cannot use mkstemp to use a generic temporary file. Instead, + # we're going to create a temporary directory and a filename to use there. + # This filename will be 8 random bytes expanded into base64. We also need + # some random bytes to password-protect the keychain we're creating, so we + # ask for 40 random bytes. + random_bytes = os.urandom(40) + filename = base64.b16encode(random_bytes[:8]).decode('utf-8') + password = base64.b16encode(random_bytes[8:]) # Must be valid UTF-8 + tempdirectory = tempfile.mkdtemp() + + keychain_path = os.path.join(tempdirectory, filename).encode('utf-8') + + # We now want to create the keychain itself. + keychain = Security.SecKeychainRef() + status = Security.SecKeychainCreate( + keychain_path, + len(password), + password, + False, + None, + ctypes.byref(keychain) + ) + _assert_no_error(status) + + # Having created the keychain, we want to pass it off to the caller. + return keychain, tempdirectory + + +def _load_items_from_file(keychain, path): + """ + Given a single file, loads all the trust objects from it into arrays and + the keychain. + Returns a tuple of lists: the first list is a list of identities, the + second a list of certs. + """ + certificates = [] + identities = [] + result_array = None + + with open(path, 'rb') as f: + raw_filedata = f.read() + + try: + filedata = CoreFoundation.CFDataCreate( + CoreFoundation.kCFAllocatorDefault, + raw_filedata, + len(raw_filedata) + ) + result_array = CoreFoundation.CFArrayRef() + result = Security.SecItemImport( + filedata, # cert data + None, # Filename, leaving it out for now + None, # What the type of the file is, we don't care + None, # what's in the file, we don't care + 0, # import flags + None, # key params, can include passphrase in the future + keychain, # The keychain to insert into + ctypes.byref(result_array) # Results + ) + _assert_no_error(result) + + # A CFArray is not very useful to us as an intermediary + # representation, so we are going to extract the objects we want + # and then free the array. We don't need to keep hold of keys: the + # keychain already has them! + result_count = CoreFoundation.CFArrayGetCount(result_array) + for index in range(result_count): + item = CoreFoundation.CFArrayGetValueAtIndex( + result_array, index + ) + item = ctypes.cast(item, CoreFoundation.CFTypeRef) + + if _is_cert(item): + CoreFoundation.CFRetain(item) + certificates.append(item) + elif _is_identity(item): + CoreFoundation.CFRetain(item) + identities.append(item) + finally: + if result_array: + CoreFoundation.CFRelease(result_array) + + CoreFoundation.CFRelease(filedata) + + return (identities, certificates) + + +def _load_client_cert_chain(keychain, *paths): + """ + Load certificates and maybe keys from a number of files. Has the end goal + of returning a CFArray containing one SecIdentityRef, and then zero or more + SecCertificateRef objects, suitable for use as a client certificate trust + chain. + """ + # Ok, the strategy. + # + # This relies on knowing that macOS will not give you a SecIdentityRef + # unless you have imported a key into a keychain. This is a somewhat + # artificial limitation of macOS (for example, it doesn't necessarily + # affect iOS), but there is nothing inside Security.framework that lets you + # get a SecIdentityRef without having a key in a keychain. + # + # So the policy here is we take all the files and iterate them in order. + # Each one will use SecItemImport to have one or more objects loaded from + # it. We will also point at a keychain that macOS can use to work with the + # private key. + # + # Once we have all the objects, we'll check what we actually have. If we + # already have a SecIdentityRef in hand, fab: we'll use that. Otherwise, + # we'll take the first certificate (which we assume to be our leaf) and + # ask the keychain to give us a SecIdentityRef with that cert's associated + # key. + # + # We'll then return a CFArray containing the trust chain: one + # SecIdentityRef and then zero-or-more SecCertificateRef objects. The + # responsibility for freeing this CFArray will be with the caller. This + # CFArray must remain alive for the entire connection, so in practice it + # will be stored with a single SSLSocket, along with the reference to the + # keychain. + certificates = [] + identities = [] + + # Filter out bad paths. + paths = (path for path in paths if path) + + try: + for file_path in paths: + new_identities, new_certs = _load_items_from_file( + keychain, file_path + ) + identities.extend(new_identities) + certificates.extend(new_certs) + + # Ok, we have everything. The question is: do we have an identity? If + # not, we want to grab one from the first cert we have. + if not identities: + new_identity = Security.SecIdentityRef() + status = Security.SecIdentityCreateWithCertificate( + keychain, + certificates[0], + ctypes.byref(new_identity) + ) + _assert_no_error(status) + identities.append(new_identity) + + # We now want to release the original certificate, as we no longer + # need it. + CoreFoundation.CFRelease(certificates.pop(0)) + + # We now need to build a new CFArray that holds the trust chain. + trust_chain = CoreFoundation.CFArrayCreateMutable( + CoreFoundation.kCFAllocatorDefault, + 0, + ctypes.byref(CoreFoundation.kCFTypeArrayCallBacks), + ) + for item in itertools.chain(identities, certificates): + # ArrayAppendValue does a CFRetain on the item. That's fine, + # because the finally block will release our other refs to them. + CoreFoundation.CFArrayAppendValue(trust_chain, item) + + return trust_chain + finally: + for obj in itertools.chain(identities, certificates): + CoreFoundation.CFRelease(obj) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py new file mode 100644 index 0000000..59f2a61 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/appengine.py @@ -0,0 +1,305 @@ +""" +This module provides a pool manager that uses Google App Engine's +`URLFetch Service <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + +Example usage:: + + from pip._vendor.urllib3 import PoolManager + from pip._vendor.urllib3.contrib.appengine import AppEngineManager, is_appengine_sandbox + + if is_appengine_sandbox(): + # AppEngineManager uses AppEngine's URLFetch API behind the scenes + http = AppEngineManager() + else: + # PoolManager uses a socket-level API behind the scenes + http = PoolManager() + + r = http.request('GET', 'https://google.com/') + +There are `limitations <https://cloud.google.com/appengine/docs/python/\ +urlfetch/#Python_Quotas_and_limits>`_ to the URLFetch service and it may not be +the best choice for your application. There are three options for using +urllib3 on Google App Engine: + +1. You can use :class:`AppEngineManager` with URLFetch. URLFetch is + cost-effective in many circumstances as long as your usage is within the + limitations. +2. You can use a normal :class:`~urllib3.PoolManager` by enabling sockets. + Sockets also have `limitations and restrictions + <https://cloud.google.com/appengine/docs/python/sockets/\ + #limitations-and-restrictions>`_ and have a lower free quota than URLFetch. + To use sockets, be sure to specify the following in your ``app.yaml``:: + + env_variables: + GAE_USE_SOCKETS_HTTPLIB : 'true' + +3. If you are using `App Engine Flexible +<https://cloud.google.com/appengine/docs/flexible/>`_, you can use the standard +:class:`PoolManager` without any configuration or special environment variables. +""" + +from __future__ import absolute_import +import logging +import os +import warnings +from ..packages.six.moves.urllib.parse import urljoin + +from ..exceptions import ( + HTTPError, + HTTPWarning, + MaxRetryError, + ProtocolError, + TimeoutError, + SSLError +) + +from ..packages.six import BytesIO +from ..request import RequestMethods +from ..response import HTTPResponse +from ..util.timeout import Timeout +from ..util.retry import Retry + +try: + from google.appengine.api import urlfetch +except ImportError: + urlfetch = None + + +log = logging.getLogger(__name__) + + +class AppEnginePlatformWarning(HTTPWarning): + pass + + +class AppEnginePlatformError(HTTPError): + pass + + +class AppEngineManager(RequestMethods): + """ + Connection manager for Google App Engine sandbox applications. + + This manager uses the URLFetch service directly instead of using the + emulated httplib, and is subject to URLFetch limitations as described in + the App Engine documentation `here + <https://cloud.google.com/appengine/docs/python/urlfetch>`_. + + Notably it will raise an :class:`AppEnginePlatformError` if: + * URLFetch is not available. + * If you attempt to use this on App Engine Flexible, as full socket + support is available. + * If a request size is more than 10 megabytes. + * If a response size is more than 32 megabtyes. + * If you use an unsupported request method such as OPTIONS. + + Beyond those cases, it will raise normal urllib3 errors. + """ + + def __init__(self, headers=None, retries=None, validate_certificate=True, + urlfetch_retries=True): + if not urlfetch: + raise AppEnginePlatformError( + "URLFetch is not available in this environment.") + + if is_prod_appengine_mvms(): + raise AppEnginePlatformError( + "Use normal urllib3.PoolManager instead of AppEngineManager" + "on Managed VMs, as using URLFetch is not necessary in " + "this environment.") + + warnings.warn( + "urllib3 is using URLFetch on Google App Engine sandbox instead " + "of sockets. To use sockets directly instead of URLFetch see " + "https://urllib3.readthedocs.io/en/latest/reference/urllib3.contrib.html.", + AppEnginePlatformWarning) + + RequestMethods.__init__(self, headers) + self.validate_certificate = validate_certificate + self.urlfetch_retries = urlfetch_retries + + self.retries = retries or Retry.DEFAULT + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + # Return False to re-raise any potential exceptions + return False + + def urlopen(self, method, url, body=None, headers=None, + retries=None, redirect=True, timeout=Timeout.DEFAULT_TIMEOUT, + **response_kw): + + retries = self._get_retries(retries, redirect) + + try: + follow_redirects = ( + redirect and + retries.redirect != 0 and + retries.total) + response = urlfetch.fetch( + url, + payload=body, + method=method, + headers=headers or {}, + allow_truncated=False, + follow_redirects=self.urlfetch_retries and follow_redirects, + deadline=self._get_absolute_timeout(timeout), + validate_certificate=self.validate_certificate, + ) + except urlfetch.DeadlineExceededError as e: + raise TimeoutError(self, e) + + except urlfetch.InvalidURLError as e: + if 'too large' in str(e): + raise AppEnginePlatformError( + "URLFetch request too large, URLFetch only " + "supports requests up to 10mb in size.", e) + raise ProtocolError(e) + + except urlfetch.DownloadError as e: + if 'Too many redirects' in str(e): + raise MaxRetryError(self, url, reason=e) + raise ProtocolError(e) + + except urlfetch.ResponseTooLargeError as e: + raise AppEnginePlatformError( + "URLFetch response too large, URLFetch only supports" + "responses up to 32mb in size.", e) + + except urlfetch.SSLCertificateError as e: + raise SSLError(e) + + except urlfetch.InvalidMethodError as e: + raise AppEnginePlatformError( + "URLFetch does not support method: %s" % method, e) + + http_response = self._urlfetch_response_to_http_response( + response, retries=retries, **response_kw) + + # Handle redirect? + redirect_location = redirect and http_response.get_redirect_location() + if redirect_location: + # Check for redirect response + if (self.urlfetch_retries and retries.raise_on_redirect): + raise MaxRetryError(self, url, "too many redirects") + else: + if http_response.status == 303: + method = 'GET' + + try: + retries = retries.increment(method, url, response=http_response, _pool=self) + except MaxRetryError: + if retries.raise_on_redirect: + raise MaxRetryError(self, url, "too many redirects") + return http_response + + retries.sleep_for_retry(http_response) + log.debug("Redirecting %s -> %s", url, redirect_location) + redirect_url = urljoin(url, redirect_location) + return self.urlopen( + method, redirect_url, body, headers, + retries=retries, redirect=redirect, + timeout=timeout, **response_kw) + + # Check if we should retry the HTTP response. + has_retry_after = bool(http_response.getheader('Retry-After')) + if retries.is_retry(method, http_response.status, has_retry_after): + retries = retries.increment( + method, url, response=http_response, _pool=self) + log.debug("Retry: %s", url) + retries.sleep(http_response) + return self.urlopen( + method, url, + body=body, headers=headers, + retries=retries, redirect=redirect, + timeout=timeout, **response_kw) + + return http_response + + def _urlfetch_response_to_http_response(self, urlfetch_resp, **response_kw): + + if is_prod_appengine(): + # Production GAE handles deflate encoding automatically, but does + # not remove the encoding header. + content_encoding = urlfetch_resp.headers.get('content-encoding') + + if content_encoding == 'deflate': + del urlfetch_resp.headers['content-encoding'] + + transfer_encoding = urlfetch_resp.headers.get('transfer-encoding') + # We have a full response's content, + # so let's make sure we don't report ourselves as chunked data. + if transfer_encoding == 'chunked': + encodings = transfer_encoding.split(",") + encodings.remove('chunked') + urlfetch_resp.headers['transfer-encoding'] = ','.join(encodings) + + original_response = HTTPResponse( + # In order for decoding to work, we must present the content as + # a file-like object. + body=BytesIO(urlfetch_resp.content), + msg=urlfetch_resp.header_msg, + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + **response_kw + ) + + return HTTPResponse( + body=BytesIO(urlfetch_resp.content), + headers=urlfetch_resp.headers, + status=urlfetch_resp.status_code, + original_response=original_response, + **response_kw + ) + + def _get_absolute_timeout(self, timeout): + if timeout is Timeout.DEFAULT_TIMEOUT: + return None # Defer to URLFetch's default. + if isinstance(timeout, Timeout): + if timeout._read is not None or timeout._connect is not None: + warnings.warn( + "URLFetch does not support granular timeout settings, " + "reverting to total or default URLFetch timeout.", + AppEnginePlatformWarning) + return timeout.total + return timeout + + def _get_retries(self, retries, redirect): + if not isinstance(retries, Retry): + retries = Retry.from_int( + retries, redirect=redirect, default=self.retries) + + if retries.connect or retries.read or retries.redirect: + warnings.warn( + "URLFetch only supports total retries and does not " + "recognize connect, read, or redirect retry parameters.", + AppEnginePlatformWarning) + + return retries + + +def is_appengine(): + return (is_local_appengine() or + is_prod_appengine() or + is_prod_appengine_mvms()) + + +def is_appengine_sandbox(): + return is_appengine() and not is_prod_appengine_mvms() + + +def is_local_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Development/' in os.environ['SERVER_SOFTWARE']) + + +def is_prod_appengine(): + return ('APPENGINE_RUNTIME' in os.environ and + 'Google App Engine/' in os.environ['SERVER_SOFTWARE'] and + not is_prod_appengine_mvms()) + + +def is_prod_appengine_mvms(): + return os.environ.get('GAE_VM', False) == 'true' diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py new file mode 100644 index 0000000..642e99e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/ntlmpool.py @@ -0,0 +1,112 @@ +""" +NTLM authenticating pool, contributed by erikcederstran + +Issue #10, see: http://code.google.com/p/urllib3/issues/detail?id=10 +""" +from __future__ import absolute_import + +from logging import getLogger +from ntlm import ntlm + +from .. import HTTPSConnectionPool +from ..packages.six.moves.http_client import HTTPSConnection + + +log = getLogger(__name__) + + +class NTLMConnectionPool(HTTPSConnectionPool): + """ + Implements an NTLM authentication version of an urllib3 connection pool + """ + + scheme = 'https' + + def __init__(self, user, pw, authurl, *args, **kwargs): + """ + authurl is a random URL on the server that is protected by NTLM. + user is the Windows user, probably in the DOMAIN\\username format. + pw is the password for the user. + """ + super(NTLMConnectionPool, self).__init__(*args, **kwargs) + self.authurl = authurl + self.rawuser = user + user_parts = user.split('\\', 1) + self.domain = user_parts[0].upper() + self.user = user_parts[1] + self.pw = pw + + def _new_conn(self): + # Performs the NTLM handshake that secures the connection. The socket + # must be kept open while requests are performed. + self.num_connections += 1 + log.debug('Starting NTLM HTTPS connection no. %d: https://%s%s', + self.num_connections, self.host, self.authurl) + + headers = {} + headers['Connection'] = 'Keep-Alive' + req_header = 'Authorization' + resp_header = 'www-authenticate' + + conn = HTTPSConnection(host=self.host, port=self.port) + + # Send negotiation message + headers[req_header] = ( + 'NTLM %s' % ntlm.create_NTLM_NEGOTIATE_MESSAGE(self.rawuser)) + log.debug('Request headers: %s', headers) + conn.request('GET', self.authurl, None, headers) + res = conn.getresponse() + reshdr = dict(res.getheaders()) + log.debug('Response status: %s %s', res.status, res.reason) + log.debug('Response headers: %s', reshdr) + log.debug('Response data: %s [...]', res.read(100)) + + # Remove the reference to the socket, so that it can not be closed by + # the response object (we want to keep the socket open) + res.fp = None + + # Server should respond with a challenge message + auth_header_values = reshdr[resp_header].split(', ') + auth_header_value = None + for s in auth_header_values: + if s[:5] == 'NTLM ': + auth_header_value = s[5:] + if auth_header_value is None: + raise Exception('Unexpected %s response header: %s' % + (resp_header, reshdr[resp_header])) + + # Send authentication message + ServerChallenge, NegotiateFlags = \ + ntlm.parse_NTLM_CHALLENGE_MESSAGE(auth_header_value) + auth_msg = ntlm.create_NTLM_AUTHENTICATE_MESSAGE(ServerChallenge, + self.user, + self.domain, + self.pw, + NegotiateFlags) + headers[req_header] = 'NTLM %s' % auth_msg + log.debug('Request headers: %s', headers) + conn.request('GET', self.authurl, None, headers) + res = conn.getresponse() + log.debug('Response status: %s %s', res.status, res.reason) + log.debug('Response headers: %s', dict(res.getheaders())) + log.debug('Response data: %s [...]', res.read()[:100]) + if res.status != 200: + if res.status == 401: + raise Exception('Server rejected request: wrong ' + 'username or password') + raise Exception('Wrong server response: %s %s' % + (res.status, res.reason)) + + res.fp = None + log.debug('Connection established') + return conn + + def urlopen(self, method, url, body=None, headers=None, retries=3, + redirect=True, assert_same_host=True): + if headers is None: + headers = {} + headers['Connection'] = 'Keep-Alive' + return super(NTLMConnectionPool, self).urlopen(method, url, body, + headers, retries, + redirect, + assert_same_host) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py new file mode 100644 index 0000000..6dd3a01 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py @@ -0,0 +1,457 @@ +""" +SSL with SNI_-support for Python 2. Follow these instructions if you would +like to verify SSL certificates in Python 2. Note, the default libraries do +*not* do certificate checking; you need to do additional work to validate +certificates yourself. + +This needs the following packages installed: + +* pyOpenSSL (tested with 16.0.0) +* cryptography (minimum 1.3.4, from pyopenssl) +* idna (minimum 2.0, from cryptography) + +However, pyopenssl depends on cryptography, which depends on idna, so while we +use all three directly here we end up having relatively few packages required. + +You can install them with the following command: + + pip install pyopenssl cryptography idna + +To activate certificate checking, call +:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code +before you begin making HTTP requests. This can be done in a ``sitecustomize`` +module, or at any other time before your application begins using ``urllib3``, +like this:: + + try: + import urllib3.contrib.pyopenssl + urllib3.contrib.pyopenssl.inject_into_urllib3() + except ImportError: + pass + +Now you can use :mod:`urllib3` as you normally would, and it will support SNI +when the required modules are installed. + +Activating this module also has the positive side effect of disabling SSL/TLS +compression in Python 2 (see `CRIME attack`_). + +If you want to configure the default list of supported cipher suites, you can +set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable. + +.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication +.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit) +""" +from __future__ import absolute_import + +import OpenSSL.SSL +from cryptography import x509 +from cryptography.hazmat.backends.openssl import backend as openssl_backend +from cryptography.hazmat.backends.openssl.x509 import _Certificate +try: + from cryptography.x509 import UnsupportedExtension +except ImportError: + # UnsupportedExtension is gone in cryptography >= 2.1.0 + class UnsupportedExtension(Exception): + pass + +from socket import timeout, error as SocketError +from io import BytesIO + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +import logging +import ssl +from ..packages import six +import sys + +from .. import util + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works. +HAS_SNI = True + +# Map from urllib3 to PyOpenSSL compatible parameter-values. +_openssl_versions = { + ssl.PROTOCOL_SSLv23: OpenSSL.SSL.SSLv23_METHOD, + ssl.PROTOCOL_TLSv1: OpenSSL.SSL.TLSv1_METHOD, +} + +if hasattr(ssl, 'PROTOCOL_TLSv1_1') and hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'): + _openssl_versions[ssl.PROTOCOL_TLSv1_1] = OpenSSL.SSL.TLSv1_1_METHOD + +if hasattr(ssl, 'PROTOCOL_TLSv1_2') and hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'): + _openssl_versions[ssl.PROTOCOL_TLSv1_2] = OpenSSL.SSL.TLSv1_2_METHOD + +try: + _openssl_versions.update({ssl.PROTOCOL_SSLv3: OpenSSL.SSL.SSLv3_METHOD}) +except AttributeError: + pass + +_stdlib_to_openssl_verify = { + ssl.CERT_NONE: OpenSSL.SSL.VERIFY_NONE, + ssl.CERT_OPTIONAL: OpenSSL.SSL.VERIFY_PEER, + ssl.CERT_REQUIRED: + OpenSSL.SSL.VERIFY_PEER + OpenSSL.SSL.VERIFY_FAIL_IF_NO_PEER_CERT, +} +_openssl_to_stdlib_verify = dict( + (v, k) for k, v in _stdlib_to_openssl_verify.items() +) + +# OpenSSL will only write 16K at a time +SSL_WRITE_BLOCKSIZE = 16384 + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + + +log = logging.getLogger(__name__) + + +def inject_into_urllib3(): + 'Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.' + + _validate_dependencies_met() + + util.ssl_.SSLContext = PyOpenSSLContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_PYOPENSSL = True + util.ssl_.IS_PYOPENSSL = True + + +def extract_from_urllib3(): + 'Undo monkey-patching by :func:`inject_into_urllib3`.' + + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_PYOPENSSL = False + util.ssl_.IS_PYOPENSSL = False + + +def _validate_dependencies_met(): + """ + Verifies that PyOpenSSL's package-level dependencies have been met. + Throws `ImportError` if they are not met. + """ + # Method added in `cryptography==1.1`; not available in older versions + from cryptography.x509.extensions import Extensions + if getattr(Extensions, "get_extension_for_class", None) is None: + raise ImportError("'cryptography' module missing required functionality. " + "Try upgrading to v1.3.4 or newer.") + + # pyOpenSSL 0.14 and above use cryptography for OpenSSL bindings. The _x509 + # attribute is only present on those versions. + from OpenSSL.crypto import X509 + x509 = X509() + if getattr(x509, "_x509", None) is None: + raise ImportError("'pyOpenSSL' module missing required functionality. " + "Try upgrading to v0.14 or newer.") + + +def _dnsname_to_stdlib(name): + """ + Converts a dNSName SubjectAlternativeName field to the form used by the + standard library on the given Python version. + + Cryptography produces a dNSName as a unicode string that was idna-decoded + from ASCII bytes. We need to idna-encode that string to get it back, and + then on Python 3 we also need to convert to unicode via UTF-8 (the stdlib + uses PyUnicode_FromStringAndSize on it, which decodes via UTF-8). + """ + def idna_encode(name): + """ + Borrowed wholesale from the Python Cryptography Project. It turns out + that we can't just safely call `idna.encode`: it can explode for + wildcard names. This avoids that problem. + """ + from pip._vendor import idna + + for prefix in [u'*.', u'.']: + if name.startswith(prefix): + name = name[len(prefix):] + return prefix.encode('ascii') + idna.encode(name) + return idna.encode(name) + + name = idna_encode(name) + if sys.version_info >= (3, 0): + name = name.decode('utf-8') + return name + + +def get_subj_alt_name(peer_cert): + """ + Given an PyOpenSSL certificate, provides all the subject alternative names. + """ + # Pass the cert to cryptography, which has much better APIs for this. + if hasattr(peer_cert, "to_cryptography"): + cert = peer_cert.to_cryptography() + else: + # This is technically using private APIs, but should work across all + # relevant versions before PyOpenSSL got a proper API for this. + cert = _Certificate(openssl_backend, peer_cert._x509) + + # We want to find the SAN extension. Ask Cryptography to locate it (it's + # faster than looping in Python) + try: + ext = cert.extensions.get_extension_for_class( + x509.SubjectAlternativeName + ).value + except x509.ExtensionNotFound: + # No such extension, return the empty list. + return [] + except (x509.DuplicateExtension, UnsupportedExtension, + x509.UnsupportedGeneralNameType, UnicodeError) as e: + # A problem has been found with the quality of the certificate. Assume + # no SAN field is present. + log.warning( + "A problem was encountered with the certificate that prevented " + "urllib3 from finding the SubjectAlternativeName field. This can " + "affect certificate validation. The error was %s", + e, + ) + return [] + + # We want to return dNSName and iPAddress fields. We need to cast the IPs + # back to strings because the match_hostname function wants them as + # strings. + # Sadly the DNS names need to be idna encoded and then, on Python 3, UTF-8 + # decoded. This is pretty frustrating, but that's what the standard library + # does with certificates, and so we need to attempt to do the same. + names = [ + ('DNS', _dnsname_to_stdlib(name)) + for name in ext.get_values_for_type(x509.DNSName) + ] + names.extend( + ('IP Address', str(name)) + for name in ext.get_values_for_type(x509.IPAddress) + ) + + return names + + +class WrappedSocket(object): + '''API-compatibility wrapper for Python OpenSSL's Connection-class. + + Note: _makefile_refs, _drop() and _reuse() are needed for the garbage + collector of pypy. + ''' + + def __init__(self, connection, socket, suppress_ragged_eofs=True): + self.connection = connection + self.socket = socket + self.suppress_ragged_eofs = suppress_ragged_eofs + self._makefile_refs = 0 + self._closed = False + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, *args, **kwargs): + try: + data = self.connection.recv(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return b'' + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return b'' + else: + raise + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(self.socket, self.socket.gettimeout()): + raise timeout('The read operation timed out') + else: + return self.recv(*args, **kwargs) + else: + return data + + def recv_into(self, *args, **kwargs): + try: + return self.connection.recv_into(*args, **kwargs) + except OpenSSL.SSL.SysCallError as e: + if self.suppress_ragged_eofs and e.args == (-1, 'Unexpected EOF'): + return 0 + else: + raise SocketError(str(e)) + except OpenSSL.SSL.ZeroReturnError as e: + if self.connection.get_shutdown() == OpenSSL.SSL.RECEIVED_SHUTDOWN: + return 0 + else: + raise + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(self.socket, self.socket.gettimeout()): + raise timeout('The read operation timed out') + else: + return self.recv_into(*args, **kwargs) + + def settimeout(self, timeout): + return self.socket.settimeout(timeout) + + def _send_until_done(self, data): + while True: + try: + return self.connection.send(data) + except OpenSSL.SSL.WantWriteError: + if not util.wait_for_write(self.socket, self.socket.gettimeout()): + raise timeout() + continue + except OpenSSL.SSL.SysCallError as e: + raise SocketError(str(e)) + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self._send_until_done(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + # FIXME rethrow compatible exceptions should we ever use this + self.connection.shutdown() + + def close(self): + if self._makefile_refs < 1: + try: + self._closed = True + return self.connection.close() + except OpenSSL.SSL.Error: + return + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + x509 = self.connection.get_peer_certificate() + + if not x509: + return x509 + + if binary_form: + return OpenSSL.crypto.dump_certificate( + OpenSSL.crypto.FILETYPE_ASN1, + x509) + + return { + 'subject': ( + (('commonName', x509.get_subject().CN),), + ), + 'subjectAltName': get_subj_alt_name(x509) + } + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) +else: # Platform-specific: Python 3 + makefile = backport_makefile + +WrappedSocket.makefile = makefile + + +class PyOpenSSLContext(object): + """ + I am a wrapper class for the PyOpenSSL ``Context`` object. I am responsible + for translating the interface of the standard library ``SSLContext`` object + to calls into PyOpenSSL. + """ + def __init__(self, protocol): + self.protocol = _openssl_versions[protocol] + self._ctx = OpenSSL.SSL.Context(self.protocol) + self._options = 0 + self.check_hostname = False + + @property + def options(self): + return self._options + + @options.setter + def options(self, value): + self._options = value + self._ctx.set_options(value) + + @property + def verify_mode(self): + return _openssl_to_stdlib_verify[self._ctx.get_verify_mode()] + + @verify_mode.setter + def verify_mode(self, value): + self._ctx.set_verify( + _stdlib_to_openssl_verify[value], + _verify_callback + ) + + def set_default_verify_paths(self): + self._ctx.set_default_verify_paths() + + def set_ciphers(self, ciphers): + if isinstance(ciphers, six.text_type): + ciphers = ciphers.encode('utf-8') + self._ctx.set_cipher_list(ciphers) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + if cafile is not None: + cafile = cafile.encode('utf-8') + if capath is not None: + capath = capath.encode('utf-8') + self._ctx.load_verify_locations(cafile, capath) + if cadata is not None: + self._ctx.load_verify_locations(BytesIO(cadata)) + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._ctx.use_certificate_chain_file(certfile) + if password is not None: + self._ctx.set_passwd_cb(lambda max_length, prompt_twice, userdata: password) + self._ctx.use_privatekey_file(keyfile or certfile) + + def wrap_socket(self, sock, server_side=False, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + server_hostname=None): + cnx = OpenSSL.SSL.Connection(self._ctx, sock) + + if isinstance(server_hostname, six.text_type): # Platform-specific: Python 3 + server_hostname = server_hostname.encode('utf-8') + + if server_hostname is not None: + cnx.set_tlsext_host_name(server_hostname) + + cnx.set_connect_state() + + while True: + try: + cnx.do_handshake() + except OpenSSL.SSL.WantReadError: + if not util.wait_for_read(sock, sock.gettimeout()): + raise timeout('select timed out') + continue + except OpenSSL.SSL.Error as e: + raise ssl.SSLError('bad handshake: %r' % e) + break + + return WrappedSocket(cnx, sock) + + +def _verify_callback(cnx, x509, err_no, err_depth, return_code): + return err_no == 0 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py new file mode 100644 index 0000000..77cb59e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/securetransport.py @@ -0,0 +1,804 @@ +""" +SecureTranport support for urllib3 via ctypes. + +This makes platform-native TLS available to urllib3 users on macOS without the +use of a compiler. This is an important feature because the Python Package +Index is moving to become a TLSv1.2-or-higher server, and the default OpenSSL +that ships with macOS is not capable of doing TLSv1.2. The only way to resolve +this is to give macOS users an alternative solution to the problem, and that +solution is to use SecureTransport. + +We use ctypes here because this solution must not require a compiler. That's +because pip is not allowed to require a compiler either. + +This is not intended to be a seriously long-term solution to this problem. +The hope is that PEP 543 will eventually solve this issue for us, at which +point we can retire this contrib module. But in the short term, we need to +solve the impending tire fire that is Python on Mac without this kind of +contrib module. So...here we are. + +To use this module, simply import and inject it:: + + import urllib3.contrib.securetransport + urllib3.contrib.securetransport.inject_into_urllib3() + +Happy TLSing! +""" +from __future__ import absolute_import + +import contextlib +import ctypes +import errno +import os.path +import shutil +import socket +import ssl +import threading +import weakref + +from .. import util +from ._securetransport.bindings import ( + Security, SecurityConst, CoreFoundation +) +from ._securetransport.low_level import ( + _assert_no_error, _cert_array_from_pem, _temporary_keychain, + _load_client_cert_chain +) + +try: # Platform-specific: Python 2 + from socket import _fileobject +except ImportError: # Platform-specific: Python 3 + _fileobject = None + from ..packages.backports.makefile import backport_makefile + +__all__ = ['inject_into_urllib3', 'extract_from_urllib3'] + +# SNI always works +HAS_SNI = True + +orig_util_HAS_SNI = util.HAS_SNI +orig_util_SSLContext = util.ssl_.SSLContext + +# This dictionary is used by the read callback to obtain a handle to the +# calling wrapped socket. This is a pretty silly approach, but for now it'll +# do. I feel like I should be able to smuggle a handle to the wrapped socket +# directly in the SSLConnectionRef, but for now this approach will work I +# guess. +# +# We need to lock around this structure for inserts, but we don't do it for +# reads/writes in the callbacks. The reasoning here goes as follows: +# +# 1. It is not possible to call into the callbacks before the dictionary is +# populated, so once in the callback the id must be in the dictionary. +# 2. The callbacks don't mutate the dictionary, they only read from it, and +# so cannot conflict with any of the insertions. +# +# This is good: if we had to lock in the callbacks we'd drastically slow down +# the performance of this code. +_connection_refs = weakref.WeakValueDictionary() +_connection_ref_lock = threading.Lock() + +# Limit writes to 16kB. This is OpenSSL's limit, but we'll cargo-cult it over +# for no better reason than we need *a* limit, and this one is right there. +SSL_WRITE_BLOCKSIZE = 16384 + +# This is our equivalent of util.ssl_.DEFAULT_CIPHERS, but expanded out to +# individual cipher suites. We need to do this because this is how +# SecureTransport wants them. +CIPHER_SUITES = [ + SecurityConst.TLS_AES_256_GCM_SHA384, + SecurityConst.TLS_CHACHA20_POLY1305_SHA256, + SecurityConst.TLS_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_256_GCM_SHA384, + SecurityConst.TLS_RSA_WITH_AES_128_GCM_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA256, + SecurityConst.TLS_RSA_WITH_AES_256_CBC_SHA, + SecurityConst.TLS_RSA_WITH_AES_128_CBC_SHA, +] + +# Basically this is simple: for PROTOCOL_SSLv23 we turn it into a low of +# TLSv1 and a high of TLSv1.2. For everything else, we pin to that version. +_protocol_to_min_max = { + ssl.PROTOCOL_SSLv23: (SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol12), +} + +if hasattr(ssl, "PROTOCOL_SSLv2"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv2] = ( + SecurityConst.kSSLProtocol2, SecurityConst.kSSLProtocol2 + ) +if hasattr(ssl, "PROTOCOL_SSLv3"): + _protocol_to_min_max[ssl.PROTOCOL_SSLv3] = ( + SecurityConst.kSSLProtocol3, SecurityConst.kSSLProtocol3 + ) +if hasattr(ssl, "PROTOCOL_TLSv1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1] = ( + SecurityConst.kTLSProtocol1, SecurityConst.kTLSProtocol1 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_1"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_1] = ( + SecurityConst.kTLSProtocol11, SecurityConst.kTLSProtocol11 + ) +if hasattr(ssl, "PROTOCOL_TLSv1_2"): + _protocol_to_min_max[ssl.PROTOCOL_TLSv1_2] = ( + SecurityConst.kTLSProtocol12, SecurityConst.kTLSProtocol12 + ) +if hasattr(ssl, "PROTOCOL_TLS"): + _protocol_to_min_max[ssl.PROTOCOL_TLS] = _protocol_to_min_max[ssl.PROTOCOL_SSLv23] + + +def inject_into_urllib3(): + """ + Monkey-patch urllib3 with SecureTransport-backed SSL-support. + """ + util.ssl_.SSLContext = SecureTransportContext + util.HAS_SNI = HAS_SNI + util.ssl_.HAS_SNI = HAS_SNI + util.IS_SECURETRANSPORT = True + util.ssl_.IS_SECURETRANSPORT = True + + +def extract_from_urllib3(): + """ + Undo monkey-patching by :func:`inject_into_urllib3`. + """ + util.ssl_.SSLContext = orig_util_SSLContext + util.HAS_SNI = orig_util_HAS_SNI + util.ssl_.HAS_SNI = orig_util_HAS_SNI + util.IS_SECURETRANSPORT = False + util.ssl_.IS_SECURETRANSPORT = False + + +def _read_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport read callback. This is called by ST to request that data + be returned from the socket. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + requested_length = data_length_pointer[0] + + timeout = wrapped_socket.gettimeout() + error = None + read_count = 0 + + try: + while read_count < requested_length: + if timeout is None or timeout >= 0: + if not util.wait_for_read(base_socket, timeout): + raise socket.error(errno.EAGAIN, 'timed out') + + remaining = requested_length - read_count + buffer = (ctypes.c_char * remaining).from_address( + data_buffer + read_count + ) + chunk_size = base_socket.recv_into(buffer, remaining) + read_count += chunk_size + if not chunk_size: + if not read_count: + return SecurityConst.errSSLClosedGraceful + break + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + data_length_pointer[0] = read_count + if error == errno.ECONNRESET or error == errno.EPIPE: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = read_count + + if read_count != requested_length: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +def _write_callback(connection_id, data_buffer, data_length_pointer): + """ + SecureTransport write callback. This is called by ST to request that data + actually be sent on the network. + """ + wrapped_socket = None + try: + wrapped_socket = _connection_refs.get(connection_id) + if wrapped_socket is None: + return SecurityConst.errSSLInternal + base_socket = wrapped_socket.socket + + bytes_to_write = data_length_pointer[0] + data = ctypes.string_at(data_buffer, bytes_to_write) + + timeout = wrapped_socket.gettimeout() + error = None + sent = 0 + + try: + while sent < bytes_to_write: + if timeout is None or timeout >= 0: + if not util.wait_for_write(base_socket, timeout): + raise socket.error(errno.EAGAIN, 'timed out') + chunk_sent = base_socket.send(data) + sent += chunk_sent + + # This has some needless copying here, but I'm not sure there's + # much value in optimising this data path. + data = data[chunk_sent:] + except (socket.error) as e: + error = e.errno + + if error is not None and error != errno.EAGAIN: + data_length_pointer[0] = sent + if error == errno.ECONNRESET or error == errno.EPIPE: + return SecurityConst.errSSLClosedAbort + raise + + data_length_pointer[0] = sent + + if sent != bytes_to_write: + return SecurityConst.errSSLWouldBlock + + return 0 + except Exception as e: + if wrapped_socket is not None: + wrapped_socket._exception = e + return SecurityConst.errSSLInternal + + +# We need to keep these two objects references alive: if they get GC'd while +# in use then SecureTransport could attempt to call a function that is in freed +# memory. That would be...uh...bad. Yeah, that's the word. Bad. +_read_callback_pointer = Security.SSLReadFunc(_read_callback) +_write_callback_pointer = Security.SSLWriteFunc(_write_callback) + + +class WrappedSocket(object): + """ + API-compatibility wrapper for Python's OpenSSL wrapped socket object. + + Note: _makefile_refs, _drop(), and _reuse() are needed for the garbage + collector of PyPy. + """ + def __init__(self, socket): + self.socket = socket + self.context = None + self._makefile_refs = 0 + self._closed = False + self._exception = None + self._keychain = None + self._keychain_dir = None + self._client_cert_chain = None + + # We save off the previously-configured timeout and then set it to + # zero. This is done because we use select and friends to handle the + # timeouts, but if we leave the timeout set on the lower socket then + # Python will "kindly" call select on that socket again for us. Avoid + # that by forcing the timeout to zero. + self._timeout = self.socket.gettimeout() + self.socket.settimeout(0) + + @contextlib.contextmanager + def _raise_on_error(self): + """ + A context manager that can be used to wrap calls that do I/O from + SecureTransport. If any of the I/O callbacks hit an exception, this + context manager will correctly propagate the exception after the fact. + This avoids silently swallowing those exceptions. + + It also correctly forces the socket closed. + """ + self._exception = None + + # We explicitly don't catch around this yield because in the unlikely + # event that an exception was hit in the block we don't want to swallow + # it. + yield + if self._exception is not None: + exception, self._exception = self._exception, None + self.close() + raise exception + + def _set_ciphers(self): + """ + Sets up the allowed ciphers. By default this matches the set in + util.ssl_.DEFAULT_CIPHERS, at least as supported by macOS. This is done + custom and doesn't allow changing at this time, mostly because parsing + OpenSSL cipher strings is going to be a freaking nightmare. + """ + ciphers = (Security.SSLCipherSuite * len(CIPHER_SUITES))(*CIPHER_SUITES) + result = Security.SSLSetEnabledCiphers( + self.context, ciphers, len(CIPHER_SUITES) + ) + _assert_no_error(result) + + def _custom_validate(self, verify, trust_bundle): + """ + Called when we have set custom validation. We do this in two cases: + first, when cert validation is entirely disabled; and second, when + using a custom trust DB. + """ + # If we disabled cert validation, just say: cool. + if not verify: + return + + # We want data in memory, so load it up. + if os.path.isfile(trust_bundle): + with open(trust_bundle, 'rb') as f: + trust_bundle = f.read() + + cert_array = None + trust = Security.SecTrustRef() + + try: + # Get a CFArray that contains the certs we want. + cert_array = _cert_array_from_pem(trust_bundle) + + # Ok, now the hard part. We want to get the SecTrustRef that ST has + # created for this connection, shove our CAs into it, tell ST to + # ignore everything else it knows, and then ask if it can build a + # chain. This is a buuuunch of code. + result = Security.SSLCopyPeerTrust( + self.context, ctypes.byref(trust) + ) + _assert_no_error(result) + if not trust: + raise ssl.SSLError("Failed to copy trust reference") + + result = Security.SecTrustSetAnchorCertificates(trust, cert_array) + _assert_no_error(result) + + result = Security.SecTrustSetAnchorCertificatesOnly(trust, True) + _assert_no_error(result) + + trust_result = Security.SecTrustResultType() + result = Security.SecTrustEvaluate( + trust, ctypes.byref(trust_result) + ) + _assert_no_error(result) + finally: + if trust: + CoreFoundation.CFRelease(trust) + + if cert_array is not None: + CoreFoundation.CFRelease(cert_array) + + # Ok, now we can look at what the result was. + successes = ( + SecurityConst.kSecTrustResultUnspecified, + SecurityConst.kSecTrustResultProceed + ) + if trust_result.value not in successes: + raise ssl.SSLError( + "certificate verify failed, error code: %d" % + trust_result.value + ) + + def handshake(self, + server_hostname, + verify, + trust_bundle, + min_version, + max_version, + client_cert, + client_key, + client_key_passphrase): + """ + Actually performs the TLS handshake. This is run automatically by + wrapped socket, and shouldn't be needed in user code. + """ + # First, we do the initial bits of connection setup. We need to create + # a context, set its I/O funcs, and set the connection reference. + self.context = Security.SSLCreateContext( + None, SecurityConst.kSSLClientSide, SecurityConst.kSSLStreamType + ) + result = Security.SSLSetIOFuncs( + self.context, _read_callback_pointer, _write_callback_pointer + ) + _assert_no_error(result) + + # Here we need to compute the handle to use. We do this by taking the + # id of self modulo 2**31 - 1. If this is already in the dictionary, we + # just keep incrementing by one until we find a free space. + with _connection_ref_lock: + handle = id(self) % 2147483647 + while handle in _connection_refs: + handle = (handle + 1) % 2147483647 + _connection_refs[handle] = self + + result = Security.SSLSetConnection(self.context, handle) + _assert_no_error(result) + + # If we have a server hostname, we should set that too. + if server_hostname: + if not isinstance(server_hostname, bytes): + server_hostname = server_hostname.encode('utf-8') + + result = Security.SSLSetPeerDomainName( + self.context, server_hostname, len(server_hostname) + ) + _assert_no_error(result) + + # Setup the ciphers. + self._set_ciphers() + + # Set the minimum and maximum TLS versions. + result = Security.SSLSetProtocolVersionMin(self.context, min_version) + _assert_no_error(result) + result = Security.SSLSetProtocolVersionMax(self.context, max_version) + _assert_no_error(result) + + # If there's a trust DB, we need to use it. We do that by telling + # SecureTransport to break on server auth. We also do that if we don't + # want to validate the certs at all: we just won't actually do any + # authing in that case. + if not verify or trust_bundle is not None: + result = Security.SSLSetSessionOption( + self.context, + SecurityConst.kSSLSessionOptionBreakOnServerAuth, + True + ) + _assert_no_error(result) + + # If there's a client cert, we need to use it. + if client_cert: + self._keychain, self._keychain_dir = _temporary_keychain() + self._client_cert_chain = _load_client_cert_chain( + self._keychain, client_cert, client_key + ) + result = Security.SSLSetCertificate( + self.context, self._client_cert_chain + ) + _assert_no_error(result) + + while True: + with self._raise_on_error(): + result = Security.SSLHandshake(self.context) + + if result == SecurityConst.errSSLWouldBlock: + raise socket.timeout("handshake timed out") + elif result == SecurityConst.errSSLServerAuthCompleted: + self._custom_validate(verify, trust_bundle) + continue + else: + _assert_no_error(result) + break + + def fileno(self): + return self.socket.fileno() + + # Copy-pasted from Python 3.5 source code + def _decref_socketios(self): + if self._makefile_refs > 0: + self._makefile_refs -= 1 + if self._closed: + self.close() + + def recv(self, bufsiz): + buffer = ctypes.create_string_buffer(bufsiz) + bytes_read = self.recv_into(buffer, bufsiz) + data = buffer[:bytes_read] + return data + + def recv_into(self, buffer, nbytes=None): + # Read short on EOF. + if self._closed: + return 0 + + if nbytes is None: + nbytes = len(buffer) + + buffer = (ctypes.c_char * nbytes).from_buffer(buffer) + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLRead( + self.context, buffer, nbytes, ctypes.byref(processed_bytes) + ) + + # There are some result codes that we want to treat as "not always + # errors". Specifically, those are errSSLWouldBlock, + # errSSLClosedGraceful, and errSSLClosedNoNotify. + if (result == SecurityConst.errSSLWouldBlock): + # If we didn't process any bytes, then this was just a time out. + # However, we can get errSSLWouldBlock in situations when we *did* + # read some data, and in those cases we should just read "short" + # and return. + if processed_bytes.value == 0: + # Timed out, no data read. + raise socket.timeout("recv timed out") + elif result in (SecurityConst.errSSLClosedGraceful, SecurityConst.errSSLClosedNoNotify): + # The remote peer has closed this connection. We should do so as + # well. Note that we don't actually return here because in + # principle this could actually be fired along with return data. + # It's unlikely though. + self.close() + else: + _assert_no_error(result) + + # Ok, we read and probably succeeded. We should return whatever data + # was actually read. + return processed_bytes.value + + def settimeout(self, timeout): + self._timeout = timeout + + def gettimeout(self): + return self._timeout + + def send(self, data): + processed_bytes = ctypes.c_size_t(0) + + with self._raise_on_error(): + result = Security.SSLWrite( + self.context, data, len(data), ctypes.byref(processed_bytes) + ) + + if result == SecurityConst.errSSLWouldBlock and processed_bytes.value == 0: + # Timed out + raise socket.timeout("send timed out") + else: + _assert_no_error(result) + + # We sent, and probably succeeded. Tell them how much we sent. + return processed_bytes.value + + def sendall(self, data): + total_sent = 0 + while total_sent < len(data): + sent = self.send(data[total_sent:total_sent + SSL_WRITE_BLOCKSIZE]) + total_sent += sent + + def shutdown(self): + with self._raise_on_error(): + Security.SSLClose(self.context) + + def close(self): + # TODO: should I do clean shutdown here? Do I have to? + if self._makefile_refs < 1: + self._closed = True + if self.context: + CoreFoundation.CFRelease(self.context) + self.context = None + if self._client_cert_chain: + CoreFoundation.CFRelease(self._client_cert_chain) + self._client_cert_chain = None + if self._keychain: + Security.SecKeychainDelete(self._keychain) + CoreFoundation.CFRelease(self._keychain) + shutil.rmtree(self._keychain_dir) + self._keychain = self._keychain_dir = None + return self.socket.close() + else: + self._makefile_refs -= 1 + + def getpeercert(self, binary_form=False): + # Urgh, annoying. + # + # Here's how we do this: + # + # 1. Call SSLCopyPeerTrust to get hold of the trust object for this + # connection. + # 2. Call SecTrustGetCertificateAtIndex for index 0 to get the leaf. + # 3. To get the CN, call SecCertificateCopyCommonName and process that + # string so that it's of the appropriate type. + # 4. To get the SAN, we need to do something a bit more complex: + # a. Call SecCertificateCopyValues to get the data, requesting + # kSecOIDSubjectAltName. + # b. Mess about with this dictionary to try to get the SANs out. + # + # This is gross. Really gross. It's going to be a few hundred LoC extra + # just to repeat something that SecureTransport can *already do*. So my + # operating assumption at this time is that what we want to do is + # instead to just flag to urllib3 that it shouldn't do its own hostname + # validation when using SecureTransport. + if not binary_form: + raise ValueError( + "SecureTransport only supports dumping binary certs" + ) + trust = Security.SecTrustRef() + certdata = None + der_bytes = None + + try: + # Grab the trust store. + result = Security.SSLCopyPeerTrust( + self.context, ctypes.byref(trust) + ) + _assert_no_error(result) + if not trust: + # Probably we haven't done the handshake yet. No biggie. + return None + + cert_count = Security.SecTrustGetCertificateCount(trust) + if not cert_count: + # Also a case that might happen if we haven't handshaked. + # Handshook? Handshaken? + return None + + leaf = Security.SecTrustGetCertificateAtIndex(trust, 0) + assert leaf + + # Ok, now we want the DER bytes. + certdata = Security.SecCertificateCopyData(leaf) + assert certdata + + data_length = CoreFoundation.CFDataGetLength(certdata) + data_buffer = CoreFoundation.CFDataGetBytePtr(certdata) + der_bytes = ctypes.string_at(data_buffer, data_length) + finally: + if certdata: + CoreFoundation.CFRelease(certdata) + if trust: + CoreFoundation.CFRelease(trust) + + return der_bytes + + def _reuse(self): + self._makefile_refs += 1 + + def _drop(self): + if self._makefile_refs < 1: + self.close() + else: + self._makefile_refs -= 1 + + +if _fileobject: # Platform-specific: Python 2 + def makefile(self, mode, bufsize=-1): + self._makefile_refs += 1 + return _fileobject(self, mode, bufsize, close=True) +else: # Platform-specific: Python 3 + def makefile(self, mode="r", buffering=None, *args, **kwargs): + # We disable buffering with SecureTransport because it conflicts with + # the buffering that ST does internally (see issue #1153 for more). + buffering = 0 + return backport_makefile(self, mode, buffering, *args, **kwargs) + +WrappedSocket.makefile = makefile + + +class SecureTransportContext(object): + """ + I am a wrapper class for the SecureTransport library, to translate the + interface of the standard library ``SSLContext`` object to calls into + SecureTransport. + """ + def __init__(self, protocol): + self._min_version, self._max_version = _protocol_to_min_max[protocol] + self._options = 0 + self._verify = False + self._trust_bundle = None + self._client_cert = None + self._client_key = None + self._client_key_passphrase = None + + @property + def check_hostname(self): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + return True + + @check_hostname.setter + def check_hostname(self, value): + """ + SecureTransport cannot have its hostname checking disabled. For more, + see the comment on getpeercert() in this file. + """ + pass + + @property + def options(self): + # TODO: Well, crap. + # + # So this is the bit of the code that is the most likely to cause us + # trouble. Essentially we need to enumerate all of the SSL options that + # users might want to use and try to see if we can sensibly translate + # them, or whether we should just ignore them. + return self._options + + @options.setter + def options(self, value): + # TODO: Update in line with above. + self._options = value + + @property + def verify_mode(self): + return ssl.CERT_REQUIRED if self._verify else ssl.CERT_NONE + + @verify_mode.setter + def verify_mode(self, value): + self._verify = True if value == ssl.CERT_REQUIRED else False + + def set_default_verify_paths(self): + # So, this has to do something a bit weird. Specifically, what it does + # is nothing. + # + # This means that, if we had previously had load_verify_locations + # called, this does not undo that. We need to do that because it turns + # out that the rest of the urllib3 code will attempt to load the + # default verify paths if it hasn't been told about any paths, even if + # the context itself was sometime earlier. We resolve that by just + # ignoring it. + pass + + def load_default_certs(self): + return self.set_default_verify_paths() + + def set_ciphers(self, ciphers): + # For now, we just require the default cipher string. + if ciphers != util.ssl_.DEFAULT_CIPHERS: + raise ValueError( + "SecureTransport doesn't support custom cipher strings" + ) + + def load_verify_locations(self, cafile=None, capath=None, cadata=None): + # OK, we only really support cadata and cafile. + if capath is not None: + raise ValueError( + "SecureTransport does not support cert directories" + ) + + self._trust_bundle = cafile or cadata + + def load_cert_chain(self, certfile, keyfile=None, password=None): + self._client_cert = certfile + self._client_key = keyfile + self._client_cert_passphrase = password + + def wrap_socket(self, sock, server_side=False, + do_handshake_on_connect=True, suppress_ragged_eofs=True, + server_hostname=None): + # So, what do we do here? Firstly, we assert some properties. This is a + # stripped down shim, so there is some functionality we don't support. + # See PEP 543 for the real deal. + assert not server_side + assert do_handshake_on_connect + assert suppress_ragged_eofs + + # Ok, we're good to go. Now we want to create the wrapped socket object + # and store it in the appropriate place. + wrapped_socket = WrappedSocket(sock) + + # Now we can handshake + wrapped_socket.handshake( + server_hostname, self._verify, self._trust_bundle, + self._min_version, self._max_version, self._client_cert, + self._client_key, self._client_key_passphrase + ) + return wrapped_socket diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py new file mode 100644 index 0000000..811e312 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/contrib/socks.py @@ -0,0 +1,192 @@ +# -*- coding: utf-8 -*- +""" +This module contains provisional support for SOCKS proxies from within +urllib3. This module supports SOCKS4 (specifically the SOCKS4A variant) and +SOCKS5. To enable its functionality, either install PySocks or install this +module with the ``socks`` extra. + +The SOCKS implementation supports the full range of urllib3 features. It also +supports the following SOCKS features: + +- SOCKS4 +- SOCKS4a +- SOCKS5 +- Usernames and passwords for the SOCKS proxy + +Known Limitations: + +- Currently PySocks does not support contacting remote websites via literal + IPv6 addresses. Any such connection attempt will fail. You must use a domain + name. +- Currently PySocks does not support IPv6 connections to the SOCKS proxy. Any + such connection attempt will fail. +""" +from __future__ import absolute_import + +try: + import socks +except ImportError: + import warnings + from ..exceptions import DependencyWarning + + warnings.warn(( + 'SOCKS support in urllib3 requires the installation of optional ' + 'dependencies: specifically, PySocks. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/contrib.html#socks-proxies' + ), + DependencyWarning + ) + raise + +from socket import error as SocketError, timeout as SocketTimeout + +from ..connection import ( + HTTPConnection, HTTPSConnection +) +from ..connectionpool import ( + HTTPConnectionPool, HTTPSConnectionPool +) +from ..exceptions import ConnectTimeoutError, NewConnectionError +from ..poolmanager import PoolManager +from ..util.url import parse_url + +try: + import ssl +except ImportError: + ssl = None + + +class SOCKSConnection(HTTPConnection): + """ + A plain-text HTTP connection that connects via a SOCKS proxy. + """ + def __init__(self, *args, **kwargs): + self._socks_options = kwargs.pop('_socks_options') + super(SOCKSConnection, self).__init__(*args, **kwargs) + + def _new_conn(self): + """ + Establish a new connection via the SOCKS proxy. + """ + extra_kw = {} + if self.source_address: + extra_kw['source_address'] = self.source_address + + if self.socket_options: + extra_kw['socket_options'] = self.socket_options + + try: + conn = socks.create_connection( + (self.host, self.port), + proxy_type=self._socks_options['socks_version'], + proxy_addr=self._socks_options['proxy_host'], + proxy_port=self._socks_options['proxy_port'], + proxy_username=self._socks_options['username'], + proxy_password=self._socks_options['password'], + proxy_rdns=self._socks_options['rdns'], + timeout=self.timeout, + **extra_kw + ) + + except SocketTimeout as e: + raise ConnectTimeoutError( + self, "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout)) + + except socks.ProxyError as e: + # This is fragile as hell, but it seems to be the only way to raise + # useful errors here. + if e.socket_err: + error = e.socket_err + if isinstance(error, SocketTimeout): + raise ConnectTimeoutError( + self, + "Connection to %s timed out. (connect timeout=%s)" % + (self.host, self.timeout) + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % error + ) + else: + raise NewConnectionError( + self, + "Failed to establish a new connection: %s" % e + ) + + except SocketError as e: # Defensive: PySocks should catch all these. + raise NewConnectionError( + self, "Failed to establish a new connection: %s" % e) + + return conn + + +# We don't need to duplicate the Verified/Unverified distinction from +# urllib3/connection.py here because the HTTPSConnection will already have been +# correctly set to either the Verified or Unverified form by that module. This +# means the SOCKSHTTPSConnection will automatically be the correct type. +class SOCKSHTTPSConnection(SOCKSConnection, HTTPSConnection): + pass + + +class SOCKSHTTPConnectionPool(HTTPConnectionPool): + ConnectionCls = SOCKSConnection + + +class SOCKSHTTPSConnectionPool(HTTPSConnectionPool): + ConnectionCls = SOCKSHTTPSConnection + + +class SOCKSProxyManager(PoolManager): + """ + A version of the urllib3 ProxyManager that routes connections via the + defined SOCKS proxy. + """ + pool_classes_by_scheme = { + 'http': SOCKSHTTPConnectionPool, + 'https': SOCKSHTTPSConnectionPool, + } + + def __init__(self, proxy_url, username=None, password=None, + num_pools=10, headers=None, **connection_pool_kw): + parsed = parse_url(proxy_url) + + if username is None and password is None and parsed.auth is not None: + split = parsed.auth.split(':') + if len(split) == 2: + username, password = split + if parsed.scheme == 'socks5': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = False + elif parsed.scheme == 'socks5h': + socks_version = socks.PROXY_TYPE_SOCKS5 + rdns = True + elif parsed.scheme == 'socks4': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = False + elif parsed.scheme == 'socks4a': + socks_version = socks.PROXY_TYPE_SOCKS4 + rdns = True + else: + raise ValueError( + "Unable to determine SOCKS version from %s" % proxy_url + ) + + self.proxy_url = proxy_url + + socks_options = { + 'socks_version': socks_version, + 'proxy_host': parsed.host, + 'proxy_port': parsed.port, + 'username': username, + 'password': password, + 'rdns': rdns + } + connection_pool_kw['_socks_options'] = socks_options + + super(SOCKSProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw + ) + + self.pool_classes_by_scheme = SOCKSProxyManager.pool_classes_by_scheme diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py new file mode 100644 index 0000000..7bbaa98 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/exceptions.py @@ -0,0 +1,246 @@ +from __future__ import absolute_import +from .packages.six.moves.http_client import ( + IncompleteRead as httplib_IncompleteRead +) +# Base Exceptions + + +class HTTPError(Exception): + "Base exception used by this module." + pass + + +class HTTPWarning(Warning): + "Base warning used by this module." + pass + + +class PoolError(HTTPError): + "Base exception for errors caused within a pool." + def __init__(self, pool, message): + self.pool = pool + HTTPError.__init__(self, "%s: %s" % (pool, message)) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, None) + + +class RequestError(PoolError): + "Base exception for PoolErrors that have associated URLs." + def __init__(self, pool, url, message): + self.url = url + PoolError.__init__(self, pool, message) + + def __reduce__(self): + # For pickling purposes. + return self.__class__, (None, self.url, None) + + +class SSLError(HTTPError): + "Raised when SSL certificate fails in an HTTPS connection." + pass + + +class ProxyError(HTTPError): + "Raised when the connection to a proxy fails." + pass + + +class DecodeError(HTTPError): + "Raised when automatic decoding based on Content-Type fails." + pass + + +class ProtocolError(HTTPError): + "Raised when something unexpected happens mid-request/response." + pass + + +#: Renamed to ProtocolError but aliased for backwards compatibility. +ConnectionError = ProtocolError + + +# Leaf Exceptions + +class MaxRetryError(RequestError): + """Raised when the maximum number of retries is exceeded. + + :param pool: The connection pool + :type pool: :class:`~urllib3.connectionpool.HTTPConnectionPool` + :param string url: The requested Url + :param exceptions.Exception reason: The underlying error + + """ + + def __init__(self, pool, url, reason=None): + self.reason = reason + + message = "Max retries exceeded with url: %s (Caused by %r)" % ( + url, reason) + + RequestError.__init__(self, pool, url, message) + + +class HostChangedError(RequestError): + "Raised when an existing pool gets a request for a foreign host." + + def __init__(self, pool, url, retries=3): + message = "Tried to open a foreign host with url: %s" % url + RequestError.__init__(self, pool, url, message) + self.retries = retries + + +class TimeoutStateError(HTTPError): + """ Raised when passing an invalid state to a timeout """ + pass + + +class TimeoutError(HTTPError): + """ Raised when a socket timeout error occurs. + + Catching this error will catch both :exc:`ReadTimeoutErrors + <ReadTimeoutError>` and :exc:`ConnectTimeoutErrors <ConnectTimeoutError>`. + """ + pass + + +class ReadTimeoutError(TimeoutError, RequestError): + "Raised when a socket timeout occurs while receiving data from a server" + pass + + +# This timeout error does not have a URL attached and needs to inherit from the +# base HTTPError +class ConnectTimeoutError(TimeoutError): + "Raised when a socket timeout occurs while connecting to a server" + pass + + +class NewConnectionError(ConnectTimeoutError, PoolError): + "Raised when we fail to establish a new connection. Usually ECONNREFUSED." + pass + + +class EmptyPoolError(PoolError): + "Raised when a pool runs out of connections and no more are allowed." + pass + + +class ClosedPoolError(PoolError): + "Raised when a request enters a pool after the pool has been closed." + pass + + +class LocationValueError(ValueError, HTTPError): + "Raised when there is something wrong with a given URL input." + pass + + +class LocationParseError(LocationValueError): + "Raised when get_host or similar fails to parse the URL input." + + def __init__(self, location): + message = "Failed to parse: %s" % location + HTTPError.__init__(self, message) + + self.location = location + + +class ResponseError(HTTPError): + "Used as a container for an error reason supplied in a MaxRetryError." + GENERIC_ERROR = 'too many error responses' + SPECIFIC_ERROR = 'too many {status_code} error responses' + + +class SecurityWarning(HTTPWarning): + "Warned when performing security reducing actions" + pass + + +class SubjectAltNameWarning(SecurityWarning): + "Warned when connecting to a host with a certificate missing a SAN." + pass + + +class InsecureRequestWarning(SecurityWarning): + "Warned when making an unverified HTTPS request." + pass + + +class SystemTimeWarning(SecurityWarning): + "Warned when system time is suspected to be wrong" + pass + + +class InsecurePlatformWarning(SecurityWarning): + "Warned when certain SSL configuration is not available on a platform." + pass + + +class SNIMissingWarning(HTTPWarning): + "Warned when making a HTTPS request without SNI available." + pass + + +class DependencyWarning(HTTPWarning): + """ + Warned when an attempt is made to import a module with missing optional + dependencies. + """ + pass + + +class ResponseNotChunked(ProtocolError, ValueError): + "Response needs to be chunked in order to read it as chunks." + pass + + +class BodyNotHttplibCompatible(HTTPError): + """ + Body should be httplib.HTTPResponse like (have an fp attribute which + returns raw chunks) for read_chunked(). + """ + pass + + +class IncompleteRead(HTTPError, httplib_IncompleteRead): + """ + Response length doesn't match expected Content-Length + + Subclass of http_client.IncompleteRead to allow int value + for `partial` to avoid creating large objects on streamed + reads. + """ + def __init__(self, partial, expected): + super(IncompleteRead, self).__init__(partial, expected) + + def __repr__(self): + return ('IncompleteRead(%i bytes read, ' + '%i more expected)' % (self.partial, self.expected)) + + +class InvalidHeader(HTTPError): + "The header provided was somehow invalid." + pass + + +class ProxySchemeUnknown(AssertionError, ValueError): + "ProxyManager does not support the supplied scheme" + # TODO(t-8ch): Stop inheriting from AssertionError in v2.0. + + def __init__(self, scheme): + message = "Not supported proxy scheme %s" % scheme + super(ProxySchemeUnknown, self).__init__(message) + + +class HeaderParsingError(HTTPError): + "Raised by assert_header_parsing, but we convert it to a log.warning statement." + def __init__(self, defects, unparsed_data): + message = '%s, unparsed data: %r' % (defects or 'Unknown', unparsed_data) + super(HeaderParsingError, self).__init__(message) + + +class UnrewindableBodyError(HTTPError): + "urllib3 encountered an error when trying to rewind a body" + pass diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py new file mode 100644 index 0000000..37fe64a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/fields.py @@ -0,0 +1,178 @@ +from __future__ import absolute_import +import email.utils +import mimetypes + +from .packages import six + + +def guess_content_type(filename, default='application/octet-stream'): + """ + Guess the "Content-Type" of a file. + + :param filename: + The filename to guess the "Content-Type" of using :mod:`mimetypes`. + :param default: + If no "Content-Type" can be guessed, default to `default`. + """ + if filename: + return mimetypes.guess_type(filename)[0] or default + return default + + +def format_header_param(name, value): + """ + Helper function to format and quote a single header parameter. + + Particularly useful for header parameters which might contain + non-ASCII values, like file names. This follows RFC 2231, as + suggested by RFC 2388 Section 4.4. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + if not any(ch in value for ch in '"\\\r\n'): + result = '%s="%s"' % (name, value) + try: + result.encode('ascii') + except (UnicodeEncodeError, UnicodeDecodeError): + pass + else: + return result + if not six.PY3 and isinstance(value, six.text_type): # Python 2: + value = value.encode('utf-8') + value = email.utils.encode_rfc2231(value, 'utf-8') + value = '%s*=%s' % (name, value) + return value + + +class RequestField(object): + """ + A data container for request body parameters. + + :param name: + The name of this request field. + :param data: + The data/value body. + :param filename: + An optional filename of the request field. + :param headers: + An optional dict-like object of headers to initially use for the field. + """ + def __init__(self, name, data, filename=None, headers=None): + self._name = name + self._filename = filename + self.data = data + self.headers = {} + if headers: + self.headers = dict(headers) + + @classmethod + def from_tuples(cls, fieldname, value): + """ + A :class:`~urllib3.fields.RequestField` factory from old-style tuple parameters. + + Supports constructing :class:`~urllib3.fields.RequestField` from + parameter of key/value strings AND key/filetuple. A filetuple is a + (filename, data, MIME type) tuple where the MIME type is optional. + For example:: + + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + + Field names and filenames must be unicode. + """ + if isinstance(value, tuple): + if len(value) == 3: + filename, data, content_type = value + else: + filename, data = value + content_type = guess_content_type(filename) + else: + filename = None + content_type = None + data = value + + request_param = cls(fieldname, data, filename=filename) + request_param.make_multipart(content_type=content_type) + + return request_param + + def _render_part(self, name, value): + """ + Overridable helper function to format a single header parameter. + + :param name: + The name of the parameter, a string expected to be ASCII only. + :param value: + The value of the parameter, provided as a unicode string. + """ + return format_header_param(name, value) + + def _render_parts(self, header_parts): + """ + Helper function to format and quote a single header. + + Useful for single headers that are composed of multiple items. E.g., + 'Content-Disposition' fields. + + :param header_parts: + A sequence of (k, v) tuples or a :class:`dict` of (k, v) to format + as `k1="v1"; k2="v2"; ...`. + """ + parts = [] + iterable = header_parts + if isinstance(header_parts, dict): + iterable = header_parts.items() + + for name, value in iterable: + if value is not None: + parts.append(self._render_part(name, value)) + + return '; '.join(parts) + + def render_headers(self): + """ + Renders the headers for this request field. + """ + lines = [] + + sort_keys = ['Content-Disposition', 'Content-Type', 'Content-Location'] + for sort_key in sort_keys: + if self.headers.get(sort_key, False): + lines.append('%s: %s' % (sort_key, self.headers[sort_key])) + + for header_name, header_value in self.headers.items(): + if header_name not in sort_keys: + if header_value: + lines.append('%s: %s' % (header_name, header_value)) + + lines.append('\r\n') + return '\r\n'.join(lines) + + def make_multipart(self, content_disposition=None, content_type=None, + content_location=None): + """ + Makes this request field into a multipart request field. + + This method overrides "Content-Disposition", "Content-Type" and + "Content-Location" headers to the request parameter. + + :param content_type: + The 'Content-Type' of the request body. + :param content_location: + The 'Content-Location' of the request body. + + """ + self.headers['Content-Disposition'] = content_disposition or 'form-data' + self.headers['Content-Disposition'] += '; '.join([ + '', self._render_parts( + (('name', self._name), ('filename', self._filename)) + ) + ]) + self.headers['Content-Type'] = content_type + self.headers['Content-Location'] = content_location diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py new file mode 100644 index 0000000..78f1e19 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/filepost.py @@ -0,0 +1,98 @@ +from __future__ import absolute_import +import binascii +import codecs +import os + +from io import BytesIO + +from .packages import six +from .packages.six import b +from .fields import RequestField + +writer = codecs.lookup('utf-8')[3] + + +def choose_boundary(): + """ + Our embarrassingly-simple replacement for mimetools.choose_boundary. + """ + boundary = binascii.hexlify(os.urandom(16)) + if six.PY3: + boundary = boundary.decode('ascii') + return boundary + + +def iter_field_objects(fields): + """ + Iterate over fields. + + Supports list of (k, v) tuples and dicts, and lists of + :class:`~urllib3.fields.RequestField`. + + """ + if isinstance(fields, dict): + i = six.iteritems(fields) + else: + i = iter(fields) + + for field in i: + if isinstance(field, RequestField): + yield field + else: + yield RequestField.from_tuples(*field) + + +def iter_fields(fields): + """ + .. deprecated:: 1.6 + + Iterate over fields. + + The addition of :class:`~urllib3.fields.RequestField` makes this function + obsolete. Instead, use :func:`iter_field_objects`, which returns + :class:`~urllib3.fields.RequestField` objects. + + Supports list of (k, v) tuples and dicts. + """ + if isinstance(fields, dict): + return ((k, v) for k, v in six.iteritems(fields)) + + return ((k, v) for k, v in fields) + + +def encode_multipart_formdata(fields, boundary=None): + """ + Encode a dictionary of ``fields`` using the multipart/form-data MIME format. + + :param fields: + Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). + + :param boundary: + If not specified, then a random boundary will be generated using + :func:`urllib3.filepost.choose_boundary`. + """ + body = BytesIO() + if boundary is None: + boundary = choose_boundary() + + for field in iter_field_objects(fields): + body.write(b('--%s\r\n' % (boundary))) + + writer(body).write(field.render_headers()) + data = field.data + + if isinstance(data, int): + data = str(data) # Backwards compatibility + + if isinstance(data, six.text_type): + writer(body).write(data) + else: + body.write(data) + + body.write(b'\r\n') + + body.write(b('--%s--\r\n' % (boundary))) + + content_type = str('multipart/form-data; boundary=%s' % boundary) + + return body.getvalue(), content_type diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py new file mode 100644 index 0000000..170e974 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__init__.py @@ -0,0 +1,5 @@ +from __future__ import absolute_import + +from . import ssl_match_hostname + +__all__ = ('ssl_match_hostname', ) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4fad728712c2de061f02fc068c5a8582807e29d GIT binary patch literal 270 zcmXv|yG{c!5VU<4C5jRu@dZ?ot_Uumj3PuqNkex+S~+Kv82rLsgZLV1e(74O`~nqr z5G&2j?CeUjx69?6l<GfMkGAl49sY|IaZ`{kN|QuVLoDqnC6dX;Fx&J^(M{jV_JMSh zW4R(79nZurd6Q9rw!ud{(m($^B?DIAaDanP=!8}G-DI2tJY~#L0mPa(lGs+70tjOO zzDS&v`P6>yINHF24r}cami>Bo-@9jgy{_g7@TQ#fk>_ZP-d*t^h8M9{i34b-5#Ta> TjI)jPG8?t6zonYDU<>vOC4Wc> literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/ordered_dict.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..852d6d070cf600c6d1f39da401f83fefce2d2076 GIT binary patch literal 8364 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fa7a7a71ffce9605700a808c012e30d976543760 GIT binary patch literal 24358 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 E1+9wfD*ylh literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..258b7d05a9e3342e08d03663a21cf2b9cf2b0c83 GIT binary patch literal 167 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd<h9ZzKg7_7nUy@s(Uyxa# zo0(T!l9-dDn_QlrmsL_|0ult{__EZzl>8$7(xRN4%p_y|g2d$P#Prl+{UjixAit=j hSU)~KGcU6wK3=b&@)n0pZhlH>PO2TqreYvw002e1DxClT literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/__pycache__/makefile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c34676cf5fd72631e8480690167ee41e52e66aec GIT binary patch literal 1265 zcmZuwUymC#5V!Y#Hk+u0s;{^eoQTvW4+Rw=glOO*orJEZrsbpvvA2o6cbjZ>7u)G_ zCx-`)XFdT4`p6p(@GbfY{J;wm(tU-#z<6_sD#2JD&-^@|@yyu6PA5b_lb`p#{KG}) zFQaS;bo2>Ku?LKz38I)<Ii6rx?c7@06B{GyQ<r+*<B3D9G3o^uKZVm|wx~)jMSqzr zSeoT5{PsT-hQqBHk!Oq?oy)VbAP>mNi700aCU=KVPRNqMCM9Xf$x1L%XY!0B1)Ru= zQ#hT-uucjoh%CvBvqUnIkh>`aze_gGNI9Lene2yGkP15NVI7Q{C<l)<<}=TrKpmJy z{uHLTg%OfS;Y%!=%&C29U*ZK8Z%a%ag;RVRUE=ScCJHaSwMVg8s}GbHp|!7kF;bow zNee9O#v-8Zx}|*nm1<G^5P|IRImnigrLB-^U0Ul<AqUMJ>ODjjiXCN9e-ZE>Xt1_G zZY>c1QMz;QTC@1?DiFWHjY4x56^;=^cnO|gO7|CEg)poa_PSl{0sbdoL4#O;+=Bc4 zZSDtXYm2IYzf$cn0xVQ*Wh+OyFPwFxu!`cgilE2siw{Erv~3_M)Bo*S%FE@hul@J? z%^_|>Z8feno?h%_#q%W3C|Q=2k#{(Gw=D8=!tas#9+{FP&&!(8o<>*D3Uqk&4-hxv z#hq0#U8O1Gj1nQC<x4@9D<R30k!e;W{Ja-wTQI4^FOq!4_Bk)P?miNNaha7xqjL*f zO}g>+mByT<LR(p>-~4QU^yt~=PvhaU(P;lkJU*E0>+bM6;*;Z}Bm-|doh6jLrXTZ6 zg5G(`zL5uyk9ks6pgJbWUPn8E<tcx|RH3!W0UogqSTQT9kvwMZDzsm)I?oEG{Tlq4 z9Ut=Cm~2u6AgPU4ZG)h_jW_K`i2EzzZ$XGxM+3R6231zw&k7--qW5R@X)%{yzh}T^ z#?M(nOFmffJkO>N1{M6v<dliQ?jH}f73x>#`sNni)vXJG#1I&AZ(|EbR)D)W!U1+* z7#`pdkd5SBuLivVdtI=O8p|8l!~70->AB4#IRxst+K*#e&f=Iyu%*4te{NdW7&mFY Y#)z>BK7z8Wa`tfmnlKE)S&@zKzqlB07XSbN literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py new file mode 100644 index 0000000..75b80dc --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/backports/makefile.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +""" +backports.makefile +~~~~~~~~~~~~~~~~~~ + +Backports the Python 3 ``socket.makefile`` method for use with anything that +wants to create a "fake" socket object. +""" +import io + +from socket import SocketIO + + +def backport_makefile(self, mode="r", buffering=None, encoding=None, + errors=None, newline=None): + """ + Backport of ``socket.makefile`` from Python 3.5. + """ + if not set(mode) <= set(["r", "w", "b"]): + raise ValueError( + "invalid mode %r (only r, w, b allowed)" % (mode,) + ) + writing = "w" in mode + reading = "r" in mode or not writing + assert reading or writing + binary = "b" in mode + rawmode = "" + if reading: + rawmode += "r" + if writing: + rawmode += "w" + raw = SocketIO(self, rawmode) + self._makefile_refs += 1 + if buffering is None: + buffering = -1 + if buffering < 0: + buffering = io.DEFAULT_BUFFER_SIZE + if buffering == 0: + if not binary: + raise ValueError("unbuffered streams must be binary") + return raw + if reading and writing: + buffer = io.BufferedRWPair(raw, raw, buffering) + elif reading: + buffer = io.BufferedReader(raw, buffering) + else: + assert writing + buffer = io.BufferedWriter(raw, buffering) + if binary: + return buffer + text = io.TextIOWrapper(buffer, encoding, errors, newline) + text.mode = mode + return text diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py new file mode 100644 index 0000000..4479363 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ordered_dict.py @@ -0,0 +1,259 @@ +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. +# Copyright 2009 Raymond Hettinger, released under the MIT License. +# http://code.activestate.com/recipes/576693/ +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + +try: + from _abcoll import KeysView, ValuesView, ItemsView +except ImportError: + pass + + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + if from_value is None: + raise value + raise value from from_value +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py new file mode 100644 index 0000000..d6594eb --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__init__.py @@ -0,0 +1,19 @@ +import sys + +try: + # Our match_hostname function is the same as 3.5's, so we only want to + # import the match_hostname function if it's at least that good. + if sys.version_info < (3, 5): + raise ImportError("Fallback to vendored code") + + from ssl import CertificateError, match_hostname +except ImportError: + try: + # Backport of the function from a pypi module + from backports.ssl_match_hostname import CertificateError, match_hostname + except ImportError: + # Our vendored copy + from ._implementation import CertificateError, match_hostname + +# Not needed, but documenting what we provide. +__all__ = ('CertificateError', 'match_hostname') diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f061e45aa8d0c5ca6ed62ad33950f22eed1a60db GIT binary patch literal 511 zcmZWkyG{c!5M28%5W=%agOnl#LP`NwK#33nfkZ<?0i2Mm<7~jhkHdC?f~Y{^H>m0O zo@=S{3skHL2qD(m@ngobySwxAEx^cMR?pukz<a#>#4H|mF#R(E2Tl~^Fj^IGLpbe& z>j=t|C-O*;OI4!NJk^c7LEr?;Q3`_gTke5CT%-1vX6lb-<y$kHXm|r%rhgS@VCX4K zkf(W*lVj*jjj<Ov>d|q6`?!H{zkE<Aby1Z4Zm`{<Fx)!9yQSr#N9(0M;ex!BWf8=_ zbJo=hx(MYpyS6@<LW?m$kKRn3_>r&YhQfJi4U^{5*0YDYvMx-%CEhESqSnQtc_$W( ztY1fh{q@WjnbegMT9{A-^sA>C!zLMf1veKxB7B@>L04HNt2JqSKz^;fyD~T7b~8SH zC7aBX4V+T)Vk4`tYH=le_P=Pxuxl9@TdziSb4y!3P+~hy=i3NPN|P38(l%KjG$QRJ EpCzV><NyEw literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/__pycache__/_implementation.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a083eea3defffdc9697d5b98e32faf5f2f0984da GIT binary patch literal 3270 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 SnTLff*Z1cA*3~cw+y4VQr*uRB literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py new file mode 100644 index 0000000..92c9bc7 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/packages/ssl_match_hostname/_implementation.py @@ -0,0 +1,157 @@ +"""The match_hostname() function from Python 3.3.3, essential when using SSL.""" + +# Note: This file is under the PSF license as the code comes from the python +# stdlib. http://docs.python.org/3/license.html + +import re +import sys + +# ipaddress has been backported to 2.6+ in pypi. If it is installed on the +# system, use it to handle IPAddress ServerAltnames (this was added in +# python-3.5) otherwise only do DNS matching. This allows +# backports.ssl_match_hostname to continue to be used all the way back to +# python-2.4. +try: + from pip._vendor import ipaddress +except ImportError: + ipaddress = None + +__version__ = '3.5.0.1' + + +class CertificateError(ValueError): + pass + + +def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + # Ported from python3-syntax: + # leftmost, *remainder = dn.split(r'.') + parts = dn.split(r'.') + leftmost = parts[0] + remainder = parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + +def _to_unicode(obj): + if isinstance(obj, str) and sys.version_info < (3,): + obj = unicode(obj, encoding='ascii', errors='strict') + return obj + +def _ipaddress_match(ipname, host_ip): + """Exact matching of IP addresses. + + RFC 6125 explicitly doesn't define an algorithm for this + (section 1.7.2 - "Out of Scope"). + """ + # OpenSSL may add a trailing newline to a subjectAltName's IP address + # Divergence from upstream: ipaddress can't handle byte str + ip = ipaddress.ip_address(_to_unicode(ipname).rstrip()) + return ip == host_ip + + +def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate, match_hostname needs a " + "SSL socket or SSL context with either " + "CERT_OPTIONAL or CERT_REQUIRED") + try: + # Divergence from upstream: ipaddress can't handle byte str + host_ip = ipaddress.ip_address(_to_unicode(hostname)) + except ValueError: + # Not an IP address (common case) + host_ip = None + except UnicodeError: + # Divergence from upstream: Have to deal with ipaddress not taking + # byte strings. addresses should be all ascii, so we consider it not + # an ipaddress in this case + host_ip = None + except AttributeError: + # Divergence from upstream: Make ipaddress library optional + if ipaddress is None: + host_ip = None + else: + raise + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if host_ip is None and _dnsname_match(value, hostname): + return + dnsnames.append(value) + elif key == 'IP Address': + if host_ip is not None and _ipaddress_match(value, host_ip): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py new file mode 100644 index 0000000..506a3c9 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/poolmanager.py @@ -0,0 +1,449 @@ +from __future__ import absolute_import +import collections +import functools +import logging + +from ._collections import RecentlyUsedContainer +from .connectionpool import HTTPConnectionPool, HTTPSConnectionPool +from .connectionpool import port_by_scheme +from .exceptions import LocationValueError, MaxRetryError, ProxySchemeUnknown +from .packages.six.moves.urllib.parse import urljoin +from .request import RequestMethods +from .util.url import parse_url +from .util.retry import Retry + + +__all__ = ['PoolManager', 'ProxyManager', 'proxy_from_url'] + + +log = logging.getLogger(__name__) + +SSL_KEYWORDS = ('key_file', 'cert_file', 'cert_reqs', 'ca_certs', + 'ssl_version', 'ca_cert_dir', 'ssl_context') + +# All known keyword arguments that could be provided to the pool manager, its +# pools, or the underlying connections. This is used to construct a pool key. +_key_fields = ( + 'key_scheme', # str + 'key_host', # str + 'key_port', # int + 'key_timeout', # int or float or Timeout + 'key_retries', # int or Retry + 'key_strict', # bool + 'key_block', # bool + 'key_source_address', # str + 'key_key_file', # str + 'key_cert_file', # str + 'key_cert_reqs', # str + 'key_ca_certs', # str + 'key_ssl_version', # str + 'key_ca_cert_dir', # str + 'key_ssl_context', # instance of ssl.SSLContext or urllib3.util.ssl_.SSLContext + 'key_maxsize', # int + 'key_headers', # dict + 'key__proxy', # parsed proxy url + 'key__proxy_headers', # dict + 'key_socket_options', # list of (level (int), optname (int), value (int or str)) tuples + 'key__socks_options', # dict + 'key_assert_hostname', # bool or string + 'key_assert_fingerprint', # str +) + +#: The namedtuple class used to construct keys for the connection pool. +#: All custom key schemes should include the fields in this key at a minimum. +PoolKey = collections.namedtuple('PoolKey', _key_fields) + + +def _default_key_normalizer(key_class, request_context): + """ + Create a pool key out of a request context dictionary. + + According to RFC 3986, both the scheme and host are case-insensitive. + Therefore, this function normalizes both before constructing the pool + key for an HTTPS request. If you wish to change this behaviour, provide + alternate callables to ``key_fn_by_scheme``. + + :param key_class: + The class to use when constructing the key. This should be a namedtuple + with the ``scheme`` and ``host`` keys at a minimum. + :type key_class: namedtuple + :param request_context: + A dictionary-like object that contain the context for a request. + :type request_context: dict + + :return: A namedtuple that can be used as a connection pool key. + :rtype: PoolKey + """ + # Since we mutate the dictionary, make a copy first + context = request_context.copy() + context['scheme'] = context['scheme'].lower() + context['host'] = context['host'].lower() + + # These are both dictionaries and need to be transformed into frozensets + for key in ('headers', '_proxy_headers', '_socks_options'): + if key in context and context[key] is not None: + context[key] = frozenset(context[key].items()) + + # The socket_options key may be a list and needs to be transformed into a + # tuple. + socket_opts = context.get('socket_options') + if socket_opts is not None: + context['socket_options'] = tuple(socket_opts) + + # Map the kwargs to the names in the namedtuple - this is necessary since + # namedtuples can't have fields starting with '_'. + for key in list(context.keys()): + context['key_' + key] = context.pop(key) + + # Default to ``None`` for keys missing from the context + for field in key_class._fields: + if field not in context: + context[field] = None + + return key_class(**context) + + +#: A dictionary that maps a scheme to a callable that creates a pool key. +#: This can be used to alter the way pool keys are constructed, if desired. +#: Each PoolManager makes a copy of this dictionary so they can be configured +#: globally here, or individually on the instance. +key_fn_by_scheme = { + 'http': functools.partial(_default_key_normalizer, PoolKey), + 'https': functools.partial(_default_key_normalizer, PoolKey), +} + +pool_classes_by_scheme = { + 'http': HTTPConnectionPool, + 'https': HTTPSConnectionPool, +} + + +class PoolManager(RequestMethods): + """ + Allows for arbitrary requests while transparently keeping track of + necessary connection pools for you. + + :param num_pools: + Number of connection pools to cache before discarding the least + recently used pool. + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + + :param \\**connection_pool_kw: + Additional parameters are used to create fresh + :class:`urllib3.connectionpool.ConnectionPool` instances. + + Example:: + + >>> manager = PoolManager(num_pools=2) + >>> r = manager.request('GET', 'http://google.com/') + >>> r = manager.request('GET', 'http://google.com/mail') + >>> r = manager.request('GET', 'http://yahoo.com/') + >>> len(manager.pools) + 2 + + """ + + proxy = None + + def __init__(self, num_pools=10, headers=None, **connection_pool_kw): + RequestMethods.__init__(self, headers) + self.connection_pool_kw = connection_pool_kw + self.pools = RecentlyUsedContainer(num_pools, + dispose_func=lambda p: p.close()) + + # Locally set the pool classes and keys so other PoolManagers can + # override them. + self.pool_classes_by_scheme = pool_classes_by_scheme + self.key_fn_by_scheme = key_fn_by_scheme.copy() + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.clear() + # Return False to re-raise any potential exceptions + return False + + def _new_pool(self, scheme, host, port, request_context=None): + """ + Create a new :class:`ConnectionPool` based on host, port, scheme, and + any additional pool keyword arguments. + + If ``request_context`` is provided, it is provided as keyword arguments + to the pool class used. This method is used to actually create the + connection pools handed out by :meth:`connection_from_url` and + companion methods. It is intended to be overridden for customization. + """ + pool_cls = self.pool_classes_by_scheme[scheme] + if request_context is None: + request_context = self.connection_pool_kw.copy() + + # Although the context has everything necessary to create the pool, + # this function has historically only used the scheme, host, and port + # in the positional args. When an API change is acceptable these can + # be removed. + for key in ('scheme', 'host', 'port'): + request_context.pop(key, None) + + if scheme == 'http': + for kw in SSL_KEYWORDS: + request_context.pop(kw, None) + + return pool_cls(host, port, **request_context) + + def clear(self): + """ + Empty our store of pools and direct them all to close. + + This will not affect in-flight connections, but they will not be + re-used after completion. + """ + self.pools.clear() + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + """ + Get a :class:`ConnectionPool` based on the host, port, and scheme. + + If ``port`` isn't given, it will be derived from the ``scheme`` using + ``urllib3.connectionpool.port_by_scheme``. If ``pool_kwargs`` is + provided, it is merged with the instance's ``connection_pool_kw`` + variable and used to create the new connection pool, if one is + needed. + """ + + if not host: + raise LocationValueError("No host specified.") + + request_context = self._merge_pool_kwargs(pool_kwargs) + request_context['scheme'] = scheme or 'http' + if not port: + port = port_by_scheme.get(request_context['scheme'].lower(), 80) + request_context['port'] = port + request_context['host'] = host + + return self.connection_from_context(request_context) + + def connection_from_context(self, request_context): + """ + Get a :class:`ConnectionPool` based on the request context. + + ``request_context`` must at least contain the ``scheme`` key and its + value must be a key in ``key_fn_by_scheme`` instance variable. + """ + scheme = request_context['scheme'].lower() + pool_key_constructor = self.key_fn_by_scheme[scheme] + pool_key = pool_key_constructor(request_context) + + return self.connection_from_pool_key(pool_key, request_context=request_context) + + def connection_from_pool_key(self, pool_key, request_context=None): + """ + Get a :class:`ConnectionPool` based on the provided pool key. + + ``pool_key`` should be a namedtuple that only contains immutable + objects. At a minimum it must have the ``scheme``, ``host``, and + ``port`` fields. + """ + with self.pools.lock: + # If the scheme, host, or port doesn't match existing open + # connections, open a new ConnectionPool. + pool = self.pools.get(pool_key) + if pool: + return pool + + # Make a fresh ConnectionPool of the desired type + scheme = request_context['scheme'] + host = request_context['host'] + port = request_context['port'] + pool = self._new_pool(scheme, host, port, request_context=request_context) + self.pools[pool_key] = pool + + return pool + + def connection_from_url(self, url, pool_kwargs=None): + """ + Similar to :func:`urllib3.connectionpool.connection_from_url`. + + If ``pool_kwargs`` is not provided and a new pool needs to be + constructed, ``self.connection_pool_kw`` is used to initialize + the :class:`urllib3.connectionpool.ConnectionPool`. If ``pool_kwargs`` + is provided, it is used instead. Note that if a new pool does not + need to be created for the request, the provided ``pool_kwargs`` are + not used. + """ + u = parse_url(url) + return self.connection_from_host(u.host, port=u.port, scheme=u.scheme, + pool_kwargs=pool_kwargs) + + def _merge_pool_kwargs(self, override): + """ + Merge a dictionary of override values for self.connection_pool_kw. + + This does not modify self.connection_pool_kw and returns a new dict. + Any keys in the override dictionary with a value of ``None`` are + removed from the merged dictionary. + """ + base_pool_kwargs = self.connection_pool_kw.copy() + if override: + for key, value in override.items(): + if value is None: + try: + del base_pool_kwargs[key] + except KeyError: + pass + else: + base_pool_kwargs[key] = value + return base_pool_kwargs + + def urlopen(self, method, url, redirect=True, **kw): + """ + Same as :meth:`urllib3.connectionpool.HTTPConnectionPool.urlopen` + with custom cross-host redirect logic and only sends the request-uri + portion of the ``url``. + + The given ``url`` parameter must be absolute, such that an appropriate + :class:`urllib3.connectionpool.ConnectionPool` can be chosen for it. + """ + u = parse_url(url) + conn = self.connection_from_host(u.host, port=u.port, scheme=u.scheme) + + kw['assert_same_host'] = False + kw['redirect'] = False + + if 'headers' not in kw: + kw['headers'] = self.headers.copy() + + if self.proxy is not None and u.scheme == "http": + response = conn.urlopen(method, url, **kw) + else: + response = conn.urlopen(method, u.request_uri, **kw) + + redirect_location = redirect and response.get_redirect_location() + if not redirect_location: + return response + + # Support relative URLs for redirecting. + redirect_location = urljoin(url, redirect_location) + + # RFC 7231, Section 6.4.4 + if response.status == 303: + method = 'GET' + + retries = kw.get('retries') + if not isinstance(retries, Retry): + retries = Retry.from_int(retries, redirect=redirect) + + # Strip headers marked as unsafe to forward to the redirected location. + # Check remove_headers_on_redirect to avoid a potential network call within + # conn.is_same_host() which may use socket.gethostbyname() in the future. + if (retries.remove_headers_on_redirect + and not conn.is_same_host(redirect_location)): + for header in retries.remove_headers_on_redirect: + kw['headers'].pop(header, None) + + try: + retries = retries.increment(method, url, response=response, _pool=conn) + except MaxRetryError: + if retries.raise_on_redirect: + raise + return response + + kw['retries'] = retries + kw['redirect'] = redirect + + log.info("Redirecting %s -> %s", url, redirect_location) + return self.urlopen(method, redirect_location, **kw) + + +class ProxyManager(PoolManager): + """ + Behaves just like :class:`PoolManager`, but sends all requests through + the defined proxy, using the CONNECT method for HTTPS URLs. + + :param proxy_url: + The URL of the proxy to be used. + + :param proxy_headers: + A dictionary containing headers that will be sent to the proxy. In case + of HTTP they are being sent with each request, while in the + HTTPS/CONNECT case they are sent only once. Could be used for proxy + authentication. + + Example: + >>> proxy = urllib3.ProxyManager('http://localhost:3128/') + >>> r1 = proxy.request('GET', 'http://google.com/') + >>> r2 = proxy.request('GET', 'http://httpbin.org/') + >>> len(proxy.pools) + 1 + >>> r3 = proxy.request('GET', 'https://httpbin.org/') + >>> r4 = proxy.request('GET', 'https://twitter.com/') + >>> len(proxy.pools) + 3 + + """ + + def __init__(self, proxy_url, num_pools=10, headers=None, + proxy_headers=None, **connection_pool_kw): + + if isinstance(proxy_url, HTTPConnectionPool): + proxy_url = '%s://%s:%i' % (proxy_url.scheme, proxy_url.host, + proxy_url.port) + proxy = parse_url(proxy_url) + if not proxy.port: + port = port_by_scheme.get(proxy.scheme, 80) + proxy = proxy._replace(port=port) + + if proxy.scheme not in ("http", "https"): + raise ProxySchemeUnknown(proxy.scheme) + + self.proxy = proxy + self.proxy_headers = proxy_headers or {} + + connection_pool_kw['_proxy'] = self.proxy + connection_pool_kw['_proxy_headers'] = self.proxy_headers + + super(ProxyManager, self).__init__( + num_pools, headers, **connection_pool_kw) + + def connection_from_host(self, host, port=None, scheme='http', pool_kwargs=None): + if scheme == "https": + return super(ProxyManager, self).connection_from_host( + host, port, scheme, pool_kwargs=pool_kwargs) + + return super(ProxyManager, self).connection_from_host( + self.proxy.host, self.proxy.port, self.proxy.scheme, pool_kwargs=pool_kwargs) + + def _set_proxy_headers(self, url, headers=None): + """ + Sets headers needed by proxies: specifically, the Accept and Host + headers. Only sets headers not provided by the user. + """ + headers_ = {'Accept': '*/*'} + + netloc = parse_url(url).netloc + if netloc: + headers_['Host'] = netloc + + if headers: + headers_.update(headers) + return headers_ + + def urlopen(self, method, url, redirect=True, **kw): + "Same as HTTP(S)ConnectionPool.urlopen, ``url`` must be absolute." + u = parse_url(url) + + if u.scheme == "http": + # For proxied HTTPS requests, httplib sets the necessary headers + # on the CONNECT to the proxy. For HTTP, we'll definitely + # need to set 'Host' at the very least. + headers = kw.get('headers', self.headers) + kw['headers'] = self._set_proxy_headers(url, headers) + + return super(ProxyManager, self).urlopen(method, url, redirect=redirect, **kw) + + +def proxy_from_url(url, **kw): + return ProxyManager(proxy_url=url, **kw) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py new file mode 100644 index 0000000..1be3334 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/request.py @@ -0,0 +1,150 @@ +from __future__ import absolute_import + +from .filepost import encode_multipart_formdata +from .packages.six.moves.urllib.parse import urlencode + + +__all__ = ['RequestMethods'] + + +class RequestMethods(object): + """ + Convenience mixin for classes who implement a :meth:`urlopen` method, such + as :class:`~urllib3.connectionpool.HTTPConnectionPool` and + :class:`~urllib3.poolmanager.PoolManager`. + + Provides behavior for making common types of HTTP request methods and + decides which type of request field encoding to use. + + Specifically, + + :meth:`.request_encode_url` is for sending requests whose fields are + encoded in the URL (such as GET, HEAD, DELETE). + + :meth:`.request_encode_body` is for sending requests whose fields are + encoded in the *body* of the request using multipart or www-form-urlencoded + (such as for POST, PUT, PATCH). + + :meth:`.request` is for making any kind of request, it will look up the + appropriate encoding format and use one of the above two methods to make + the request. + + Initializer parameters: + + :param headers: + Headers to include with all requests, unless other headers are given + explicitly. + """ + + _encode_url_methods = set(['DELETE', 'GET', 'HEAD', 'OPTIONS']) + + def __init__(self, headers=None): + self.headers = headers or {} + + def urlopen(self, method, url, body=None, headers=None, + encode_multipart=True, multipart_boundary=None, + **kw): # Abstract + raise NotImplementedError("Classes extending RequestMethods must implement " + "their own ``urlopen`` method.") + + def request(self, method, url, fields=None, headers=None, **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the appropriate encoding of + ``fields`` based on the ``method`` used. + + This is a convenience method that requires the least amount of manual + effort. It can be used in most situations, while still having the + option to drop down to more specific methods when necessary, such as + :meth:`request_encode_url`, :meth:`request_encode_body`, + or even the lowest level :meth:`urlopen`. + """ + method = method.upper() + + urlopen_kw['request_url'] = url + + if method in self._encode_url_methods: + return self.request_encode_url(method, url, fields=fields, + headers=headers, + **urlopen_kw) + else: + return self.request_encode_body(method, url, fields=fields, + headers=headers, + **urlopen_kw) + + def request_encode_url(self, method, url, fields=None, headers=None, + **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the url. This is useful for request methods like GET, HEAD, DELETE, etc. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': headers} + extra_kw.update(urlopen_kw) + + if fields: + url += '?' + urlencode(fields) + + return self.urlopen(method, url, **extra_kw) + + def request_encode_body(self, method, url, fields=None, headers=None, + encode_multipart=True, multipart_boundary=None, + **urlopen_kw): + """ + Make a request using :meth:`urlopen` with the ``fields`` encoded in + the body. This is useful for request methods like POST, PUT, PATCH, etc. + + When ``encode_multipart=True`` (default), then + :meth:`urllib3.filepost.encode_multipart_formdata` is used to encode + the payload with the appropriate content type. Otherwise + :meth:`urllib.urlencode` is used with the + 'application/x-www-form-urlencoded' content type. + + Multipart encoding must be used when posting files, and it's reasonably + safe to use it in other times too. However, it may break request + signing, such as with OAuth. + + Supports an optional ``fields`` parameter of key/value strings AND + key/filetuple. A filetuple is a (filename, data, MIME type) tuple where + the MIME type is optional. For example:: + + fields = { + 'foo': 'bar', + 'fakefile': ('foofile.txt', 'contents of foofile'), + 'realfile': ('barfile.txt', open('realfile').read()), + 'typedfile': ('bazfile.bin', open('bazfile').read(), + 'image/jpeg'), + 'nonamefile': 'contents of nonamefile field', + } + + When uploading a file, providing a filename (the first parameter of the + tuple) is optional but recommended to best mimic behavior of browsers. + + Note that if ``headers`` are supplied, the 'Content-Type' header will + be overwritten because it depends on the dynamic random boundary string + which is used to compose the body of the request. The random boundary + string can be explicitly set with the ``multipart_boundary`` parameter. + """ + if headers is None: + headers = self.headers + + extra_kw = {'headers': {}} + + if fields: + if 'body' in urlopen_kw: + raise TypeError( + "request got values for both 'fields' and 'body', can only specify one.") + + if encode_multipart: + body, content_type = encode_multipart_formdata(fields, boundary=multipart_boundary) + else: + body, content_type = urlencode(fields), 'application/x-www-form-urlencoded' + + extra_kw['body'] = body + extra_kw['headers'] = {'Content-Type': content_type} + + extra_kw['headers'].update(headers) + extra_kw.update(urlopen_kw) + + return self.urlopen(method, url, **extra_kw) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py new file mode 100644 index 0000000..9873cb9 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/response.py @@ -0,0 +1,676 @@ +from __future__ import absolute_import +from contextlib import contextmanager +import zlib +import io +import logging +from socket import timeout as SocketTimeout +from socket import error as SocketError + +from ._collections import HTTPHeaderDict +from .exceptions import ( + BodyNotHttplibCompatible, ProtocolError, DecodeError, ReadTimeoutError, + ResponseNotChunked, IncompleteRead, InvalidHeader +) +from .packages.six import string_types as basestring, binary_type, PY3 +from .packages.six.moves import http_client as httplib +from .connection import HTTPException, BaseSSLError +from .util.response import is_fp_closed, is_response_to_head + +log = logging.getLogger(__name__) + + +class DeflateDecoder(object): + + def __init__(self): + self._first_try = True + self._data = binary_type() + self._obj = zlib.decompressobj() + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + if not data: + return data + + if not self._first_try: + return self._obj.decompress(data) + + self._data += data + try: + decompressed = self._obj.decompress(data) + if decompressed: + self._first_try = False + self._data = None + return decompressed + except zlib.error: + self._first_try = False + self._obj = zlib.decompressobj(-zlib.MAX_WBITS) + try: + return self.decompress(self._data) + finally: + self._data = None + + +class GzipDecoderState(object): + + FIRST_MEMBER = 0 + OTHER_MEMBERS = 1 + SWALLOW_DATA = 2 + + +class GzipDecoder(object): + + def __init__(self): + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + self._state = GzipDecoderState.FIRST_MEMBER + + def __getattr__(self, name): + return getattr(self._obj, name) + + def decompress(self, data): + ret = binary_type() + if self._state == GzipDecoderState.SWALLOW_DATA or not data: + return ret + while True: + try: + ret += self._obj.decompress(data) + except zlib.error: + previous_state = self._state + # Ignore data after the first error + self._state = GzipDecoderState.SWALLOW_DATA + if previous_state == GzipDecoderState.OTHER_MEMBERS: + # Allow trailing garbage acceptable in other gzip clients + return ret + raise + data = self._obj.unused_data + if not data: + return ret + self._state = GzipDecoderState.OTHER_MEMBERS + self._obj = zlib.decompressobj(16 + zlib.MAX_WBITS) + + +def _get_decoder(mode): + if mode == 'gzip': + return GzipDecoder() + + return DeflateDecoder() + + +class HTTPResponse(io.IOBase): + """ + HTTP Response container. + + Backwards-compatible to httplib's HTTPResponse but the response ``body`` is + loaded and decoded on-demand when the ``data`` property is accessed. This + class is also compatible with the Python standard library's :mod:`io` + module, and can hence be treated as a readable object in the context of that + framework. + + Extra parameters for behaviour not present in httplib.HTTPResponse: + + :param preload_content: + If True, the response's body will be preloaded during construction. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param original_response: + When this HTTPResponse wrapper is generated from an httplib.HTTPResponse + object, it's convenient to include the original for debug purposes. It's + otherwise unused. + + :param retries: + The retries contains the last :class:`~urllib3.util.retry.Retry` that + was used during the request. + + :param enforce_content_length: + Enforce content length checking. Body returned by server must match + value of Content-Length header, if present. Otherwise, raise error. + """ + + CONTENT_DECODERS = ['gzip', 'deflate'] + REDIRECT_STATUSES = [301, 302, 303, 307, 308] + + def __init__(self, body='', headers=None, status=0, version=0, reason=None, + strict=0, preload_content=True, decode_content=True, + original_response=None, pool=None, connection=None, msg=None, + retries=None, enforce_content_length=False, + request_method=None, request_url=None): + + if isinstance(headers, HTTPHeaderDict): + self.headers = headers + else: + self.headers = HTTPHeaderDict(headers) + self.status = status + self.version = version + self.reason = reason + self.strict = strict + self.decode_content = decode_content + self.retries = retries + self.enforce_content_length = enforce_content_length + + self._decoder = None + self._body = None + self._fp = None + self._original_response = original_response + self._fp_bytes_read = 0 + self.msg = msg + self._request_url = request_url + + if body and isinstance(body, (basestring, binary_type)): + self._body = body + + self._pool = pool + self._connection = connection + + if hasattr(body, 'read'): + self._fp = body + + # Are we using the chunked-style of transfer encoding? + self.chunked = False + self.chunk_left = None + tr_enc = self.headers.get('transfer-encoding', '').lower() + # Don't incur the penalty of creating a list and then discarding it + encodings = (enc.strip() for enc in tr_enc.split(",")) + if "chunked" in encodings: + self.chunked = True + + # Determine length of response + self.length_remaining = self._init_length(request_method) + + # If requested, preload the body. + if preload_content and not self._body: + self._body = self.read(decode_content=decode_content) + + def get_redirect_location(self): + """ + Should we redirect and where to? + + :returns: Truthy redirect location string if we got a redirect status + code and valid location. ``None`` if redirect status and no + location. ``False`` if not a redirect status code. + """ + if self.status in self.REDIRECT_STATUSES: + return self.headers.get('location') + + return False + + def release_conn(self): + if not self._pool or not self._connection: + return + + self._pool._put_conn(self._connection) + self._connection = None + + @property + def data(self): + # For backwords-compat with earlier urllib3 0.4 and earlier. + if self._body: + return self._body + + if self._fp: + return self.read(cache_content=True) + + @property + def connection(self): + return self._connection + + def isclosed(self): + return is_fp_closed(self._fp) + + def tell(self): + """ + Obtain the number of bytes pulled over the wire so far. May differ from + the amount of content returned by :meth:``HTTPResponse.read`` if bytes + are encoded on the wire (e.g, compressed). + """ + return self._fp_bytes_read + + def _init_length(self, request_method): + """ + Set initial length value for Response content if available. + """ + length = self.headers.get('content-length') + + if length is not None: + if self.chunked: + # This Response will fail with an IncompleteRead if it can't be + # received as chunked. This method falls back to attempt reading + # the response before raising an exception. + log.warning("Received response with both Content-Length and " + "Transfer-Encoding set. This is expressly forbidden " + "by RFC 7230 sec 3.3.2. Ignoring Content-Length and " + "attempting to process response as Transfer-Encoding: " + "chunked.") + return None + + try: + # RFC 7230 section 3.3.2 specifies multiple content lengths can + # be sent in a single Content-Length header + # (e.g. Content-Length: 42, 42). This line ensures the values + # are all valid ints and that as long as the `set` length is 1, + # all values are the same. Otherwise, the header is invalid. + lengths = set([int(val) for val in length.split(',')]) + if len(lengths) > 1: + raise InvalidHeader("Content-Length contained multiple " + "unmatching values (%s)" % length) + length = lengths.pop() + except ValueError: + length = None + else: + if length < 0: + length = None + + # Convert status to int for comparison + # In some cases, httplib returns a status of "_UNKNOWN" + try: + status = int(self.status) + except ValueError: + status = 0 + + # Check for responses that shouldn't include a body + if status in (204, 304) or 100 <= status < 200 or request_method == 'HEAD': + length = 0 + + return length + + def _init_decoder(self): + """ + Set-up the _decoder attribute if necessary. + """ + # Note: content-encoding value should be case-insensitive, per RFC 7230 + # Section 3.2 + content_encoding = self.headers.get('content-encoding', '').lower() + if self._decoder is None and content_encoding in self.CONTENT_DECODERS: + self._decoder = _get_decoder(content_encoding) + + def _decode(self, data, decode_content, flush_decoder): + """ + Decode the data passed in and potentially flush the decoder. + """ + try: + if decode_content and self._decoder: + data = self._decoder.decompress(data) + except (IOError, zlib.error) as e: + content_encoding = self.headers.get('content-encoding', '').lower() + raise DecodeError( + "Received response with content-encoding: %s, but " + "failed to decode it." % content_encoding, e) + + if flush_decoder and decode_content: + data += self._flush_decoder() + + return data + + def _flush_decoder(self): + """ + Flushes the decoder. Should only be called if the decoder is actually + being used. + """ + if self._decoder: + buf = self._decoder.decompress(b'') + return buf + self._decoder.flush() + + return b'' + + @contextmanager + def _error_catcher(self): + """ + Catch low-level python exceptions, instead re-raising urllib3 + variants, so that low-level exceptions are not leaked in the + high-level api. + + On exit, release the connection back to the pool. + """ + clean_exit = False + + try: + try: + yield + + except SocketTimeout: + # FIXME: Ideally we'd like to include the url in the ReadTimeoutError but + # there is yet no clean way to get at it from this context. + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except BaseSSLError as e: + # FIXME: Is there a better way to differentiate between SSLErrors? + if 'read operation timed out' not in str(e): # Defensive: + # This shouldn't happen but just in case we're missing an edge + # case, let's avoid swallowing SSL errors. + raise + + raise ReadTimeoutError(self._pool, None, 'Read timed out.') + + except (HTTPException, SocketError) as e: + # This includes IncompleteRead. + raise ProtocolError('Connection broken: %r' % e, e) + + # If no exception is thrown, we should avoid cleaning up + # unnecessarily. + clean_exit = True + finally: + # If we didn't terminate cleanly, we need to throw away our + # connection. + if not clean_exit: + # The response may not be closed but we're not going to use it + # anymore so close it now to ensure that the connection is + # released back to the pool. + if self._original_response: + self._original_response.close() + + # Closing the response may not actually be sufficient to close + # everything, so if we have a hold of the connection close that + # too. + if self._connection: + self._connection.close() + + # If we hold the original response but it's closed now, we should + # return the connection back to the pool. + if self._original_response and self._original_response.isclosed(): + self.release_conn() + + def read(self, amt=None, decode_content=None, cache_content=False): + """ + Similar to :meth:`httplib.HTTPResponse.read`, but with two additional + parameters: ``decode_content`` and ``cache_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + + :param cache_content: + If True, will save the returned data such that the same result is + returned despite of the state of the underlying file object. This + is useful if you want the ``.data`` property to continue working + after having ``.read()`` the file object. (Overridden if ``amt`` is + set.) + """ + self._init_decoder() + if decode_content is None: + decode_content = self.decode_content + + if self._fp is None: + return + + flush_decoder = False + data = None + + with self._error_catcher(): + if amt is None: + # cStringIO doesn't like amt=None + data = self._fp.read() + flush_decoder = True + else: + cache_content = False + data = self._fp.read(amt) + if amt != 0 and not data: # Platform-specific: Buggy versions of Python. + # Close the connection when no data is returned + # + # This is redundant to what httplib/http.client _should_ + # already do. However, versions of python released before + # December 15, 2012 (http://bugs.python.org/issue16298) do + # not properly close the connection in all cases. There is + # no harm in redundantly calling close. + self._fp.close() + flush_decoder = True + if self.enforce_content_length and self.length_remaining not in (0, None): + # This is an edge case that httplib failed to cover due + # to concerns of backward compatibility. We're + # addressing it here to make sure IncompleteRead is + # raised during streaming, so all calls with incorrect + # Content-Length are caught. + raise IncompleteRead(self._fp_bytes_read, self.length_remaining) + + if data: + self._fp_bytes_read += len(data) + if self.length_remaining is not None: + self.length_remaining -= len(data) + + data = self._decode(data, decode_content, flush_decoder) + + if cache_content: + self._body = data + + return data + + def stream(self, amt=2**16, decode_content=None): + """ + A generator wrapper for the read() method. A call will block until + ``amt`` bytes have been read from the connection or until the + connection is closed. + + :param amt: + How much of the content to read. The generator will return up to + much data per iteration, but may return less. This is particularly + likely when using compressed data. However, the empty string will + never be returned. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + if self.chunked and self.supports_chunked_reads(): + for line in self.read_chunked(amt, decode_content=decode_content): + yield line + else: + while not is_fp_closed(self._fp): + data = self.read(amt=amt, decode_content=decode_content) + + if data: + yield data + + @classmethod + def from_httplib(ResponseCls, r, **response_kw): + """ + Given an :class:`httplib.HTTPResponse` instance ``r``, return a + corresponding :class:`urllib3.response.HTTPResponse` object. + + Remaining parameters are passed to the HTTPResponse constructor, along + with ``original_response=r``. + """ + headers = r.msg + + if not isinstance(headers, HTTPHeaderDict): + if PY3: # Python 3 + headers = HTTPHeaderDict(headers.items()) + else: # Python 2 + headers = HTTPHeaderDict.from_httplib(headers) + + # HTTPResponse objects in Python 3 don't have a .strict attribute + strict = getattr(r, 'strict', 0) + resp = ResponseCls(body=r, + headers=headers, + status=r.status, + version=r.version, + reason=r.reason, + strict=strict, + original_response=r, + **response_kw) + return resp + + # Backwards-compatibility methods for httplib.HTTPResponse + def getheaders(self): + return self.headers + + def getheader(self, name, default=None): + return self.headers.get(name, default) + + # Backwards compatibility for http.cookiejar + def info(self): + return self.headers + + # Overrides from io.IOBase + def close(self): + if not self.closed: + self._fp.close() + + if self._connection: + self._connection.close() + + @property + def closed(self): + if self._fp is None: + return True + elif hasattr(self._fp, 'isclosed'): + return self._fp.isclosed() + elif hasattr(self._fp, 'closed'): + return self._fp.closed + else: + return True + + def fileno(self): + if self._fp is None: + raise IOError("HTTPResponse has no file to get a fileno from") + elif hasattr(self._fp, "fileno"): + return self._fp.fileno() + else: + raise IOError("The file-like object this HTTPResponse is wrapped " + "around has no file descriptor") + + def flush(self): + if self._fp is not None and hasattr(self._fp, 'flush'): + return self._fp.flush() + + def readable(self): + # This method is required for `io` module compatibility. + return True + + def readinto(self, b): + # This method is required for `io` module compatibility. + temp = self.read(len(b)) + if len(temp) == 0: + return 0 + else: + b[:len(temp)] = temp + return len(temp) + + def supports_chunked_reads(self): + """ + Checks if the underlying file-like object looks like a + httplib.HTTPResponse object. We do this by testing for the fp + attribute. If it is present we assume it returns raw chunks as + processed by read_chunked(). + """ + return hasattr(self._fp, 'fp') + + def _update_chunk_length(self): + # First, we'll figure out length of a chunk and then + # we'll try to read it from socket. + if self.chunk_left is not None: + return + line = self._fp.fp.readline() + line = line.split(b';', 1)[0] + try: + self.chunk_left = int(line, 16) + except ValueError: + # Invalid chunked protocol response, abort. + self.close() + raise httplib.IncompleteRead(line) + + def _handle_chunk(self, amt): + returned_chunk = None + if amt is None: + chunk = self._fp._safe_read(self.chunk_left) + returned_chunk = chunk + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + elif amt < self.chunk_left: + value = self._fp._safe_read(amt) + self.chunk_left = self.chunk_left - amt + returned_chunk = value + elif amt == self.chunk_left: + value = self._fp._safe_read(amt) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + returned_chunk = value + else: # amt > self.chunk_left + returned_chunk = self._fp._safe_read(self.chunk_left) + self._fp._safe_read(2) # Toss the CRLF at the end of the chunk. + self.chunk_left = None + return returned_chunk + + def read_chunked(self, amt=None, decode_content=None): + """ + Similar to :meth:`HTTPResponse.read`, but with an additional + parameter: ``decode_content``. + + :param amt: + How much of the content to read. If specified, caching is skipped + because it doesn't make sense to cache partial content as the full + response. + + :param decode_content: + If True, will attempt to decode the body based on the + 'content-encoding' header. + """ + self._init_decoder() + # FIXME: Rewrite this method and make it a class with a better structured logic. + if not self.chunked: + raise ResponseNotChunked( + "Response is not chunked. " + "Header 'transfer-encoding: chunked' is missing.") + if not self.supports_chunked_reads(): + raise BodyNotHttplibCompatible( + "Body should be httplib.HTTPResponse like. " + "It should have have an fp attribute which returns raw chunks.") + + with self._error_catcher(): + # Don't bother reading the body of a HEAD request. + if self._original_response and is_response_to_head(self._original_response): + self._original_response.close() + return + + # If a response is already read and closed + # then return immediately. + if self._fp.fp is None: + return + + while True: + self._update_chunk_length() + if self.chunk_left == 0: + break + chunk = self._handle_chunk(amt) + decoded = self._decode(chunk, decode_content=decode_content, + flush_decoder=False) + if decoded: + yield decoded + + if decode_content: + # On CPython and PyPy, we should never need to flush the + # decoder. However, on Jython we *might* need to, so + # lets defensively do it anyway. + decoded = self._flush_decoder() + if decoded: # Platform-specific: Jython. + yield decoded + + # Chunk content ends with \r\n: discard it. + while True: + line = self._fp.fp.readline() + if not line: + # Some sites may not end with '\r\n'. + break + if line == b'\r\n': + break + + # We read everything; close the "file". + if self._original_response: + self._original_response.close() + + def geturl(self): + """ + Returns the URL that was the source of this response. + If the request that generated this response redirected, this method + will return the final redirect location. + """ + if self.retries is not None and len(self.retries.history): + return self.retries.history[-1].redirect_location + else: + return self._request_url diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py new file mode 100644 index 0000000..2f2770b --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__init__.py @@ -0,0 +1,54 @@ +from __future__ import absolute_import +# For backwards compatibility, provide imports that used to be here. +from .connection import is_connection_dropped +from .request import make_headers +from .response import is_fp_closed +from .ssl_ import ( + SSLContext, + HAS_SNI, + IS_PYOPENSSL, + IS_SECURETRANSPORT, + assert_fingerprint, + resolve_cert_reqs, + resolve_ssl_version, + ssl_wrap_socket, +) +from .timeout import ( + current_time, + Timeout, +) + +from .retry import Retry +from .url import ( + get_host, + parse_url, + split_first, + Url, +) +from .wait import ( + wait_for_read, + wait_for_write +) + +__all__ = ( + 'HAS_SNI', + 'IS_PYOPENSSL', + 'IS_SECURETRANSPORT', + 'SSLContext', + 'Retry', + 'Timeout', + 'Url', + 'assert_fingerprint', + 'current_time', + 'is_connection_dropped', + 'is_fp_closed', + 'get_host', + 'parse_url', + 'make_headers', + 'resolve_cert_reqs', + 'resolve_ssl_version', + 'split_first', + 'ssl_wrap_socket', + 'wait_for_read', + 'wait_for_write' +) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fe28417883ef24e0259a0a086c8f282da955000c GIT binary patch literal 948 zcmZ9KO;6h}7{`;gY0@-lOJ8^!3~7gHJ+L0O<1`Hr(vYTt8aT|FWQD{)hMff4q2tr+ zvdg}buRHM-cG~j<F{UNTPtS{E|NXc3!_c?jA>Utq8MiF!7bcHS1A-6msULvUN^Ncl zo7lFMHqs_<h$d;)af`QvL!3Hxcw4x{t>ZTLM2B>QPkhlOT@jE#gd`L_(i45s7Xvb= z$GLn(49QT8$f(XeJ{A))spAe`6>DTotdn)IK{muD*{th6e<rrbme?lSkax-RG>EKe zcn?agscri4xhi<28O=mlNPTZV)F+vuNs;F)(OHqxR2F5)QurYd@in7YEKZqJn8Uz} zk|w-R(D#fVMV}6eT(fW5xF7c-8qJSPa1_y#&&MZ+bLg5OWYOWl+2ZhYu{V!Sju)q9 z7%Ro3rWaX$$z&<BT$>fiK-(>&33epAQD*d5Qi{`CPypggACskwOR9?Gn(1l71W6?& z%Qe-RV8%TK7L^9M&Vp%qH*Fd3l4*KXC~Z1rEES`b<ff}io}mZ{_2!x6FjcsWu~bM< z5T~a1H(kn1v*}oR;F#<n@P<eiv4R*NCWtPgkASOV$u?q$7$F=)fCv#|L=UlwSOd(b zJI1H<qSBRQluEpC#(z4WdRpUxMHN%Jp3rz;RaxZVDlTVQXwrkY{{+|Ko|eazjf=j4 zV-KQnBgT>FT)i{X1hf9xK&==zYFg;dlWyZu8gowRPfNalevRMzGcC$lnU%X)t~B&_ zljUXpRo}eDV*SC{=4l~kuny18-^?nV@foFA4o5*>mv_c{CyKP<>^<IBg<b}Yz{dBL MKX3wjy*+6E0qkY`*8l(j literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/connection.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..40c054af5aee3c486433b7f7c559f791ada05eda GIT binary patch literal 3025 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/queue.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed62fcdcb5e49f119a2d6f14e1593a3ff920f466 GIT binary patch literal 997 zcmZuvOK;Oa5Z;IFIB8M}^fw^+&;$WT1Qj50K@o@(E2Ne2ZX$>EBYqU9a%=tv&5^&f zS57^0<;2XUu3TWGnVp@_-tU{)eKDDg2$=Z(;Nve!$WPpK=0S1_UcZ8%h@yrFqL|`_ zW=t@Oxo3Fh36B!ZR(>^gUj<_DnkZidTcQH(t%3_KLPg(`XmAB5k@*#a7*WgX^eZg> zy49^t5bBIWatdBQgrJF_iU_8tVp}4(_7+re<!!0(_cS6<0~G=`P(z>@+2NaXQM_}< zA{QF2=r6(RLkJDIq&u=9k|_c|(Rsw}K~fl_lO`?l+WJa^vI@r#G3(XZEG(5jNQEQ& z{e0GB<*ZE0lQgfJ*qD>#%Q9az>nB)rF3)tXifYzY#-yJf&)Oz6GuQ02{APWb=4o?) za-2qbe&<H@)M3egwIln6ZpeyU;7ma`z1CQT09kHy?j-I564*el>-1b>+a1|akIaF$ z*zf|}q>dm#u1mV1I|_GxJuBuoZ4j3wG#Rlyx0g0L`<vX8W!v2CQ6KiG0ZQQEIm7kl zid>tHcz2tUmqiIJW3T@*Ep>AYK-XlS37~lt+EB_o&a{+vBxP2p)?hxCa^1#ek5pqk zdx8NcR-yLlJ_Z!k3pm@#hk*4O6@@h9V;*u>jfPbKH5-<3@;P4Wy27!Fd);;l?|+&V zX8_<Mv;6IcN7i@GRvgPVZ)>eOiLUBS?eRM~?t;Uo`&ORe3~Q{1bWF!AU?KkldQZ|y literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/request.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cda3ff7e8d5148b65729fd6f2c6cb203d70a3e44 GIT binary patch literal 3178 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 BlY9UG literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/response.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2c0255ff01f3740087308cc58ce2e957bc9a4e92 GIT binary patch literal 1859 zcmZXVO>Z1E7{~3I+1<%xla>@Dgb=kVRJ0P=RB8`sg%D{QDM%0^8c<kOns~>a-N|}h zVtbNom|O@~J_E^-8=q&cobnYo@z}GQmv$uEkKgU*|MN31S5^W9-|(-eZ@*YV=wDM= zd=41jLQ*DUh+%<JJj56=hq=N@-Jxe~PqfnZunl&Lwf{iF4(l)<N}nyU0Lmq{{08;9 z*RTre;ram`sa%wrhe=xGQeT^WpnZ9wbrD7);hBc&+BT<*%Uvo}l8v{d%w>el67ZSQ zhx7`PiXof%6}m)M=ne9a#?wH4ieV5&zoN|9N3(W?4xO96ukQ5)(C0Ed^>6z3@Ahkt zIT!eM%rM-+J<|b!@707yQ$<cDTu-<pl#G*Oo{=~ad|f0{PV&(qk2FaXiA1hA>j!q; zprDebrgvcLX05#me}AIRNo4lu+hIFry`M8W5}ZIg<C@Df$@tCoadBs(UaR&K)$CfY zZfY%)5%}8ruWrxVow%rjU#KXXcJQ_fXZjn-F8K1lmm4}QHj1QJPco&c5bM#&I6Krw zFHECNAzYW`a-)<&B%|jWrB1|#<f_Os#rwsq?j|aXjhg269V62xkRji3eY}d>j^nhO z(hY1WSE2VtUk@rRNLJssU}#i<u7}QrqdwE1)}^Og6}rGz*l43cU&G{ud*0ZdwV~zQ ztsMEfaxM^9Sbbl)a$k2UT)C|Ervs|GplX}$0#Me|n@Vx1?<gw-nOF`Lnb2cSMjUij zWfXCx;!=ni0ZFaEM$4^JEolVvc^2hm210R0xItHuSmr4KTnM<S6q@9*oeFF(c9=u* zV+O09<PreOGqO9=6DXeFCun}A0cjqIGGH8YnZ&b(n1P-Ze6j9;9GIsCLiM-z_I7`O zqth`zSga^%qPQY+Df|31;)PB?$o~5;@D|(eZjV2|Ae8_z+!|mvzBqfrPYZYi;DN>N z^PRsW<6M*9o}KsW4&yP5Q9JeWnCq~hGm%r)bL0aMy<RD^#=9Y-n)duUNFWvfl3B#- z&V1E+`Oc;4r9HU#9QHVuDb=-Sd{K8`eG0EZ8m@XCOmAehJIRO8C_gZnc>ztf0#^MI zwM2x?XgHvaMo*zjeFzzP*u`z!b-Iu|>;c$5mWK2jludARAz73^2Lr+l0!(p*HQ+2i zt{}8bAvjg|(!BzVjSYe3AM3<-0!@R@QOT9%hZ>gblLI(a!zLx$Tbr-fCAXs*DYj|G z1W0VAAC-wED<+#ov6YP>kSsuGf>V@dStD};k*$+KB)}7cdm#NZ-~7NH_1fIB_RQ|a zy<rNmF=ukkw7N;A>sDD5T=tyWU!1yb&j-EZ^hXdp7Gpx4Tjy`VI?BX+wA97{1~)$e zd#4xFK^VrRE+r2`X}mpLD`+$Y!c|`-r~NcP=1Q7~A|F9k2e*J*7Hs6Pn%Nca0ANpL aDe%8eb5;uejrs8?^T#xTcU}Ln|M-7v1OLSU literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/retry.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ccaa2ca3ebed1fb4fab006005a1eb268a19d901 GIT binary patch literal 12611 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 ViC@FY70p7bpcl;YUu*Pd{13+&`xO8H literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/ssl_.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b2f977abd6d1fad5ff1deb8e3858b16cc61ca02f GIT binary patch literal 9949 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 VTFhR{zL_0Y)cmKg8u6E3{%^(dtb70f literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/timeout.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fcf7c239739944349edd78a670a8adb6a9da47aa GIT binary patch literal 8727 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/url.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..96f664af559e3709fc1295aea02c0f934d0f5114 GIT binary patch literal 5137 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/__pycache__/wait.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b83d336cd5b3941ba97aeb106b1cd1e100c708e GIT binary patch literal 3110 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py new file mode 100644 index 0000000..5cf488f --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/connection.py @@ -0,0 +1,126 @@ +from __future__ import absolute_import +import socket +from .wait import NoWayToWaitForSocketError, wait_for_read + + +def is_connection_dropped(conn): # Platform-specific + """ + Returns True if the connection is dropped and should be closed. + + :param conn: + :class:`httplib.HTTPConnection` object. + + Note: For platforms like AppEngine, this will always return ``False`` to + let the platform handle connection recycling transparently for us. + """ + sock = getattr(conn, 'sock', False) + if sock is False: # Platform-specific: AppEngine + return False + if sock is None: # Connection already closed (such as by httplib). + return True + try: + # Returns True if readable, which here means it's been dropped + return wait_for_read(sock, timeout=0.0) + except NoWayToWaitForSocketError: # Platform-specific: AppEngine + return False + + +# This function is copied from socket.py in the Python 2.7 standard +# library test suite. Added to its signature is only `socket_options`. +# One additional modification is that we avoid binding to IPv6 servers +# discovered in DNS if the system doesn't have IPv6 functionality. +def create_connection(address, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, + source_address=None, socket_options=None): + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of '' or port 0 tells the OS to use the default. + """ + + host, port = address + if host.startswith('['): + host = host.strip('[]') + err = None + + # Using the value from allowed_gai_family() in the context of getaddrinfo lets + # us select whether to work with IPv4 DNS records, IPv6 records, or both. + # The original create_connection function always returns all records. + family = allowed_gai_family() + + for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket.socket(af, socktype, proto) + + # If provided, set socket level options before connecting. + _set_socket_options(sock, socket_options) + + if timeout is not socket._GLOBAL_DEFAULT_TIMEOUT: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except socket.error as e: + err = e + if sock is not None: + sock.close() + sock = None + + if err is not None: + raise err + + raise socket.error("getaddrinfo returns an empty list") + + +def _set_socket_options(sock, options): + if options is None: + return + + for opt in options: + sock.setsockopt(*opt) + + +def allowed_gai_family(): + """This function is designed to work in the context of + getaddrinfo, where family=socket.AF_UNSPEC is the default and + will perform a DNS search for both IPv6 and IPv4 records.""" + + family = socket.AF_INET + if HAS_IPV6: + family = socket.AF_UNSPEC + return family + + +def _has_ipv6(host): + """ Returns True if the system can bind an IPv6 address. """ + sock = None + has_ipv6 = False + + if socket.has_ipv6: + # has_ipv6 returns true if cPython was compiled with IPv6 support. + # It does not tell us if the system has IPv6 support enabled. To + # determine that we must bind to an IPv6 address. + # https://github.com/shazow/urllib3/pull/611 + # https://bugs.python.org/issue658327 + try: + sock = socket.socket(socket.AF_INET6) + sock.bind((host, 0)) + has_ipv6 = True + except Exception: + pass + + if sock: + sock.close() + return has_ipv6 + + +HAS_IPV6 = _has_ipv6('::1') diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py new file mode 100644 index 0000000..d3d379a --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/queue.py @@ -0,0 +1,21 @@ +import collections +from ..packages import six +from ..packages.six.moves import queue + +if six.PY2: + # Queue is imported for side effects on MS Windows. See issue #229. + import Queue as _unused_module_Queue # noqa: F401 + + +class LifoQueue(queue.Queue): + def _init(self, _): + self.queue = collections.deque() + + def _qsize(self, len=len): + return len(self.queue) + + def _put(self, item): + self.queue.append(item) + + def _get(self): + return self.queue.pop() diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py new file mode 100644 index 0000000..3ddfcd5 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/request.py @@ -0,0 +1,118 @@ +from __future__ import absolute_import +from base64 import b64encode + +from ..packages.six import b, integer_types +from ..exceptions import UnrewindableBodyError + +ACCEPT_ENCODING = 'gzip,deflate' +_FAILEDTELL = object() + + +def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, + basic_auth=None, proxy_basic_auth=None, disable_cache=None): + """ + Shortcuts for generating request headers. + + :param keep_alive: + If ``True``, adds 'connection: keep-alive' header. + + :param accept_encoding: + Can be a boolean, list, or string. + ``True`` translates to 'gzip,deflate'. + List will get joined by comma. + String will be used as provided. + + :param user_agent: + String representing the user-agent you want, such as + "python-urllib3/0.6" + + :param basic_auth: + Colon-separated username:password string for 'authorization: basic ...' + auth header. + + :param proxy_basic_auth: + Colon-separated username:password string for 'proxy-authorization: basic ...' + auth header. + + :param disable_cache: + If ``True``, adds 'cache-control: no-cache' header. + + Example:: + + >>> make_headers(keep_alive=True, user_agent="Batman/1.0") + {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} + >>> make_headers(accept_encoding=True) + {'accept-encoding': 'gzip,deflate'} + """ + headers = {} + if accept_encoding: + if isinstance(accept_encoding, str): + pass + elif isinstance(accept_encoding, list): + accept_encoding = ','.join(accept_encoding) + else: + accept_encoding = ACCEPT_ENCODING + headers['accept-encoding'] = accept_encoding + + if user_agent: + headers['user-agent'] = user_agent + + if keep_alive: + headers['connection'] = 'keep-alive' + + if basic_auth: + headers['authorization'] = 'Basic ' + \ + b64encode(b(basic_auth)).decode('utf-8') + + if proxy_basic_auth: + headers['proxy-authorization'] = 'Basic ' + \ + b64encode(b(proxy_basic_auth)).decode('utf-8') + + if disable_cache: + headers['cache-control'] = 'no-cache' + + return headers + + +def set_file_position(body, pos): + """ + If a position is provided, move file to that point. + Otherwise, we'll attempt to record a position for future use. + """ + if pos is not None: + rewind_body(body, pos) + elif getattr(body, 'tell', None) is not None: + try: + pos = body.tell() + except (IOError, OSError): + # This differentiates from None, allowing us to catch + # a failed `tell()` later when trying to rewind the body. + pos = _FAILEDTELL + + return pos + + +def rewind_body(body, body_pos): + """ + Attempt to rewind body to a certain position. + Primarily used for request redirects and retries. + + :param body: + File-like object that supports seek. + + :param int pos: + Position to seek to in file. + """ + body_seek = getattr(body, 'seek', None) + if body_seek is not None and isinstance(body_pos, integer_types): + try: + body_seek(body_pos) + except (IOError, OSError): + raise UnrewindableBodyError("An error occurred when rewinding request " + "body for redirect/retry.") + elif body_pos is _FAILEDTELL: + raise UnrewindableBodyError("Unable to record file position for rewinding " + "request body during a redirect/retry.") + else: + raise ValueError("body_pos must be of type integer, " + "instead it was %s." % type(body_pos)) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py new file mode 100644 index 0000000..67cf730 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/response.py @@ -0,0 +1,81 @@ +from __future__ import absolute_import +from ..packages.six.moves import http_client as httplib + +from ..exceptions import HeaderParsingError + + +def is_fp_closed(obj): + """ + Checks whether a given file-like object is closed. + + :param obj: + The file-like object to check. + """ + + try: + # Check `isclosed()` first, in case Python3 doesn't set `closed`. + # GH Issue #928 + return obj.isclosed() + except AttributeError: + pass + + try: + # Check via the official file-like-object way. + return obj.closed + except AttributeError: + pass + + try: + # Check if the object is a container for another file-like object that + # gets released on exhaustion (e.g. HTTPResponse). + return obj.fp is None + except AttributeError: + pass + + raise ValueError("Unable to determine whether fp is closed.") + + +def assert_header_parsing(headers): + """ + Asserts whether all headers have been successfully parsed. + Extracts encountered errors from the result of parsing headers. + + Only works on Python 3. + + :param headers: Headers to verify. + :type headers: `httplib.HTTPMessage`. + + :raises urllib3.exceptions.HeaderParsingError: + If parsing errors are found. + """ + + # This will fail silently if we pass in the wrong kind of parameter. + # To make debugging easier add an explicit check. + if not isinstance(headers, httplib.HTTPMessage): + raise TypeError('expected httplib.Message, got {0}.'.format( + type(headers))) + + defects = getattr(headers, 'defects', None) + get_payload = getattr(headers, 'get_payload', None) + + unparsed_data = None + if get_payload: # Platform-specific: Python 3. + unparsed_data = get_payload() + + if defects or unparsed_data: + raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) + + +def is_response_to_head(response): + """ + Checks whether the request of a response has been a HEAD-request. + Handles the quirks of AppEngine. + + :param conn: + :type conn: :class:`httplib.HTTPResponse` + """ + # FIXME: Can we do this somehow without accessing private httplib _method? + method = response._method + if isinstance(method, int): # Platform-specific: Appengine + return method == 3 + return method.upper() == 'HEAD' diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py new file mode 100644 index 0000000..7ad3dc6 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/retry.py @@ -0,0 +1,411 @@ +from __future__ import absolute_import +import time +import logging +from collections import namedtuple +from itertools import takewhile +import email +import re + +from ..exceptions import ( + ConnectTimeoutError, + MaxRetryError, + ProtocolError, + ReadTimeoutError, + ResponseError, + InvalidHeader, +) +from ..packages import six + + +log = logging.getLogger(__name__) + + +# Data structure for representing the metadata of requests that result in a retry. +RequestHistory = namedtuple('RequestHistory', ["method", "url", "error", + "status", "redirect_location"]) + + +class Retry(object): + """ Retry configuration. + + Each retry attempt will create a new Retry object with updated values, so + they can be safely reused. + + Retries can be defined as a default for a pool:: + + retries = Retry(connect=5, read=2, redirect=5) + http = PoolManager(retries=retries) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', retries=Retry(10)) + + Retries can be disabled by passing ``False``:: + + response = http.request('GET', 'http://example.com/', retries=False) + + Errors will be wrapped in :class:`~urllib3.exceptions.MaxRetryError` unless + retries are disabled, in which case the causing exception will be raised. + + :param int total: + Total number of retries to allow. Takes precedence over other counts. + + Set to ``None`` to remove this constraint and fall back on other + counts. It's a good idea to set this to some sensibly-high value to + account for unexpected edge cases and avoid infinite retry loops. + + Set to ``0`` to fail on the first retry. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int connect: + How many connection-related errors to retry on. + + These are errors raised before the request is sent to the remote server, + which we assume has not triggered the server to process the request. + + Set to ``0`` to fail on the first retry of this type. + + :param int read: + How many times to retry on read errors. + + These errors are raised after the request was sent to the server, so the + request may have side-effects. + + Set to ``0`` to fail on the first retry of this type. + + :param int redirect: + How many redirects to perform. Limit this to avoid infinite redirect + loops. + + A redirect is a HTTP response with a status code 301, 302, 303, 307 or + 308. + + Set to ``0`` to fail on the first retry of this type. + + Set to ``False`` to disable and imply ``raise_on_redirect=False``. + + :param int status: + How many times to retry on bad status codes. + + These are retries made on responses, where status code matches + ``status_forcelist``. + + Set to ``0`` to fail on the first retry of this type. + + :param iterable method_whitelist: + Set of uppercased HTTP method verbs that we should retry on. + + By default, we only retry on methods which are considered to be + idempotent (multiple requests with the same parameters end with the + same state). See :attr:`Retry.DEFAULT_METHOD_WHITELIST`. + + Set to a ``False`` value to retry on any verb. + + :param iterable status_forcelist: + A set of integer HTTP status codes that we should force a retry on. + A retry is initiated if the request method is in ``method_whitelist`` + and the response status code is in ``status_forcelist``. + + By default, this is disabled with ``None``. + + :param float backoff_factor: + A backoff factor to apply between attempts after the second try + (most errors are resolved immediately by a second try without a + delay). urllib3 will sleep for:: + + {backoff factor} * (2 ^ ({number of total retries} - 1)) + + seconds. If the backoff_factor is 0.1, then :func:`.sleep` will sleep + for [0.0s, 0.2s, 0.4s, ...] between retries. It will never be longer + than :attr:`Retry.BACKOFF_MAX`. + + By default, backoff is disabled (set to 0). + + :param bool raise_on_redirect: Whether, if the number of redirects is + exhausted, to raise a MaxRetryError, or to return a response with a + response code in the 3xx range. + + :param bool raise_on_status: Similar meaning to ``raise_on_redirect``: + whether we should raise an exception, or return a response, + if status falls in ``status_forcelist`` range and retries have + been exhausted. + + :param tuple history: The history of the request encountered during + each call to :meth:`~Retry.increment`. The list is in the order + the requests occurred. Each list item is of class :class:`RequestHistory`. + + :param bool respect_retry_after_header: + Whether to respect Retry-After header on status codes defined as + :attr:`Retry.RETRY_AFTER_STATUS_CODES` or not. + + :param iterable remove_headers_on_redirect: + Sequence of headers to remove from the request when a response + indicating a redirect is returned before firing off the redirected + request. + """ + + DEFAULT_METHOD_WHITELIST = frozenset([ + 'HEAD', 'GET', 'PUT', 'DELETE', 'OPTIONS', 'TRACE']) + + RETRY_AFTER_STATUS_CODES = frozenset([413, 429, 503]) + + DEFAULT_REDIRECT_HEADERS_BLACKLIST = frozenset(['Authorization']) + + #: Maximum backoff time. + BACKOFF_MAX = 120 + + def __init__(self, total=10, connect=None, read=None, redirect=None, status=None, + method_whitelist=DEFAULT_METHOD_WHITELIST, status_forcelist=None, + backoff_factor=0, raise_on_redirect=True, raise_on_status=True, + history=None, respect_retry_after_header=True, + remove_headers_on_redirect=DEFAULT_REDIRECT_HEADERS_BLACKLIST): + + self.total = total + self.connect = connect + self.read = read + self.status = status + + if redirect is False or total is False: + redirect = 0 + raise_on_redirect = False + + self.redirect = redirect + self.status_forcelist = status_forcelist or set() + self.method_whitelist = method_whitelist + self.backoff_factor = backoff_factor + self.raise_on_redirect = raise_on_redirect + self.raise_on_status = raise_on_status + self.history = history or tuple() + self.respect_retry_after_header = respect_retry_after_header + self.remove_headers_on_redirect = remove_headers_on_redirect + + def new(self, **kw): + params = dict( + total=self.total, + connect=self.connect, read=self.read, redirect=self.redirect, status=self.status, + method_whitelist=self.method_whitelist, + status_forcelist=self.status_forcelist, + backoff_factor=self.backoff_factor, + raise_on_redirect=self.raise_on_redirect, + raise_on_status=self.raise_on_status, + history=self.history, + remove_headers_on_redirect=self.remove_headers_on_redirect + ) + params.update(kw) + return type(self)(**params) + + @classmethod + def from_int(cls, retries, redirect=True, default=None): + """ Backwards-compatibility for the old retries format.""" + if retries is None: + retries = default if default is not None else cls.DEFAULT + + if isinstance(retries, Retry): + return retries + + redirect = bool(redirect) and None + new_retries = cls(retries, redirect=redirect) + log.debug("Converted retries value: %r -> %r", retries, new_retries) + return new_retries + + def get_backoff_time(self): + """ Formula for computing the current backoff + + :rtype: float + """ + # We want to consider only the last consecutive errors sequence (Ignore redirects). + consecutive_errors_len = len(list(takewhile(lambda x: x.redirect_location is None, + reversed(self.history)))) + if consecutive_errors_len <= 1: + return 0 + + backoff_value = self.backoff_factor * (2 ** (consecutive_errors_len - 1)) + return min(self.BACKOFF_MAX, backoff_value) + + def parse_retry_after(self, retry_after): + # Whitespace: https://tools.ietf.org/html/rfc7230#section-3.2.4 + if re.match(r"^\s*[0-9]+\s*$", retry_after): + seconds = int(retry_after) + else: + retry_date_tuple = email.utils.parsedate(retry_after) + if retry_date_tuple is None: + raise InvalidHeader("Invalid Retry-After header: %s" % retry_after) + retry_date = time.mktime(retry_date_tuple) + seconds = retry_date - time.time() + + if seconds < 0: + seconds = 0 + + return seconds + + def get_retry_after(self, response): + """ Get the value of Retry-After in seconds. """ + + retry_after = response.getheader("Retry-After") + + if retry_after is None: + return None + + return self.parse_retry_after(retry_after) + + def sleep_for_retry(self, response=None): + retry_after = self.get_retry_after(response) + if retry_after: + time.sleep(retry_after) + return True + + return False + + def _sleep_backoff(self): + backoff = self.get_backoff_time() + if backoff <= 0: + return + time.sleep(backoff) + + def sleep(self, response=None): + """ Sleep between retry attempts. + + This method will respect a server's ``Retry-After`` response header + and sleep the duration of the time requested. If that is not present, it + will use an exponential backoff. By default, the backoff factor is 0 and + this method will return immediately. + """ + + if response: + slept = self.sleep_for_retry(response) + if slept: + return + + self._sleep_backoff() + + def _is_connection_error(self, err): + """ Errors when we're fairly sure that the server did not receive the + request, so it should be safe to retry. + """ + return isinstance(err, ConnectTimeoutError) + + def _is_read_error(self, err): + """ Errors that occur after the request has been started, so we should + assume that the server began processing it. + """ + return isinstance(err, (ReadTimeoutError, ProtocolError)) + + def _is_method_retryable(self, method): + """ Checks if a given HTTP method should be retried upon, depending if + it is included on the method whitelist. + """ + if self.method_whitelist and method.upper() not in self.method_whitelist: + return False + + return True + + def is_retry(self, method, status_code, has_retry_after=False): + """ Is this method/status code retryable? (Based on whitelists and control + variables such as the number of total retries to allow, whether to + respect the Retry-After header, whether this header is present, and + whether the returned status code is on the list of status codes to + be retried upon on the presence of the aforementioned header) + """ + if not self._is_method_retryable(method): + return False + + if self.status_forcelist and status_code in self.status_forcelist: + return True + + return (self.total and self.respect_retry_after_header and + has_retry_after and (status_code in self.RETRY_AFTER_STATUS_CODES)) + + def is_exhausted(self): + """ Are we out of retries? """ + retry_counts = (self.total, self.connect, self.read, self.redirect, self.status) + retry_counts = list(filter(None, retry_counts)) + if not retry_counts: + return False + + return min(retry_counts) < 0 + + def increment(self, method=None, url=None, response=None, error=None, + _pool=None, _stacktrace=None): + """ Return a new Retry object with incremented retry counters. + + :param response: A response object, or None, if the server did not + return a response. + :type response: :class:`~urllib3.response.HTTPResponse` + :param Exception error: An error encountered during the request, or + None if the response was received successfully. + + :return: A new ``Retry`` object. + """ + if self.total is False and error: + # Disabled, indicate to re-raise the error. + raise six.reraise(type(error), error, _stacktrace) + + total = self.total + if total is not None: + total -= 1 + + connect = self.connect + read = self.read + redirect = self.redirect + status_count = self.status + cause = 'unknown' + status = None + redirect_location = None + + if error and self._is_connection_error(error): + # Connect retry? + if connect is False: + raise six.reraise(type(error), error, _stacktrace) + elif connect is not None: + connect -= 1 + + elif error and self._is_read_error(error): + # Read retry? + if read is False or not self._is_method_retryable(method): + raise six.reraise(type(error), error, _stacktrace) + elif read is not None: + read -= 1 + + elif response and response.get_redirect_location(): + # Redirect retry? + if redirect is not None: + redirect -= 1 + cause = 'too many redirects' + redirect_location = response.get_redirect_location() + status = response.status + + else: + # Incrementing because of a server error like a 500 in + # status_forcelist and a the given method is in the whitelist + cause = ResponseError.GENERIC_ERROR + if response and response.status: + if status_count is not None: + status_count -= 1 + cause = ResponseError.SPECIFIC_ERROR.format( + status_code=response.status) + status = response.status + + history = self.history + (RequestHistory(method, url, error, status, redirect_location),) + + new_retry = self.new( + total=total, + connect=connect, read=read, redirect=redirect, status=status_count, + history=history) + + if new_retry.is_exhausted(): + raise MaxRetryError(_pool, url, error or ResponseError(cause)) + + log.debug("Incremented Retry for (url='%s'): %r", url, new_retry) + + return new_retry + + def __repr__(self): + return ('{cls.__name__}(total={self.total}, connect={self.connect}, ' + 'read={self.read}, redirect={self.redirect}, status={self.status})').format( + cls=type(self), self=self) + + +# For backwards compatibility (equivalent to pre-v1.9): +Retry.DEFAULT = Retry(3) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py new file mode 100644 index 0000000..3254280 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/ssl_.py @@ -0,0 +1,396 @@ +from __future__ import absolute_import +import errno +import warnings +import hmac +import socket + +from binascii import hexlify, unhexlify +from hashlib import md5, sha1, sha256 + +from ..exceptions import SSLError, InsecurePlatformWarning, SNIMissingWarning +from ..packages import six + + +SSLContext = None +HAS_SNI = False +IS_PYOPENSSL = False +IS_SECURETRANSPORT = False + +# Maps the length of a digest to a possible hash function producing this digest +HASHFUNC_MAP = { + 32: md5, + 40: sha1, + 64: sha256, +} + + +def _const_compare_digest_backport(a, b): + """ + Compare two digests of equal length in constant time. + + The digests must be of type str/bytes. + Returns True if the digests match, and False otherwise. + """ + result = abs(len(a) - len(b)) + for l, r in zip(bytearray(a), bytearray(b)): + result |= l ^ r + return result == 0 + + +_const_compare_digest = getattr(hmac, 'compare_digest', + _const_compare_digest_backport) + + +try: # Test for SSL features + import ssl + from ssl import wrap_socket, CERT_NONE, PROTOCOL_SSLv23 + from ssl import HAS_SNI # Has SNI? +except ImportError: + pass + + +try: + from ssl import OP_NO_SSLv2, OP_NO_SSLv3, OP_NO_COMPRESSION +except ImportError: + OP_NO_SSLv2, OP_NO_SSLv3 = 0x1000000, 0x2000000 + OP_NO_COMPRESSION = 0x20000 + + +# Python 2.7 and earlier didn't have inet_pton on non-Linux +# so we fallback on inet_aton in those cases. This means that +# we can only detect IPv4 addresses in this case. +if hasattr(socket, 'inet_pton'): + inet_pton = socket.inet_pton +else: + # Maybe we can use ipaddress if the user has urllib3[secure]? + try: + from pip._vendor import ipaddress + + def inet_pton(_, host): + if isinstance(host, six.binary_type): + host = host.decode('ascii') + return ipaddress.ip_address(host) + + except ImportError: # Platform-specific: Non-Linux + def inet_pton(_, host): + return socket.inet_aton(host) + + +# A secure default. +# Sources for more information on TLS ciphers: +# +# - https://wiki.mozilla.org/Security/Server_Side_TLS +# - https://www.ssllabs.com/projects/best-practices/index.html +# - https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/ +# +# The general intent is: +# - Prefer TLS 1.3 cipher suites +# - prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE), +# - prefer ECDHE over DHE for better performance, +# - prefer any AES-GCM and ChaCha20 over any AES-CBC for better performance and +# security, +# - prefer AES-GCM over ChaCha20 because hardware-accelerated AES is common, +# - disable NULL authentication, MD5 MACs and DSS for security reasons. +DEFAULT_CIPHERS = ':'.join([ + 'TLS13-AES-256-GCM-SHA384', + 'TLS13-CHACHA20-POLY1305-SHA256', + 'TLS13-AES-128-GCM-SHA256', + 'ECDH+AESGCM', + 'ECDH+CHACHA20', + 'DH+AESGCM', + 'DH+CHACHA20', + 'ECDH+AES256', + 'DH+AES256', + 'ECDH+AES128', + 'DH+AES', + 'RSA+AESGCM', + 'RSA+AES', + '!aNULL', + '!eNULL', + '!MD5', +]) + +try: + from ssl import SSLContext # Modern SSL? +except ImportError: + import sys + + class SSLContext(object): # Platform-specific: Python 2 & 3.1 + supports_set_ciphers = ((2, 7) <= sys.version_info < (3,) or + (3, 2) <= sys.version_info) + + def __init__(self, protocol_version): + self.protocol = protocol_version + # Use default values from a real SSLContext + self.check_hostname = False + self.verify_mode = ssl.CERT_NONE + self.ca_certs = None + self.options = 0 + self.certfile = None + self.keyfile = None + self.ciphers = None + + def load_cert_chain(self, certfile, keyfile): + self.certfile = certfile + self.keyfile = keyfile + + def load_verify_locations(self, cafile=None, capath=None): + self.ca_certs = cafile + + if capath is not None: + raise SSLError("CA directories not supported in older Pythons") + + def set_ciphers(self, cipher_suite): + if not self.supports_set_ciphers: + raise TypeError( + 'Your version of Python does not support setting ' + 'a custom cipher suite. Please upgrade to Python ' + '2.7, 3.2, or later if you need this functionality.' + ) + self.ciphers = cipher_suite + + def wrap_socket(self, socket, server_hostname=None, server_side=False): + warnings.warn( + 'A true SSLContext object is not available. This prevents ' + 'urllib3 from configuring SSL appropriately and may cause ' + 'certain SSL connections to fail. You can upgrade to a newer ' + 'version of Python to solve this. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings', + InsecurePlatformWarning + ) + kwargs = { + 'keyfile': self.keyfile, + 'certfile': self.certfile, + 'ca_certs': self.ca_certs, + 'cert_reqs': self.verify_mode, + 'ssl_version': self.protocol, + 'server_side': server_side, + } + if self.supports_set_ciphers: # Platform-specific: Python 2.7+ + return wrap_socket(socket, ciphers=self.ciphers, **kwargs) + else: # Platform-specific: Python 2.6 + return wrap_socket(socket, **kwargs) + + +def assert_fingerprint(cert, fingerprint): + """ + Checks if given fingerprint matches the supplied certificate. + + :param cert: + Certificate as bytes object. + :param fingerprint: + Fingerprint as string of hexdigits, can be interspersed by colons. + """ + + fingerprint = fingerprint.replace(':', '').lower() + digest_length = len(fingerprint) + hashfunc = HASHFUNC_MAP.get(digest_length) + if not hashfunc: + raise SSLError( + 'Fingerprint of invalid length: {0}'.format(fingerprint)) + + # We need encode() here for py32; works on py2 and p33. + fingerprint_bytes = unhexlify(fingerprint.encode()) + + cert_digest = hashfunc(cert).digest() + + if not _const_compare_digest(cert_digest, fingerprint_bytes): + raise SSLError('Fingerprints did not match. Expected "{0}", got "{1}".' + .format(fingerprint, hexlify(cert_digest))) + + +def resolve_cert_reqs(candidate): + """ + Resolves the argument to a numeric constant, which can be passed to + the wrap_socket function/method from the ssl module. + Defaults to :data:`ssl.CERT_NONE`. + If given a string it is assumed to be the name of the constant in the + :mod:`ssl` module or its abbreviation. + (So you can specify `REQUIRED` instead of `CERT_REQUIRED`. + If it's neither `None` nor a string we assume it is already the numeric + constant which can directly be passed to wrap_socket. + """ + if candidate is None: + return CERT_NONE + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'CERT_' + candidate) + return res + + return candidate + + +def resolve_ssl_version(candidate): + """ + like resolve_cert_reqs + """ + if candidate is None: + return PROTOCOL_SSLv23 + + if isinstance(candidate, str): + res = getattr(ssl, candidate, None) + if res is None: + res = getattr(ssl, 'PROTOCOL_' + candidate) + return res + + return candidate + + +def create_urllib3_context(ssl_version=None, cert_reqs=None, + options=None, ciphers=None): + """All arguments have the same meaning as ``ssl_wrap_socket``. + + By default, this function does a lot of the same work that + ``ssl.create_default_context`` does on Python 3.4+. It: + + - Disables SSLv2, SSLv3, and compression + - Sets a restricted set of server ciphers + + If you wish to enable SSLv3, you can do:: + + from pip._vendor.urllib3.util import ssl_ + context = ssl_.create_urllib3_context() + context.options &= ~ssl_.OP_NO_SSLv3 + + You can do the same to enable compression (substituting ``COMPRESSION`` + for ``SSLv3`` in the last line above). + + :param ssl_version: + The desired protocol version to use. This will default to + PROTOCOL_SSLv23 which will negotiate the highest protocol that both + the server and your installation of OpenSSL support. + :param cert_reqs: + Whether to require the certificate verification. This defaults to + ``ssl.CERT_REQUIRED``. + :param options: + Specific OpenSSL options. These default to ``ssl.OP_NO_SSLv2``, + ``ssl.OP_NO_SSLv3``, ``ssl.OP_NO_COMPRESSION``. + :param ciphers: + Which cipher suites to allow the server to select. + :returns: + Constructed SSLContext object with specified options + :rtype: SSLContext + """ + context = SSLContext(ssl_version or ssl.PROTOCOL_SSLv23) + + # Setting the default here, as we may have no ssl module on import + cert_reqs = ssl.CERT_REQUIRED if cert_reqs is None else cert_reqs + + if options is None: + options = 0 + # SSLv2 is easily broken and is considered harmful and dangerous + options |= OP_NO_SSLv2 + # SSLv3 has several problems and is now dangerous + options |= OP_NO_SSLv3 + # Disable compression to prevent CRIME attacks for OpenSSL 1.0+ + # (issue #309) + options |= OP_NO_COMPRESSION + + context.options |= options + + if getattr(context, 'supports_set_ciphers', True): # Platform-specific: Python 2.6 + context.set_ciphers(ciphers or DEFAULT_CIPHERS) + + context.verify_mode = cert_reqs + if getattr(context, 'check_hostname', None) is not None: # Platform-specific: Python 3.2 + # We do our own verification, including fingerprints and alternative + # hostnames. So disable it here + context.check_hostname = False + return context + + +def ssl_wrap_socket(sock, keyfile=None, certfile=None, cert_reqs=None, + ca_certs=None, server_hostname=None, + ssl_version=None, ciphers=None, ssl_context=None, + ca_cert_dir=None): + """ + All arguments except for server_hostname, ssl_context, and ca_cert_dir have + the same meaning as they do when using :func:`ssl.wrap_socket`. + + :param server_hostname: + When SNI is supported, the expected hostname of the certificate + :param ssl_context: + A pre-made :class:`SSLContext` object. If none is provided, one will + be created using :func:`create_urllib3_context`. + :param ciphers: + A string of ciphers we wish the client to support. This is not + supported on Python 2.6 as the ssl module does not support it. + :param ca_cert_dir: + A directory containing CA certificates in multiple separate files, as + supported by OpenSSL's -CApath flag or the capath argument to + SSLContext.load_verify_locations(). + """ + context = ssl_context + if context is None: + # Note: This branch of code and all the variables in it are no longer + # used by urllib3 itself. We should consider deprecating and removing + # this code. + context = create_urllib3_context(ssl_version, cert_reqs, + ciphers=ciphers) + + if ca_certs or ca_cert_dir: + try: + context.load_verify_locations(ca_certs, ca_cert_dir) + except IOError as e: # Platform-specific: Python 2.6, 2.7, 3.2 + raise SSLError(e) + # Py33 raises FileNotFoundError which subclasses OSError + # These are not equivalent unless we check the errno attribute + except OSError as e: # Platform-specific: Python 3.3 and beyond + if e.errno == errno.ENOENT: + raise SSLError(e) + raise + elif getattr(context, 'load_default_certs', None) is not None: + # try to load OS default certs; works well on Windows (require Python3.4+) + context.load_default_certs() + + if certfile: + context.load_cert_chain(certfile, keyfile) + + # If we detect server_hostname is an IP address then the SNI + # extension should not be used according to RFC3546 Section 3.1 + # We shouldn't warn the user if SNI isn't available but we would + # not be using SNI anyways due to IP address for server_hostname. + if ((server_hostname is not None and not is_ipaddress(server_hostname)) + or IS_SECURETRANSPORT): + if HAS_SNI and server_hostname is not None: + return context.wrap_socket(sock, server_hostname=server_hostname) + + warnings.warn( + 'An HTTPS request has been made, but the SNI (Server Name ' + 'Indication) extension to TLS is not available on this platform. ' + 'This may cause the server to present an incorrect TLS ' + 'certificate, which can cause validation failures. You can upgrade to ' + 'a newer version of Python to solve this. For more information, see ' + 'https://urllib3.readthedocs.io/en/latest/advanced-usage.html' + '#ssl-warnings', + SNIMissingWarning + ) + + return context.wrap_socket(sock) + + +def is_ipaddress(hostname): + """Detects whether the hostname given is an IP address. + + :param str hostname: Hostname to examine. + :return: True if the hostname is an IP address, False otherwise. + """ + if six.PY3 and isinstance(hostname, six.binary_type): + # IDN A-label bytes are ASCII compatible. + hostname = hostname.decode('ascii') + + families = [socket.AF_INET] + if hasattr(socket, 'AF_INET6'): + families.append(socket.AF_INET6) + + for af in families: + try: + inet_pton(af, hostname) + except (socket.error, ValueError, OSError): + pass + else: + return True + return False diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py new file mode 100644 index 0000000..cec817e --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/timeout.py @@ -0,0 +1,242 @@ +from __future__ import absolute_import +# The default socket timeout, used by httplib to indicate that no timeout was +# specified by the user +from socket import _GLOBAL_DEFAULT_TIMEOUT +import time + +from ..exceptions import TimeoutStateError + +# A sentinel value to indicate that no timeout was specified by the user in +# urllib3 +_Default = object() + + +# Use time.monotonic if available. +current_time = getattr(time, "monotonic", time.time) + + +class Timeout(object): + """ Timeout configuration. + + Timeouts can be defined as a default for a pool:: + + timeout = Timeout(connect=2.0, read=7.0) + http = PoolManager(timeout=timeout) + response = http.request('GET', 'http://example.com/') + + Or per-request (which overrides the default for the pool):: + + response = http.request('GET', 'http://example.com/', timeout=Timeout(10)) + + Timeouts can be disabled by setting all the parameters to ``None``:: + + no_timeout = Timeout(connect=None, read=None) + response = http.request('GET', 'http://example.com/, timeout=no_timeout) + + + :param total: + This combines the connect and read timeouts into one; the read timeout + will be set to the time leftover from the connect attempt. In the + event that both a connect timeout and a total are specified, or a read + timeout and a total are specified, the shorter timeout will be applied. + + Defaults to None. + + :type total: integer, float, or None + + :param connect: + The maximum amount of time to wait for a connection attempt to a server + to succeed. Omitting the parameter will default the connect timeout to + the system default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout for connection attempts. + + :type connect: integer, float, or None + + :param read: + The maximum amount of time to wait between consecutive + read operations for a response from the server. Omitting + the parameter will default the read timeout to the system + default, probably `the global default timeout in socket.py + <http://hg.python.org/cpython/file/603b4d593758/Lib/socket.py#l535>`_. + None will set an infinite timeout. + + :type read: integer, float, or None + + .. note:: + + Many factors can affect the total amount of time for urllib3 to return + an HTTP response. + + For example, Python's DNS resolver does not obey the timeout specified + on the socket. Other factors that can affect total request time include + high CPU load, high swap, the program running at a low priority level, + or other behaviors. + + In addition, the read and total timeouts only measure the time between + read operations on the socket connecting the client and the server, + not the total amount of time for the request to return a complete + response. For most requests, the timeout is raised because the server + has not sent the first byte in the specified time. This is not always + the case; if a server streams one byte every fifteen seconds, a timeout + of 20 seconds will not trigger, even though the request will take + several minutes to complete. + + If your goal is to cut off any request after a set amount of wall clock + time, consider having a second "watcher" thread to cut off a slow + request. + """ + + #: A sentinel object representing the default timeout value + DEFAULT_TIMEOUT = _GLOBAL_DEFAULT_TIMEOUT + + def __init__(self, total=None, connect=_Default, read=_Default): + self._connect = self._validate_timeout(connect, 'connect') + self._read = self._validate_timeout(read, 'read') + self.total = self._validate_timeout(total, 'total') + self._start_connect = None + + def __str__(self): + return '%s(connect=%r, read=%r, total=%r)' % ( + type(self).__name__, self._connect, self._read, self.total) + + @classmethod + def _validate_timeout(cls, value, name): + """ Check that a timeout attribute is valid. + + :param value: The timeout value to validate + :param name: The name of the timeout attribute to validate. This is + used to specify in error messages. + :return: The validated and casted version of the given value. + :raises ValueError: If it is a numeric value less than or equal to + zero, or the type is not an integer, float, or None. + """ + if value is _Default: + return cls.DEFAULT_TIMEOUT + + if value is None or value is cls.DEFAULT_TIMEOUT: + return value + + if isinstance(value, bool): + raise ValueError("Timeout cannot be a boolean value. It must " + "be an int, float or None.") + try: + float(value) + except (TypeError, ValueError): + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + try: + if value <= 0: + raise ValueError("Attempted to set %s timeout to %s, but the " + "timeout cannot be set to a value less " + "than or equal to 0." % (name, value)) + except TypeError: # Python 3 + raise ValueError("Timeout value %s was %s, but it must be an " + "int, float or None." % (name, value)) + + return value + + @classmethod + def from_float(cls, timeout): + """ Create a new Timeout from a legacy timeout value. + + The timeout value used by httplib.py sets the same timeout on the + connect(), and recv() socket requests. This creates a :class:`Timeout` + object that sets the individual timeouts to the ``timeout`` value + passed to this function. + + :param timeout: The legacy timeout value. + :type timeout: integer, float, sentinel default object, or None + :return: Timeout object + :rtype: :class:`Timeout` + """ + return Timeout(read=timeout, connect=timeout) + + def clone(self): + """ Create a copy of the timeout object + + Timeout properties are stored per-pool but each request needs a fresh + Timeout object to ensure each one has its own start/stop configured. + + :return: a copy of the timeout object + :rtype: :class:`Timeout` + """ + # We can't use copy.deepcopy because that will also create a new object + # for _GLOBAL_DEFAULT_TIMEOUT, which socket.py uses as a sentinel to + # detect the user default. + return Timeout(connect=self._connect, read=self._read, + total=self.total) + + def start_connect(self): + """ Start the timeout clock, used during a connect() attempt + + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to start a timer that has been started already. + """ + if self._start_connect is not None: + raise TimeoutStateError("Timeout timer has already been started.") + self._start_connect = current_time() + return self._start_connect + + def get_connect_duration(self): + """ Gets the time elapsed since the call to :meth:`start_connect`. + + :return: Elapsed time. + :rtype: float + :raises urllib3.exceptions.TimeoutStateError: if you attempt + to get duration for a timer that hasn't been started. + """ + if self._start_connect is None: + raise TimeoutStateError("Can't get connect duration for timer " + "that has not started.") + return current_time() - self._start_connect + + @property + def connect_timeout(self): + """ Get the value to use when setting a connection timeout. + + This will be a positive float or integer, the value None + (never timeout), or the default system timeout. + + :return: Connect timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + """ + if self.total is None: + return self._connect + + if self._connect is None or self._connect is self.DEFAULT_TIMEOUT: + return self.total + + return min(self._connect, self.total) + + @property + def read_timeout(self): + """ Get the value for the read timeout. + + This assumes some time has elapsed in the connection timeout and + computes the read timeout appropriately. + + If self.total is set, the read timeout is dependent on the amount of + time taken by the connect timeout. If the connection time has not been + established, a :exc:`~urllib3.exceptions.TimeoutStateError` will be + raised. + + :return: Value to use for the read timeout. + :rtype: int, float, :attr:`Timeout.DEFAULT_TIMEOUT` or None + :raises urllib3.exceptions.TimeoutStateError: If :meth:`start_connect` + has not yet been called on this object. + """ + if (self.total is not None and + self.total is not self.DEFAULT_TIMEOUT and + self._read is not None and + self._read is not self.DEFAULT_TIMEOUT): + # In case the connect timeout has not yet been established. + if self._start_connect is None: + return self._read + return max(0, min(self.total - self.get_connect_duration(), + self._read)) + elif self.total is not None and self.total is not self.DEFAULT_TIMEOUT: + return max(0, self.total - self.get_connect_duration()) + else: + return self._read diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py new file mode 100644 index 0000000..6b6f996 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/url.py @@ -0,0 +1,230 @@ +from __future__ import absolute_import +from collections import namedtuple + +from ..exceptions import LocationParseError + + +url_attrs = ['scheme', 'auth', 'host', 'port', 'path', 'query', 'fragment'] + +# We only want to normalize urls with an HTTP(S) scheme. +# urllib3 infers URLs without a scheme (None) to be http. +NORMALIZABLE_SCHEMES = ('http', 'https', None) + + +class Url(namedtuple('Url', url_attrs)): + """ + Datastructure for representing an HTTP URL. Used as a return value for + :func:`parse_url`. Both the scheme and host are normalized as they are + both case-insensitive according to RFC 3986. + """ + __slots__ = () + + def __new__(cls, scheme=None, auth=None, host=None, port=None, path=None, + query=None, fragment=None): + if path and not path.startswith('/'): + path = '/' + path + if scheme: + scheme = scheme.lower() + if host and scheme in NORMALIZABLE_SCHEMES: + host = host.lower() + return super(Url, cls).__new__(cls, scheme, auth, host, port, path, + query, fragment) + + @property + def hostname(self): + """For backwards-compatibility with urlparse. We're nice like that.""" + return self.host + + @property + def request_uri(self): + """Absolute path including the query string.""" + uri = self.path or '/' + + if self.query is not None: + uri += '?' + self.query + + return uri + + @property + def netloc(self): + """Network location including host and port""" + if self.port: + return '%s:%d' % (self.host, self.port) + return self.host + + @property + def url(self): + """ + Convert self into a url + + This function should more or less round-trip with :func:`.parse_url`. The + returned url may not be exactly the same as the url inputted to + :func:`.parse_url`, but it should be equivalent by the RFC (e.g., urls + with a blank port will have : removed). + + Example: :: + + >>> U = parse_url('http://google.com/mail/') + >>> U.url + 'http://google.com/mail/' + >>> Url('http', 'username:password', 'host.com', 80, + ... '/path', 'query', 'fragment').url + 'http://username:password@host.com:80/path?query#fragment' + """ + scheme, auth, host, port, path, query, fragment = self + url = '' + + # We use "is not None" we want things to happen with empty strings (or 0 port) + if scheme is not None: + url += scheme + '://' + if auth is not None: + url += auth + '@' + if host is not None: + url += host + if port is not None: + url += ':' + str(port) + if path is not None: + url += path + if query is not None: + url += '?' + query + if fragment is not None: + url += '#' + fragment + + return url + + def __str__(self): + return self.url + + +def split_first(s, delims): + """ + Given a string and an iterable of delimiters, split on the first found + delimiter. Return two split parts and the matched delimiter. + + If not found, then the first part is the full input string. + + Example:: + + >>> split_first('foo/bar?baz', '?/=') + ('foo', 'bar?baz', '/') + >>> split_first('foo/bar?baz', '123') + ('foo/bar?baz', '', None) + + Scales linearly with number of delims. Not ideal for large number of delims. + """ + min_idx = None + min_delim = None + for d in delims: + idx = s.find(d) + if idx < 0: + continue + + if min_idx is None or idx < min_idx: + min_idx = idx + min_delim = d + + if min_idx is None or min_idx < 0: + return s, '', None + + return s[:min_idx], s[min_idx + 1:], min_delim + + +def parse_url(url): + """ + Given a url, return a parsed :class:`.Url` namedtuple. Best-effort is + performed to parse incomplete urls. Fields not provided will be None. + + Partly backwards-compatible with :mod:`urlparse`. + + Example:: + + >>> parse_url('http://google.com/mail/') + Url(scheme='http', host='google.com', port=None, path='/mail/', ...) + >>> parse_url('google.com:80') + Url(scheme=None, host='google.com', port=80, path=None, ...) + >>> parse_url('/foo?bar') + Url(scheme=None, host=None, port=None, path='/foo', query='bar', ...) + """ + + # While this code has overlap with stdlib's urlparse, it is much + # simplified for our needs and less annoying. + # Additionally, this implementations does silly things to be optimal + # on CPython. + + if not url: + # Empty + return Url() + + scheme = None + auth = None + host = None + port = None + path = None + fragment = None + query = None + + # Scheme + if '://' in url: + scheme, url = url.split('://', 1) + + # Find the earliest Authority Terminator + # (http://tools.ietf.org/html/rfc3986#section-3.2) + url, path_, delim = split_first(url, ['/', '?', '#']) + + if delim: + # Reassemble the path + path = delim + path_ + + # Auth + if '@' in url: + # Last '@' denotes end of auth part + auth, url = url.rsplit('@', 1) + + # IPv6 + if url and url[0] == '[': + host, url = url.split(']', 1) + host += ']' + + # Port + if ':' in url: + _host, port = url.split(':', 1) + + if not host: + host = _host + + if port: + # If given, ports must be integers. No whitespace, no plus or + # minus prefixes, no non-integer digits such as ^2 (superscript). + if not port.isdigit(): + raise LocationParseError(url) + try: + port = int(port) + except ValueError: + raise LocationParseError(url) + else: + # Blank ports are cool, too. (rfc3986#section-3.2.3) + port = None + + elif not host and url: + host = url + + if not path: + return Url(scheme, auth, host, port, path, query, fragment) + + # Fragment + if '#' in path: + path, fragment = path.split('#', 1) + + # Query + if '?' in path: + path, query = path.split('?', 1) + + return Url(scheme, auth, host, port, path, query, fragment) + + +def get_host(url): + """ + Deprecated. Use :func:`parse_url` instead. + """ + p = parse_url(url) + return p.scheme or 'http', p.hostname, p.port diff --git a/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py new file mode 100644 index 0000000..fa686ef --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/urllib3/util/wait.py @@ -0,0 +1,153 @@ +import errno +from functools import partial +import select +import sys +try: + from time import monotonic +except ImportError: + from time import time as monotonic + +__all__ = ["NoWayToWaitForSocketError", "wait_for_read", "wait_for_write"] + + +class NoWayToWaitForSocketError(Exception): + pass + + +# How should we wait on sockets? +# +# There are two types of APIs you can use for waiting on sockets: the fancy +# modern stateful APIs like epoll/kqueue, and the older stateless APIs like +# select/poll. The stateful APIs are more efficient when you have a lots of +# sockets to keep track of, because you can set them up once and then use them +# lots of times. But we only ever want to wait on a single socket at a time +# and don't want to keep track of state, so the stateless APIs are actually +# more efficient. So we want to use select() or poll(). +# +# Now, how do we choose between select() and poll()? On traditional Unixes, +# select() has a strange calling convention that makes it slow, or fail +# altogether, for high-numbered file descriptors. The point of poll() is to fix +# that, so on Unixes, we prefer poll(). +# +# On Windows, there is no poll() (or at least Python doesn't provide a wrapper +# for it), but that's OK, because on Windows, select() doesn't have this +# strange calling convention; plain select() works fine. +# +# So: on Windows we use select(), and everywhere else we use poll(). We also +# fall back to select() in case poll() is somehow broken or missing. + +if sys.version_info >= (3, 5): + # Modern Python, that retries syscalls by default + def _retry_on_intr(fn, timeout): + return fn(timeout) +else: + # Old and broken Pythons. + def _retry_on_intr(fn, timeout): + if timeout is not None and timeout <= 0: + return fn(timeout) + + if timeout is None: + deadline = float("inf") + else: + deadline = monotonic() + timeout + + while True: + try: + return fn(timeout) + # OSError for 3 <= pyver < 3.5, select.error for pyver <= 2.7 + except (OSError, select.error) as e: + # 'e.args[0]' incantation works for both OSError and select.error + if e.args[0] != errno.EINTR: + raise + else: + timeout = deadline - monotonic() + if timeout < 0: + timeout = 0 + if timeout == float("inf"): + timeout = None + continue + + +def select_wait_for_socket(sock, read=False, write=False, timeout=None): + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + rcheck = [] + wcheck = [] + if read: + rcheck.append(sock) + if write: + wcheck.append(sock) + # When doing a non-blocking connect, most systems signal success by + # marking the socket writable. Windows, though, signals success by marked + # it as "exceptional". We paper over the difference by checking the write + # sockets for both conditions. (The stdlib selectors module does the same + # thing.) + fn = partial(select.select, rcheck, wcheck, wcheck) + rready, wready, xready = _retry_on_intr(fn, timeout) + return bool(rready or wready or xready) + + +def poll_wait_for_socket(sock, read=False, write=False, timeout=None): + if not read and not write: + raise RuntimeError("must specify at least one of read=True, write=True") + mask = 0 + if read: + mask |= select.POLLIN + if write: + mask |= select.POLLOUT + poll_obj = select.poll() + poll_obj.register(sock, mask) + + # For some reason, poll() takes timeout in milliseconds + def do_poll(t): + if t is not None: + t *= 1000 + return poll_obj.poll(t) + + return bool(_retry_on_intr(do_poll, timeout)) + + +def null_wait_for_socket(*args, **kwargs): + raise NoWayToWaitForSocketError("no select-equivalent available") + + +def _have_working_poll(): + # Apparently some systems have a select.poll that fails as soon as you try + # to use it, either due to strange configuration or broken monkeypatching + # from libraries like eventlet/greenlet. + try: + poll_obj = select.poll() + poll_obj.poll(0) + except (AttributeError, OSError): + return False + else: + return True + + +def wait_for_socket(*args, **kwargs): + # We delay choosing which implementation to use until the first time we're + # called. We could do it at import time, but then we might make the wrong + # decision if someone goes wild with monkeypatching select.poll after + # we're imported. + global wait_for_socket + if _have_working_poll(): + wait_for_socket = poll_wait_for_socket + elif hasattr(select, "select"): + wait_for_socket = select_wait_for_socket + else: # Platform-specific: Appengine. + wait_for_socket = null_wait_for_socket + return wait_for_socket(*args, **kwargs) + + +def wait_for_read(sock, timeout=None): + """ Waits for reading to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, read=True, timeout=timeout) + + +def wait_for_write(sock, timeout=None): + """ Waits for writing to be available on a given socket. + Returns True if the socket is readable, or False if the timeout expired. + """ + return wait_for_socket(sock, write=True, timeout=timeout) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py new file mode 100644 index 0000000..d21d697 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__init__.py @@ -0,0 +1,342 @@ +# coding: utf-8 +""" + + webencodings + ~~~~~~~~~~~~ + + This is a Python implementation of the `WHATWG Encoding standard + <http://encoding.spec.whatwg.org/>`. See README for details. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + +from .labels import LABELS + + +VERSION = '0.5.1' + + +# Some names in Encoding are not valid Python aliases. Remap these. +PYTHON_NAMES = { + 'iso-8859-8-i': 'iso-8859-8', + 'x-mac-cyrillic': 'mac-cyrillic', + 'macintosh': 'mac-roman', + 'windows-874': 'cp874'} + +CACHE = {} + + +def ascii_lower(string): + r"""Transform (only) ASCII letters to lower case: A-Z is mapped to a-z. + + :param string: An Unicode string. + :returns: A new Unicode string. + + This is used for `ASCII case-insensitive + <http://encoding.spec.whatwg.org/#ascii-case-insensitive>`_ + matching of encoding labels. + The same matching is also used, among other things, + for `CSS keywords <http://dev.w3.org/csswg/css-values/#keywords>`_. + + This is different from the :meth:`~py:str.lower` method of Unicode strings + which also affect non-ASCII characters, + sometimes mapping them into the ASCII range: + + >>> keyword = u'Bac\N{KELVIN SIGN}ground' + >>> assert keyword.lower() == u'background' + >>> assert ascii_lower(keyword) != keyword.lower() + >>> assert ascii_lower(keyword) == u'bac\N{KELVIN SIGN}ground' + + """ + # This turns out to be faster than unicode.translate() + return string.encode('utf8').lower().decode('utf8') + + +def lookup(label): + """ + Look for an encoding by its label. + This is the spec’s `get an encoding + <http://encoding.spec.whatwg.org/#concept-encoding-get>`_ algorithm. + Supported labels are listed there. + + :param label: A string. + :returns: + An :class:`Encoding` object, or :obj:`None` for an unknown label. + + """ + # Only strip ASCII whitespace: U+0009, U+000A, U+000C, U+000D, and U+0020. + label = ascii_lower(label.strip('\t\n\f\r ')) + name = LABELS.get(label) + if name is None: + return None + encoding = CACHE.get(name) + if encoding is None: + if name == 'x-user-defined': + from .x_user_defined import codec_info + else: + python_name = PYTHON_NAMES.get(name, name) + # Any python_name value that gets to here should be valid. + codec_info = codecs.lookup(python_name) + encoding = Encoding(name, codec_info) + CACHE[name] = encoding + return encoding + + +def _get_encoding(encoding_or_label): + """ + Accept either an encoding object or label. + + :param encoding: An :class:`Encoding` object or a label string. + :returns: An :class:`Encoding` object. + :raises: :exc:`~exceptions.LookupError` for an unknown label. + + """ + if hasattr(encoding_or_label, 'codec_info'): + return encoding_or_label + + encoding = lookup(encoding_or_label) + if encoding is None: + raise LookupError('Unknown encoding label: %r' % encoding_or_label) + return encoding + + +class Encoding(object): + """Reresents a character encoding such as UTF-8, + that can be used for decoding or encoding. + + .. attribute:: name + + Canonical name of the encoding + + .. attribute:: codec_info + + The actual implementation of the encoding, + a stdlib :class:`~codecs.CodecInfo` object. + See :func:`codecs.register`. + + """ + def __init__(self, name, codec_info): + self.name = name + self.codec_info = codec_info + + def __repr__(self): + return '<Encoding %s>' % self.name + + +#: The UTF-8 encoding. Should be used for new content and formats. +UTF8 = lookup('utf-8') + +_UTF16LE = lookup('utf-16le') +_UTF16BE = lookup('utf-16be') + + +def decode(input, fallback_encoding, errors='replace'): + """ + Decode a single string. + + :param input: A byte string + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: + A ``(output, encoding)`` tuple of an Unicode string + and an :obj:`Encoding`. + + """ + # Fail early if `encoding` is an invalid label. + fallback_encoding = _get_encoding(fallback_encoding) + bom_encoding, input = _detect_bom(input) + encoding = bom_encoding or fallback_encoding + return encoding.codec_info.decode(input, errors)[0], encoding + + +def _detect_bom(input): + """Return (bom_encoding, input), with any BOM removed from the input.""" + if input.startswith(b'\xFF\xFE'): + return _UTF16LE, input[2:] + if input.startswith(b'\xFE\xFF'): + return _UTF16BE, input[2:] + if input.startswith(b'\xEF\xBB\xBF'): + return UTF8, input[3:] + return None, input + + +def encode(input, encoding=UTF8, errors='strict'): + """ + Encode a single string. + + :param input: An Unicode string. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :return: A byte string. + + """ + return _get_encoding(encoding).codec_info.encode(input, errors)[0] + + +def iter_decode(input, fallback_encoding, errors='replace'): + """ + "Pull"-based decoder. + + :param input: + An iterable of byte strings. + + The input is first consumed just enough to determine the encoding + based on the precense of a BOM, + then consumed on demand when the return value is. + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: + An ``(output, encoding)`` tuple. + :obj:`output` is an iterable of Unicode strings, + :obj:`encoding` is the :obj:`Encoding` that is being used. + + """ + + decoder = IncrementalDecoder(fallback_encoding, errors) + generator = _iter_decode_generator(input, decoder) + encoding = next(generator) + return generator, encoding + + +def _iter_decode_generator(input, decoder): + """Return a generator that first yields the :obj:`Encoding`, + then yields output chukns as Unicode strings. + + """ + decode = decoder.decode + input = iter(input) + for chunck in input: + output = decode(chunck) + if output: + assert decoder.encoding is not None + yield decoder.encoding + yield output + break + else: + # Input exhausted without determining the encoding + output = decode(b'', final=True) + assert decoder.encoding is not None + yield decoder.encoding + if output: + yield output + return + + for chunck in input: + output = decode(chunck) + if output: + yield output + output = decode(b'', final=True) + if output: + yield output + + +def iter_encode(input, encoding=UTF8, errors='strict'): + """ + “Pull”-based encoder. + + :param input: An iterable of Unicode strings. + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + :returns: An iterable of byte strings. + + """ + # Fail early if `encoding` is an invalid label. + encode = IncrementalEncoder(encoding, errors).encode + return _iter_encode_generator(input, encode) + + +def _iter_encode_generator(input, encode): + for chunck in input: + output = encode(chunck) + if output: + yield output + output = encode('', final=True) + if output: + yield output + + +class IncrementalDecoder(object): + """ + “Push”-based decoder. + + :param fallback_encoding: + An :class:`Encoding` object or a label string. + The encoding to use if :obj:`input` does note have a BOM. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + """ + def __init__(self, fallback_encoding, errors='replace'): + # Fail early if `encoding` is an invalid label. + self._fallback_encoding = _get_encoding(fallback_encoding) + self._errors = errors + self._buffer = b'' + self._decoder = None + #: The actual :class:`Encoding` that is being used, + #: or :obj:`None` if that is not determined yet. + #: (Ie. if there is not enough input yet to determine + #: if there is a BOM.) + self.encoding = None # Not known yet. + + def decode(self, input, final=False): + """Decode one chunk of the input. + + :param input: A byte string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: An Unicode string. + + """ + decoder = self._decoder + if decoder is not None: + return decoder(input, final) + + input = self._buffer + input + encoding, input = _detect_bom(input) + if encoding is None: + if len(input) < 3 and not final: # Not enough data yet. + self._buffer = input + return '' + else: # No BOM + encoding = self._fallback_encoding + decoder = encoding.codec_info.incrementaldecoder(self._errors).decode + self._decoder = decoder + self.encoding = encoding + return decoder(input, final) + + +class IncrementalEncoder(object): + """ + “Push”-based encoder. + + :param encoding: An :class:`Encoding` object or a label string. + :param errors: Type of error handling. See :func:`codecs.register`. + :raises: :exc:`~exceptions.LookupError` for an unknown encoding label. + + .. method:: encode(input, final=False) + + :param input: An Unicode string. + :param final: + Indicate that no more input is available. + Must be :obj:`True` if this is the last call. + :returns: A byte string. + + """ + def __init__(self, encoding=UTF8, errors='strict'): + encoding = _get_encoding(encoding) + self.encode = encoding.codec_info.incrementalencoder(errors).encode diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d869d280e2f33d049294e9dce1d55d18db000f42 GIT binary patch literal 9632 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/labels.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ffc978fc18c3ab8c86e2818a2734ad9dca90996b GIT binary patch literal 4046 zcmeHKOK%)S5MJBs-SzsF2X6=r1OkSPJ@1{d5DE!7Acb6fi;zaM)9u~%&dw~;yRkC| zehCt1B+eZ8AwlXZ|AG_M-Sg<NW95v*esZR&ySl5otGcT4aCdjuf#0)V@BMiDZm07% zXR6;{Ks<my`sZ4wgF4STXiZ=pNo=6Y=%UNmM3>P+ZS>Lg7@${U3%v?M#IfDN4&vAq z*h3BW(Ty56(XA4<QG+)S$D0Cgq1WMU#PQBGco%WJC-6Sv_(0$ex`RHvf{&1fKCbZz z;<yX=w1v;mRop}O(C6q2zybR5mzU4h&{rp&gZsrF!=VPhb3DdroFS4<=wT9#aYDuT z&sTqP!4J_wt5#@ofws)F<rI@#OQShHlyb*$ws?_~$#i+FJ*r5}GE7SwztB#|JWI8c zXhBk;?l>VaPANXt9-e%6U!xdnPriTj`02@G?KI0ZgqIOXC~RG9u9l~|&w6A$_dTx| z5}N70?*_W1(6&N53hgSix^|?D`^8SZr>~P@yXH(oWo(skRK`^qujtJ(;_G?&U9qis z6q9tB(P^=LPEwSeQ{5jq#ZJYTmTR;)v&C60&Tet-UEJ23*WyMk&M)>Zbg)a0!Dk6L zgKbR4GuEGsP2aGMVmK}I$ym2+(_-B*nYcv{uVVddA&+VqmIVykqEm9Z49^Ia^Rrx; z2WG&XXL@5?Q3>XXR}|+u!lxv~=-_2>bCnVZNvxXy;qJ=oUEqAS0gh*z@q&K_F_n>! zLqh7XZD47ZL`#yY@letv*G<DLwm?LN3>%cB6bQ>e+K17SJ~jh?#MTpw_2jOq3N_41 zTBryb6?Uyc3dn8kqETUU6+Wo2OBJ@NLXF;%<|-f*>r*(j3Mn8}IEo6VQsI;;9CoX@ zsM_U&ic(%f`C_<E$7yuBwN5D@b-Id9SL*CVc{C<*F^K3q(?^D19**C%hgF8K8;woX zDjd%vIIVgM5XRsh`Q|+xw>Tm#=hj-I###uI($DhIOKUyFT2K0Uzp-GFV>~Mcr2#%0 z;3Qjyf#tJJF~xe~<12SnW)Y#?YqXDQ?NUH$A1T^LQu_{Fr6FF0a(@}h{GNQQUd<Gb zb9~Nv@~fzCCobGvh3z-Sz(LBZkd{khe8m{Qblh`7S5cyP$S2BOLuO?CB%6@9mJ#p6 zQ*$5W4ely_A+9{TcwnZ%s^A53J@Lw@Y^{~gMatWa{H3hR_m?tGBjczKC{PWO!73NH z%>tRQ<yDw2SkzkNv3^W>4$s*Jd{~#$RaR#ryN6A72e;MvooxV_uR~%gwq<(Fvw4&j zeU!<RuhbS(+?6!VY)mtY{*qALv!M1=^#O_n>&1&JWx^;17rGoT=i7zDtmn;QFG?v1 zFYH4{Hv<oXI-)Tl<uXfTS2IxW(Uc|E43vnIHVgk6N<uR07?T3!#VRpo%79-_U{?_~ zVA_i6!iH8|vTBnd0gI!x>z!TCL-rK&E$6HCzBF89GUY)8wXsq_8XG9a2He;HqQWhW zZI@N2HlgxLd)}?*VZAW1U5LGU9^QeNZ<pp#JwGbv;h|Td05Ra#^H+*^u`i=;HOnKC zk|>2po<fnOnAgq8Sd?>_^ITuDz5$6%PC)SwxkNE63EemH4Ia$=^>VL+?#&D63ubwj z4=YVVz9|NHr=U+~G^RyAPIb=08K`I=AXYEr$nBUyGqISV)A{l&T14Eyy1xK1*=dx) z$XkueZO1UCqVa&fgAL|1oJHvwDP%LE!(iS6Ygm^8*}Nj#JS%z^Iv?Z@9F)v*whJ$v z#;#|WyzbXc%&<yhPQV|0j^PpS&1e{hTohgq$hP@_^~;Ue00<%1=nh~Xncw+wuJ4k1 zvR}HsTY7r1&iY}9vN#M`@5#3hA3r(yt&_)aUh&UA4~~}e#nFN+bdu6#lq7n5K1t7( yKRJ9*{DsdkG@<#C`d@(~+1Vd1Ua-N}^9-#L{LMCON`HqotJ_;&`yc;}8~7LHLRd8b literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/mklabels.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f9480e0ec05b8767262d2fa4d95199b9d95cdefe GIT binary patch literal 1868 zcmcIlPfsL86tAl8>FMcZk>I*nTn@FY7$<?56*nFT5|=-RO^}0Q6v=Kn%~Z|MOHX%C zRUr({cn}ix=qGSE`ZfF*b@k*|;N*MV46>1UvpV(a|Eu47?^mxk?%xjxl>Og6d^J}g z<WC$-iVvO7q3R9@LH3EDf+cjH4rZX|B&_G`JCuAwQtlGz9tCQR68wtQO1b(iN!cC| zuBcp)eNT9z3T;*T!ari_K-Oec)XwQSg;T6W>cQC`LBOG$$OD<SGZCj<-RK=9(Sb~K zvGT)Rr9AYd?8-D!k&)aS%C~it8h9@g$BAr|`&ZjpK2UM@(5&*!NtdrY`*?*P40tQ< zWhrk(d7Ks(uO@L@rdqD@jn>u@*HZGGmz&$Wt!>`P6c^G&aiT%>U*IpYTc@^qtdcAT zJ1EXT!PbGg2~|G;F@$eSF3AzoGlu?1hXkBJck9enlI%n(JN-gysZ5-u+e&2$lzQ4I z@XGH*d7$8GqiK41GmrD-IMpUflI8YEH+^IJ&vCM-;de3>nQGqlX>;P!Mn14pQE^FF zT#2x>3xd!Ys*nUX@DVy*ifzdX+NC34g>Wv2A!BOTket)8b4kXoa4+d4-GcFmnTn_g z?}7{&j?d{YWJt%}PozUd73TeN{t{RK^Ht$vPt?Z#5HuhwcB6N}bqfm%caY=1sZk#I zBFg!MPW+k)CPR|Mil<TUe<nl${3+kt+v8gqPcy@%h|QDWDgWv)*1QuZl0zFEo2(a^ zxD8PpaG<h8DhuS|t!M?o&WnxhofiL$e;?e01_Oq%YGG)0Ky-mwueU~YNClZATjcep zBQ|7$7X6P#jv<B)9Sp{p33f>h1V=b?7`|fMVZXZl`Tk7bg#fs=HgTV}Ug<zfkFATo zt2@?JGFJsxU={h9!x7eaX8kr;(9P7q`V$4fY<$cGdrMITxL3hi5^K}WdinY?+JHRs z7^744Y<}X3##)krbM!iNCYx;~((O3DaRhR+;3q119|X8z_7xi;3xQqd^lNy9eI~9S z8nsR$)4HSHfvsv5#S{v>{ua908e%xj)%pr7Xa>S1XOHgyHre+UAhhrkJh%h`0DVvb z5&%fhpW*2sut($p#GvCmB-aozAv$N%m<|{9>Y@g@6kJgbsYSg9ivEQfQ%)~B4Z)&+ zu&al#^*LT%pr)3NEUDM5`$lIerkO}+g-aO4NLWuu$h*=ypvijj)IjpEUX()~6L2Vt z!CTgW%w{Wjq>NVh2Pv)tSdXxe)>?n!n>iS1bS#<mn8)UwS?bcD_|#&tGYorCoQC09 z<ItFVwb`6drJ-}#Zk!xO=A_%mRQF~<HxPV1u+=aWSvw5XW7OmUsw6%rt-1HImuJcp zY12-ZD-9+4#}WvNPvz!zBykvmIgnS)t;iP~D2-Vw{~PP~;9Oyh%Y4cpK~B?I$FKNL GeEK)qr{UB9 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/tests.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c0090208a9660b8d46fcc8131f3d1493a651d219 GIT binary patch literal 5009 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/__pycache__/x_user_defined.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3c711d314d340b2947fd5fa1e16b1dba7e646fc8 GIT binary patch literal 2621 zcmbtW*?Sa45TDtZJ+m7^<PgvCLZc+{KH?P!peV*8D!QWMW~T!aXJ?n5Svf=z0^SJT z2T(;oPUTX-gX@p*^JQLr@~Pf^vU-+H0^;}SXYW@v-PJQyUB5bd=M)M#jYkn@F8;Mm z(|%Wr=E(A-mnqoG%+ZRPqdN&tuOx~IUCj;8C>jrGj_D-VYfe%a!{&%lG+B~z(kw}{ zB*~H_OEONDC0UlFSdwB%&S_yui!fQ19x;n)mgSuS%L=h9!?FzTWt~=Gj%dTVn74?e zNQsO{JCio1i+QK5SP;hcR#6z$i<2B<K<k*i>bG3Z;;~!|3cp-+Tz^T>wZg6kLfVcP za(&^%`)~a7XegNNTW+Q1iHh*UQs`EFt2$(bONF(fQz`2_tITRz>1uq|Q?AxlN_WZ9 zu*d3aPOV#SzU5YHaHTciR#?$Mspk6eDSAA&Ec`(9SaSyE&awg_tc45u=JgNEvxchD zazt2iy?|B!!9mbE^r)@wyX=*)JvS7x<OTg@wbL91PkNaGi<!`hItMP{q@9Fgtk;VM z2SSBQFPct@!OBL-KGs!^Qb8!)a#&WMtD&Arraq>im0755*H`PS6JcUhp{)0J7*R@{ zqZ~x7<)tNADb?&42@$n65wXM4peOiEGZ5ZTlyv=CJ&aO9%Bl?ZX|jbC|M_rtSgCc_ z+*+sW2Vu$cI?KzK_`~6{+m$dT`&HpPRoOi;q}}I+w5zs~6{~oQ>FUf0W}3b#AG_Dp z*!WN0N#*{yYwReij#}d<r&QB5nc>%@Dix_JDR!yB^6L9k<GV|Ee%_H98~q)+G<mc6 zNJbgk_DdCE+fmN8D^;iNsd?VEm(@#NV@DR0B`(*A<`kAv*_0}FQ<(y#IFra3v82q4 zv7uh+WeTP-8_Sa9SeBR^;#AbWz%R>2`g`+YXyyD1V>pG?oXrqzI1w77hNI8WSV^K^ z>b%!s#&F6M&l@<UmDCtVFG_M{mb~-ui#@%PUu}Xn<L^g08(c<mKAV}WEVL_jkzz4Y zF*M^W21%Xx3Z__bMwe>+KOveMr^x?>NEKTHqDefP2$57lJs%*I1=liN2%xhE>KaS6 z3jp+wS)?-Knx<j~NUhHSNX4~Ry`b<M%OPC_J<1P+Qj{u-r0P-JD$WnfcreD(R+a4y zN}noSHmKJB)!<X2<os)c7qfv`6AY^Ls@8Lxdq+AlRnd)?T-5H4S4E?*$a7>3v}Kg% zmdY3~@sXOV<uM|4P5G!N3^SQZXR^7Le4%wx+vN6(rc9kS{o)yyTzc8%S6pdbb@esZ zUN`gl8#->hX;x=fH(wyP-G0ZNcinwY&%O8E|G<O2v*+~9oj3oXhZj8Z=)%YPAAjP> zrv{#W=GjHhJzsob@ry6nFP8?(d_^r;>JGo+Rs3pgnGC}EtIJocT=m-O*WXw}@Fu}p zf^`HV1nUVl5WGe3Ho-dt?-IO6@IJu@1RDuHB-li-ncyRWj|n~@_>|x?g3k%QAo!Bt zD}t{Hwh(M3*hT;ZNU)t?lwb$JPJ(X;b`k6**h8?FU?0JLf^P}FBRD{Ckl+x(VS*zB z-xK^maFpN}!Eu5g34S8@ncx?K69gv-P7$0YI79d*;ab9Vgd>FO2{#bFMff)1JB05N zzDM{z;Rl2p2|py<M7WvoBf^gfKOy{-@H4{C3BMrxlJG0SuL-vhZYA7C2!u$uop6+J z2jNb_ZwPl0?k3zrxR-Dr;eNtz3BMyeKzNYw5aD6MBZS`*{y=z?@EGB7!XF8LBK(=~ z7s3;SCkamxo+dog(H5m`+o_ftt$wH;)+M)ksZyiSEe$nOjVUg^xFDoT(kL6>Y72b+ zhcI>(L^*Xqm2Fo^RqKcf&1-qE?s|??9d|<a7%RLeb6?|{c|a9%Fq4^?$R{$%_H28y ZJvqgkk}~y#p5k93{$;Y}8f}f1{0ny^{qFz( literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py new file mode 100644 index 0000000..29cbf91 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/labels.py @@ -0,0 +1,231 @@ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { + 'unicode-1-1-utf-8': 'utf-8', + 'utf-8': 'utf-8', + 'utf8': 'utf-8', + '866': 'ibm866', + 'cp866': 'ibm866', + 'csibm866': 'ibm866', + 'ibm866': 'ibm866', + 'csisolatin2': 'iso-8859-2', + 'iso-8859-2': 'iso-8859-2', + 'iso-ir-101': 'iso-8859-2', + 'iso8859-2': 'iso-8859-2', + 'iso88592': 'iso-8859-2', + 'iso_8859-2': 'iso-8859-2', + 'iso_8859-2:1987': 'iso-8859-2', + 'l2': 'iso-8859-2', + 'latin2': 'iso-8859-2', + 'csisolatin3': 'iso-8859-3', + 'iso-8859-3': 'iso-8859-3', + 'iso-ir-109': 'iso-8859-3', + 'iso8859-3': 'iso-8859-3', + 'iso88593': 'iso-8859-3', + 'iso_8859-3': 'iso-8859-3', + 'iso_8859-3:1988': 'iso-8859-3', + 'l3': 'iso-8859-3', + 'latin3': 'iso-8859-3', + 'csisolatin4': 'iso-8859-4', + 'iso-8859-4': 'iso-8859-4', + 'iso-ir-110': 'iso-8859-4', + 'iso8859-4': 'iso-8859-4', + 'iso88594': 'iso-8859-4', + 'iso_8859-4': 'iso-8859-4', + 'iso_8859-4:1988': 'iso-8859-4', + 'l4': 'iso-8859-4', + 'latin4': 'iso-8859-4', + 'csisolatincyrillic': 'iso-8859-5', + 'cyrillic': 'iso-8859-5', + 'iso-8859-5': 'iso-8859-5', + 'iso-ir-144': 'iso-8859-5', + 'iso8859-5': 'iso-8859-5', + 'iso88595': 'iso-8859-5', + 'iso_8859-5': 'iso-8859-5', + 'iso_8859-5:1988': 'iso-8859-5', + 'arabic': 'iso-8859-6', + 'asmo-708': 'iso-8859-6', + 'csiso88596e': 'iso-8859-6', + 'csiso88596i': 'iso-8859-6', + 'csisolatinarabic': 'iso-8859-6', + 'ecma-114': 'iso-8859-6', + 'iso-8859-6': 'iso-8859-6', + 'iso-8859-6-e': 'iso-8859-6', + 'iso-8859-6-i': 'iso-8859-6', + 'iso-ir-127': 'iso-8859-6', + 'iso8859-6': 'iso-8859-6', + 'iso88596': 'iso-8859-6', + 'iso_8859-6': 'iso-8859-6', + 'iso_8859-6:1987': 'iso-8859-6', + 'csisolatingreek': 'iso-8859-7', + 'ecma-118': 'iso-8859-7', + 'elot_928': 'iso-8859-7', + 'greek': 'iso-8859-7', + 'greek8': 'iso-8859-7', + 'iso-8859-7': 'iso-8859-7', + 'iso-ir-126': 'iso-8859-7', + 'iso8859-7': 'iso-8859-7', + 'iso88597': 'iso-8859-7', + 'iso_8859-7': 'iso-8859-7', + 'iso_8859-7:1987': 'iso-8859-7', + 'sun_eu_greek': 'iso-8859-7', + 'csiso88598e': 'iso-8859-8', + 'csisolatinhebrew': 'iso-8859-8', + 'hebrew': 'iso-8859-8', + 'iso-8859-8': 'iso-8859-8', + 'iso-8859-8-e': 'iso-8859-8', + 'iso-ir-138': 'iso-8859-8', + 'iso8859-8': 'iso-8859-8', + 'iso88598': 'iso-8859-8', + 'iso_8859-8': 'iso-8859-8', + 'iso_8859-8:1988': 'iso-8859-8', + 'visual': 'iso-8859-8', + 'csiso88598i': 'iso-8859-8-i', + 'iso-8859-8-i': 'iso-8859-8-i', + 'logical': 'iso-8859-8-i', + 'csisolatin6': 'iso-8859-10', + 'iso-8859-10': 'iso-8859-10', + 'iso-ir-157': 'iso-8859-10', + 'iso8859-10': 'iso-8859-10', + 'iso885910': 'iso-8859-10', + 'l6': 'iso-8859-10', + 'latin6': 'iso-8859-10', + 'iso-8859-13': 'iso-8859-13', + 'iso8859-13': 'iso-8859-13', + 'iso885913': 'iso-8859-13', + 'iso-8859-14': 'iso-8859-14', + 'iso8859-14': 'iso-8859-14', + 'iso885914': 'iso-8859-14', + 'csisolatin9': 'iso-8859-15', + 'iso-8859-15': 'iso-8859-15', + 'iso8859-15': 'iso-8859-15', + 'iso885915': 'iso-8859-15', + 'iso_8859-15': 'iso-8859-15', + 'l9': 'iso-8859-15', + 'iso-8859-16': 'iso-8859-16', + 'cskoi8r': 'koi8-r', + 'koi': 'koi8-r', + 'koi8': 'koi8-r', + 'koi8-r': 'koi8-r', + 'koi8_r': 'koi8-r', + 'koi8-u': 'koi8-u', + 'csmacintosh': 'macintosh', + 'mac': 'macintosh', + 'macintosh': 'macintosh', + 'x-mac-roman': 'macintosh', + 'dos-874': 'windows-874', + 'iso-8859-11': 'windows-874', + 'iso8859-11': 'windows-874', + 'iso885911': 'windows-874', + 'tis-620': 'windows-874', + 'windows-874': 'windows-874', + 'cp1250': 'windows-1250', + 'windows-1250': 'windows-1250', + 'x-cp1250': 'windows-1250', + 'cp1251': 'windows-1251', + 'windows-1251': 'windows-1251', + 'x-cp1251': 'windows-1251', + 'ansi_x3.4-1968': 'windows-1252', + 'ascii': 'windows-1252', + 'cp1252': 'windows-1252', + 'cp819': 'windows-1252', + 'csisolatin1': 'windows-1252', + 'ibm819': 'windows-1252', + 'iso-8859-1': 'windows-1252', + 'iso-ir-100': 'windows-1252', + 'iso8859-1': 'windows-1252', + 'iso88591': 'windows-1252', + 'iso_8859-1': 'windows-1252', + 'iso_8859-1:1987': 'windows-1252', + 'l1': 'windows-1252', + 'latin1': 'windows-1252', + 'us-ascii': 'windows-1252', + 'windows-1252': 'windows-1252', + 'x-cp1252': 'windows-1252', + 'cp1253': 'windows-1253', + 'windows-1253': 'windows-1253', + 'x-cp1253': 'windows-1253', + 'cp1254': 'windows-1254', + 'csisolatin5': 'windows-1254', + 'iso-8859-9': 'windows-1254', + 'iso-ir-148': 'windows-1254', + 'iso8859-9': 'windows-1254', + 'iso88599': 'windows-1254', + 'iso_8859-9': 'windows-1254', + 'iso_8859-9:1989': 'windows-1254', + 'l5': 'windows-1254', + 'latin5': 'windows-1254', + 'windows-1254': 'windows-1254', + 'x-cp1254': 'windows-1254', + 'cp1255': 'windows-1255', + 'windows-1255': 'windows-1255', + 'x-cp1255': 'windows-1255', + 'cp1256': 'windows-1256', + 'windows-1256': 'windows-1256', + 'x-cp1256': 'windows-1256', + 'cp1257': 'windows-1257', + 'windows-1257': 'windows-1257', + 'x-cp1257': 'windows-1257', + 'cp1258': 'windows-1258', + 'windows-1258': 'windows-1258', + 'x-cp1258': 'windows-1258', + 'x-mac-cyrillic': 'x-mac-cyrillic', + 'x-mac-ukrainian': 'x-mac-cyrillic', + 'chinese': 'gbk', + 'csgb2312': 'gbk', + 'csiso58gb231280': 'gbk', + 'gb2312': 'gbk', + 'gb_2312': 'gbk', + 'gb_2312-80': 'gbk', + 'gbk': 'gbk', + 'iso-ir-58': 'gbk', + 'x-gbk': 'gbk', + 'gb18030': 'gb18030', + 'hz-gb-2312': 'hz-gb-2312', + 'big5': 'big5', + 'big5-hkscs': 'big5', + 'cn-big5': 'big5', + 'csbig5': 'big5', + 'x-x-big5': 'big5', + 'cseucpkdfmtjapanese': 'euc-jp', + 'euc-jp': 'euc-jp', + 'x-euc-jp': 'euc-jp', + 'csiso2022jp': 'iso-2022-jp', + 'iso-2022-jp': 'iso-2022-jp', + 'csshiftjis': 'shift_jis', + 'ms_kanji': 'shift_jis', + 'shift-jis': 'shift_jis', + 'shift_jis': 'shift_jis', + 'sjis': 'shift_jis', + 'windows-31j': 'shift_jis', + 'x-sjis': 'shift_jis', + 'cseuckr': 'euc-kr', + 'csksc56011987': 'euc-kr', + 'euc-kr': 'euc-kr', + 'iso-ir-149': 'euc-kr', + 'korean': 'euc-kr', + 'ks_c_5601-1987': 'euc-kr', + 'ks_c_5601-1989': 'euc-kr', + 'ksc5601': 'euc-kr', + 'ksc_5601': 'euc-kr', + 'windows-949': 'euc-kr', + 'csiso2022kr': 'iso-2022-kr', + 'iso-2022-kr': 'iso-2022-kr', + 'utf-16be': 'utf-16be', + 'utf-16': 'utf-16le', + 'utf-16le': 'utf-16le', + 'x-user-defined': 'x-user-defined', +} diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py new file mode 100644 index 0000000..295dc92 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/mklabels.py @@ -0,0 +1,59 @@ +""" + + webencodings.mklabels + ~~~~~~~~~~~~~~~~~~~~~ + + Regenarate the webencodings.labels module. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +import json +try: + from urllib import urlopen +except ImportError: + from urllib.request import urlopen + + +def assert_lower(string): + assert string == string.lower() + return string + + +def generate(url): + parts = ['''\ +""" + + webencodings.labels + ~~~~~~~~~~~~~~~~~~~ + + Map encoding labels to their name. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +# XXX Do not edit! +# This file is automatically generated by mklabels.py + +LABELS = { +'''] + labels = [ + (repr(assert_lower(label)).lstrip('u'), + repr(encoding['name']).lstrip('u')) + for category in json.loads(urlopen(url).read().decode('ascii')) + for encoding in category['encodings'] + for label in encoding['labels']] + max_len = max(len(label) for label, name in labels) + parts.extend( + ' %s:%s %s,\n' % (label, ' ' * (max_len - len(label)), name) + for label, name in labels) + parts.append('}') + return ''.join(parts) + + +if __name__ == '__main__': + print(generate('http://encoding.spec.whatwg.org/encodings.json')) diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py new file mode 100644 index 0000000..e12c10d --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/tests.py @@ -0,0 +1,153 @@ +# coding: utf-8 +""" + + webencodings.tests + ~~~~~~~~~~~~~~~~~~ + + A basic test suite for Encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +from . import (lookup, LABELS, decode, encode, iter_decode, iter_encode, + IncrementalDecoder, IncrementalEncoder, UTF8) + + +def assert_raises(exception, function, *args, **kwargs): + try: + function(*args, **kwargs) + except exception: + return + else: # pragma: no cover + raise AssertionError('Did not raise %s.' % exception) + + +def test_labels(): + assert lookup('utf-8').name == 'utf-8' + assert lookup('Utf-8').name == 'utf-8' + assert lookup('UTF-8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8').name == 'utf-8' + assert lookup('utf8 ').name == 'utf-8' + assert lookup(' \r\nutf8\t').name == 'utf-8' + assert lookup('u8') is None # Python label. + assert lookup('utf-8 ') is None # Non-ASCII white space. + + assert lookup('US-ASCII').name == 'windows-1252' + assert lookup('iso-8859-1').name == 'windows-1252' + assert lookup('latin1').name == 'windows-1252' + assert lookup('LATIN1').name == 'windows-1252' + assert lookup('latin-1') is None + assert lookup('LATİN1') is None # ASCII-only case insensitivity. + + +def test_all_labels(): + for label in LABELS: + assert decode(b'', label) == ('', lookup(label)) + assert encode('', label) == b'' + for repeat in [0, 1, 12]: + output, _ = iter_decode([b''] * repeat, label) + assert list(output) == [] + assert list(iter_encode([''] * repeat, label)) == [] + decoder = IncrementalDecoder(label) + assert decoder.decode(b'') == '' + assert decoder.decode(b'', final=True) == '' + encoder = IncrementalEncoder(label) + assert encoder.encode('') == b'' + assert encoder.encode('', final=True) == b'' + # All encoding names are valid labels too: + for name in set(LABELS.values()): + assert lookup(name).name == name + + +def test_invalid_label(): + assert_raises(LookupError, decode, b'\xEF\xBB\xBF\xc3\xa9', 'invalid') + assert_raises(LookupError, encode, 'é', 'invalid') + assert_raises(LookupError, iter_decode, [], 'invalid') + assert_raises(LookupError, iter_encode, [], 'invalid') + assert_raises(LookupError, IncrementalDecoder, 'invalid') + assert_raises(LookupError, IncrementalEncoder, 'invalid') + + +def test_decode(): + assert decode(b'\x80', 'latin1') == ('€', lookup('latin1')) + assert decode(b'\x80', lookup('latin1')) == ('€', lookup('latin1')) + assert decode(b'\xc3\xa9', 'utf8') == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', UTF8) == ('é', lookup('utf8')) + assert decode(b'\xc3\xa9', 'ascii') == ('é', lookup('ascii')) + assert decode(b'\xEF\xBB\xBF\xc3\xa9', 'ascii') == ('é', lookup('utf8')) # UTF-8 with BOM + + assert decode(b'\xFE\xFF\x00\xe9', 'ascii') == ('é', lookup('utf-16be')) # UTF-16-BE with BOM + assert decode(b'\xFF\xFE\xe9\x00', 'ascii') == ('é', lookup('utf-16le')) # UTF-16-LE with BOM + assert decode(b'\xFE\xFF\xe9\x00', 'ascii') == ('\ue900', lookup('utf-16be')) + assert decode(b'\xFF\xFE\x00\xe9', 'ascii') == ('\ue900', lookup('utf-16le')) + + assert decode(b'\x00\xe9', 'UTF-16BE') == ('é', lookup('utf-16be')) + assert decode(b'\xe9\x00', 'UTF-16LE') == ('é', lookup('utf-16le')) + assert decode(b'\xe9\x00', 'UTF-16') == ('é', lookup('utf-16le')) + + assert decode(b'\xe9\x00', 'UTF-16BE') == ('\ue900', lookup('utf-16be')) + assert decode(b'\x00\xe9', 'UTF-16LE') == ('\ue900', lookup('utf-16le')) + assert decode(b'\x00\xe9', 'UTF-16') == ('\ue900', lookup('utf-16le')) + + +def test_encode(): + assert encode('é', 'latin1') == b'\xe9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf8') == b'\xc3\xa9' + assert encode('é', 'utf-16') == b'\xe9\x00' + assert encode('é', 'utf-16le') == b'\xe9\x00' + assert encode('é', 'utf-16be') == b'\x00\xe9' + + +def test_iter_decode(): + def iter_decode_to_string(input, fallback_encoding): + output, _encoding = iter_decode(input, fallback_encoding) + return ''.join(output) + assert iter_decode_to_string([], 'latin1') == '' + assert iter_decode_to_string([b''], 'latin1') == '' + assert iter_decode_to_string([b'\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'hello'], 'latin1') == 'hello' + assert iter_decode_to_string([b'he', b'llo'], 'latin1') == 'hello' + assert iter_decode_to_string([b'hell', b'o'], 'latin1') == 'hello' + assert iter_decode_to_string([b'\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF\xc3\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'\xEF\xBB\xBF', b'a', b'\xc3'], 'latin1') == 'a\uFFFD' + assert iter_decode_to_string([ + b'', b'\xEF', b'', b'', b'\xBB\xBF\xc3', b'\xa9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xEF\xBB\xBF'], 'latin1') == '' + assert iter_decode_to_string([b'\xEF\xBB'], 'latin1') == 'ï»' + assert iter_decode_to_string([b'\xFE\xFF\x00\xe9'], 'latin1') == 'é' + assert iter_decode_to_string([b'\xFF\xFE\xe9\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'\xFF', b'', b'', b'\xFE\xe9', b'\x00'], 'latin1') == 'é' + assert iter_decode_to_string([ + b'', b'h\xe9', b'llo'], 'x-user-defined') == 'h\uF7E9llo' + + +def test_iter_encode(): + assert b''.join(iter_encode([], 'latin1')) == b'' + assert b''.join(iter_encode([''], 'latin1')) == b'' + assert b''.join(iter_encode(['é'], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'latin1')) == b'\xe9' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16le')) == b'\xe9\x00' + assert b''.join(iter_encode(['', 'é', '', ''], 'utf-16be')) == b'\x00\xe9' + assert b''.join(iter_encode([ + '', 'h\uF7E9', '', 'llo'], 'x-user-defined')) == b'h\xe9llo' + + +def test_x_user_defined(): + encoded = b'2,\x0c\x0b\x1aO\xd9#\xcb\x0f\xc9\xbbt\xcf\xa8\xca' + decoded = '2,\x0c\x0b\x1aO\uf7d9#\uf7cb\x0f\uf7c9\uf7bbt\uf7cf\uf7a8\uf7ca' + encoded = b'aa' + decoded = 'aa' + assert decode(encoded, 'x-user-defined') == (decoded, lookup('x-user-defined')) + assert encode(decoded, 'x-user-defined') == encoded diff --git a/env/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py new file mode 100644 index 0000000..d16e326 --- /dev/null +++ b/env/lib/python3.7/site-packages/pip/_vendor/webencodings/x_user_defined.py @@ -0,0 +1,325 @@ +# coding: utf-8 +""" + + webencodings.x_user_defined + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + An implementation of the x-user-defined encoding. + + :copyright: Copyright 2012 by Simon Sapin + :license: BSD, see LICENSE for details. + +""" + +from __future__ import unicode_literals + +import codecs + + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return codecs.charmap_encode(input, errors, encoding_table) + + def decode(self, input, errors='strict'): + return codecs.charmap_decode(input, errors, decoding_table) + + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, encoding_table)[0] + + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, decoding_table)[0] + + +class StreamWriter(Codec, codecs.StreamWriter): + pass + + +class StreamReader(Codec, codecs.StreamReader): + pass + + +### encodings module API + +codec_info = codecs.CodecInfo( + name='x-user-defined', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, +) + + +### Decoding Table + +# Python 3: +# for c in range(256): print(' %r' % chr(c if c < 128 else c + 0xF700)) +decoding_table = ( + '\x00' + '\x01' + '\x02' + '\x03' + '\x04' + '\x05' + '\x06' + '\x07' + '\x08' + '\t' + '\n' + '\x0b' + '\x0c' + '\r' + '\x0e' + '\x0f' + '\x10' + '\x11' + '\x12' + '\x13' + '\x14' + '\x15' + '\x16' + '\x17' + '\x18' + '\x19' + '\x1a' + '\x1b' + '\x1c' + '\x1d' + '\x1e' + '\x1f' + ' ' + '!' + '"' + '#' + '$' + '%' + '&' + "'" + '(' + ')' + '*' + '+' + ',' + '-' + '.' + '/' + '0' + '1' + '2' + '3' + '4' + '5' + '6' + '7' + '8' + '9' + ':' + ';' + '<' + '=' + '>' + '?' + '@' + 'A' + 'B' + 'C' + 'D' + 'E' + 'F' + 'G' + 'H' + 'I' + 'J' + 'K' + 'L' + 'M' + 'N' + 'O' + 'P' + 'Q' + 'R' + 'S' + 'T' + 'U' + 'V' + 'W' + 'X' + 'Y' + 'Z' + '[' + '\\' + ']' + '^' + '_' + '`' + 'a' + 'b' + 'c' + 'd' + 'e' + 'f' + 'g' + 'h' + 'i' + 'j' + 'k' + 'l' + 'm' + 'n' + 'o' + 'p' + 'q' + 'r' + 's' + 't' + 'u' + 'v' + 'w' + 'x' + 'y' + 'z' + '{' + '|' + '}' + '~' + '\x7f' + '\uf780' + '\uf781' + '\uf782' + '\uf783' + '\uf784' + '\uf785' + '\uf786' + '\uf787' + '\uf788' + '\uf789' + '\uf78a' + '\uf78b' + '\uf78c' + '\uf78d' + '\uf78e' + '\uf78f' + '\uf790' + '\uf791' + '\uf792' + '\uf793' + '\uf794' + '\uf795' + '\uf796' + '\uf797' + '\uf798' + '\uf799' + '\uf79a' + '\uf79b' + '\uf79c' + '\uf79d' + '\uf79e' + '\uf79f' + '\uf7a0' + '\uf7a1' + '\uf7a2' + '\uf7a3' + '\uf7a4' + '\uf7a5' + '\uf7a6' + '\uf7a7' + '\uf7a8' + '\uf7a9' + '\uf7aa' + '\uf7ab' + '\uf7ac' + '\uf7ad' + '\uf7ae' + '\uf7af' + '\uf7b0' + '\uf7b1' + '\uf7b2' + '\uf7b3' + '\uf7b4' + '\uf7b5' + '\uf7b6' + '\uf7b7' + '\uf7b8' + '\uf7b9' + '\uf7ba' + '\uf7bb' + '\uf7bc' + '\uf7bd' + '\uf7be' + '\uf7bf' + '\uf7c0' + '\uf7c1' + '\uf7c2' + '\uf7c3' + '\uf7c4' + '\uf7c5' + '\uf7c6' + '\uf7c7' + '\uf7c8' + '\uf7c9' + '\uf7ca' + '\uf7cb' + '\uf7cc' + '\uf7cd' + '\uf7ce' + '\uf7cf' + '\uf7d0' + '\uf7d1' + '\uf7d2' + '\uf7d3' + '\uf7d4' + '\uf7d5' + '\uf7d6' + '\uf7d7' + '\uf7d8' + '\uf7d9' + '\uf7da' + '\uf7db' + '\uf7dc' + '\uf7dd' + '\uf7de' + '\uf7df' + '\uf7e0' + '\uf7e1' + '\uf7e2' + '\uf7e3' + '\uf7e4' + '\uf7e5' + '\uf7e6' + '\uf7e7' + '\uf7e8' + '\uf7e9' + '\uf7ea' + '\uf7eb' + '\uf7ec' + '\uf7ed' + '\uf7ee' + '\uf7ef' + '\uf7f0' + '\uf7f1' + '\uf7f2' + '\uf7f3' + '\uf7f4' + '\uf7f5' + '\uf7f6' + '\uf7f7' + '\uf7f8' + '\uf7f9' + '\uf7fa' + '\uf7fb' + '\uf7fc' + '\uf7fd' + '\uf7fe' + '\uf7ff' +) + +### Encoding table +encoding_table = codecs.charmap_build(decoding_table) diff --git a/env/lib/python3.7/site-packages/pkg_resources/__init__.py b/env/lib/python3.7/site-packages/pkg_resources/__init__.py new file mode 100644 index 0000000..6ca68da --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/__init__.py @@ -0,0 +1,3171 @@ +# coding: utf-8 +""" +Package resource API +-------------------- + +A resource is a logical file contained within a package, or a logical +subdirectory thereof. The package resource API expects resource names +to have their path parts separated with ``/``, *not* whatever the local +path separator is. Do not use os.path operations to manipulate resource +names being passed into the API. + +The package resource API is designed to work with normal filesystem packages, +.egg files, and unpacked .egg files. It can also work in a limited way with +.zip files and with custom PEP 302 loaders that support the ``get_data()`` +method. +""" + +from __future__ import absolute_import + +import sys +import os +import io +import time +import re +import types +import zipfile +import zipimport +import warnings +import stat +import functools +import pkgutil +import operator +import platform +import collections +import plistlib +import email.parser +import errno +import tempfile +import textwrap +import itertools +import inspect +from pkgutil import get_importer + +try: + import _imp +except ImportError: + # Python 3.2 compatibility + import imp as _imp + +try: + FileExistsError +except NameError: + FileExistsError = OSError + +from pkg_resources.extern import six +from pkg_resources.extern.six.moves import urllib, map, filter + +# capture these to bypass sandboxing +from os import utime +try: + from os import mkdir, rename, unlink + WRITE_SUPPORT = True +except ImportError: + # no write support, probably under GAE + WRITE_SUPPORT = False + +from os import open as os_open +from os.path import isdir, split + +try: + import importlib.machinery as importlib_machinery + # access attribute to force import under delayed import mechanisms. + importlib_machinery.__name__ +except ImportError: + importlib_machinery = None + +from . import py31compat +from pkg_resources.extern import appdirs +from pkg_resources.extern import packaging +__import__('pkg_resources.extern.packaging.version') +__import__('pkg_resources.extern.packaging.specifiers') +__import__('pkg_resources.extern.packaging.requirements') +__import__('pkg_resources.extern.packaging.markers') + + +__metaclass__ = type + + +if (3, 0) < sys.version_info < (3, 4): + raise RuntimeError("Python 3.4 or later is required") + +if six.PY2: + # Those builtin exceptions are only defined in Python 3 + PermissionError = None + NotADirectoryError = None + +# declare some globals that will be defined later to +# satisfy the linters. +require = None +working_set = None +add_activation_listener = None +resources_stream = None +cleanup_resources = None +resource_dir = None +resource_stream = None +set_extraction_path = None +resource_isdir = None +resource_string = None +iter_entry_points = None +resource_listdir = None +resource_filename = None +resource_exists = None +_distribution_finders = None +_namespace_handlers = None +_namespace_packages = None + + +class PEP440Warning(RuntimeWarning): + """ + Used when there is an issue with a version or specifier not complying with + PEP 440. + """ + + +def parse_version(v): + try: + return packaging.version.Version(v) + except packaging.version.InvalidVersion: + return packaging.version.LegacyVersion(v) + + +_state_vars = {} + + +def _declare_state(vartype, **kw): + globals().update(kw) + _state_vars.update(dict.fromkeys(kw, vartype)) + + +def __getstate__(): + state = {} + g = globals() + for k, v in _state_vars.items(): + state[k] = g['_sget_' + v](g[k]) + return state + + +def __setstate__(state): + g = globals() + for k, v in state.items(): + g['_sset_' + _state_vars[k]](k, g[k], v) + return state + + +def _sget_dict(val): + return val.copy() + + +def _sset_dict(key, ob, state): + ob.clear() + ob.update(state) + + +def _sget_object(val): + return val.__getstate__() + + +def _sset_object(key, ob, state): + ob.__setstate__(state) + + +_sget_none = _sset_none = lambda *args: None + + +def get_supported_platform(): + """Return this platform's maximum compatible version. + + distutils.util.get_platform() normally reports the minimum version + of Mac OS X that would be required to *use* extensions produced by + distutils. But what we want when checking compatibility is to know the + version of Mac OS X that we are *running*. To allow usage of packages that + explicitly require a newer version of Mac OS X, we must also know the + current version of the OS. + + If this condition occurs for any other platform with a version in its + platform strings, this function should be extended accordingly. + """ + plat = get_build_platform() + m = macosVersionString.match(plat) + if m is not None and sys.platform == "darwin": + try: + plat = 'macosx-%s-%s' % ('.'.join(_macosx_vers()[:2]), m.group(3)) + except ValueError: + # not Mac OS X + pass + return plat + + +__all__ = [ + # Basic resource access and distribution/entry point discovery + 'require', 'run_script', 'get_provider', 'get_distribution', + 'load_entry_point', 'get_entry_map', 'get_entry_info', + 'iter_entry_points', + 'resource_string', 'resource_stream', 'resource_filename', + 'resource_listdir', 'resource_exists', 'resource_isdir', + + # Environmental control + 'declare_namespace', 'working_set', 'add_activation_listener', + 'find_distributions', 'set_extraction_path', 'cleanup_resources', + 'get_default_cache', + + # Primary implementation classes + 'Environment', 'WorkingSet', 'ResourceManager', + 'Distribution', 'Requirement', 'EntryPoint', + + # Exceptions + 'ResolutionError', 'VersionConflict', 'DistributionNotFound', + 'UnknownExtra', 'ExtractionError', + + # Warnings + 'PEP440Warning', + + # Parsing functions and string utilities + 'parse_requirements', 'parse_version', 'safe_name', 'safe_version', + 'get_platform', 'compatible_platforms', 'yield_lines', 'split_sections', + 'safe_extra', 'to_filename', 'invalid_marker', 'evaluate_marker', + + # filesystem utilities + 'ensure_directory', 'normalize_path', + + # Distribution "precedence" constants + 'EGG_DIST', 'BINARY_DIST', 'SOURCE_DIST', 'CHECKOUT_DIST', 'DEVELOP_DIST', + + # "Provider" interfaces, implementations, and registration/lookup APIs + 'IMetadataProvider', 'IResourceProvider', 'FileMetadata', + 'PathMetadata', 'EggMetadata', 'EmptyProvider', 'empty_provider', + 'NullProvider', 'EggProvider', 'DefaultProvider', 'ZipProvider', + 'register_finder', 'register_namespace_handler', 'register_loader_type', + 'fixup_namespace_packages', 'get_importer', + + # Warnings + 'PkgResourcesDeprecationWarning', + + # Deprecated/backward compatibility only + 'run_main', 'AvailableDistributions', +] + + +class ResolutionError(Exception): + """Abstract base for dependency resolution errors""" + + def __repr__(self): + return self.__class__.__name__ + repr(self.args) + + +class VersionConflict(ResolutionError): + """ + An already-installed version conflicts with the requested version. + + Should be initialized with the installed Distribution and the requested + Requirement. + """ + + _template = "{self.dist} is installed but {self.req} is required" + + @property + def dist(self): + return self.args[0] + + @property + def req(self): + return self.args[1] + + def report(self): + return self._template.format(**locals()) + + def with_context(self, required_by): + """ + If required_by is non-empty, return a version of self that is a + ContextualVersionConflict. + """ + if not required_by: + return self + args = self.args + (required_by,) + return ContextualVersionConflict(*args) + + +class ContextualVersionConflict(VersionConflict): + """ + A VersionConflict that accepts a third parameter, the set of the + requirements that required the installed Distribution. + """ + + _template = VersionConflict._template + ' by {self.required_by}' + + @property + def required_by(self): + return self.args[2] + + +class DistributionNotFound(ResolutionError): + """A requested distribution was not found""" + + _template = ("The '{self.req}' distribution was not found " + "and is required by {self.requirers_str}") + + @property + def req(self): + return self.args[0] + + @property + def requirers(self): + return self.args[1] + + @property + def requirers_str(self): + if not self.requirers: + return 'the application' + return ', '.join(self.requirers) + + def report(self): + return self._template.format(**locals()) + + def __str__(self): + return self.report() + + +class UnknownExtra(ResolutionError): + """Distribution doesn't have an "extra feature" of the given name""" + + +_provider_factories = {} + +PY_MAJOR = sys.version[:3] +EGG_DIST = 3 +BINARY_DIST = 2 +SOURCE_DIST = 1 +CHECKOUT_DIST = 0 +DEVELOP_DIST = -1 + + +def register_loader_type(loader_type, provider_factory): + """Register `provider_factory` to make providers for `loader_type` + + `loader_type` is the type or class of a PEP 302 ``module.__loader__``, + and `provider_factory` is a function that, passed a *module* object, + returns an ``IResourceProvider`` for that module. + """ + _provider_factories[loader_type] = provider_factory + + +def get_provider(moduleOrReq): + """Return an IResourceProvider for the named module or requirement""" + if isinstance(moduleOrReq, Requirement): + return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] + try: + module = sys.modules[moduleOrReq] + except KeyError: + __import__(moduleOrReq) + module = sys.modules[moduleOrReq] + loader = getattr(module, '__loader__', None) + return _find_adapter(_provider_factories, loader)(module) + + +def _macosx_vers(_cache=[]): + if not _cache: + version = platform.mac_ver()[0] + # fallback for MacPorts + if version == '': + plist = '/System/Library/CoreServices/SystemVersion.plist' + if os.path.exists(plist): + if hasattr(plistlib, 'readPlist'): + plist_content = plistlib.readPlist(plist) + if 'ProductVersion' in plist_content: + version = plist_content['ProductVersion'] + + _cache.append(version.split('.')) + return _cache[0] + + +def _macosx_arch(machine): + return {'PowerPC': 'ppc', 'Power_Macintosh': 'ppc'}.get(machine, machine) + + +def get_build_platform(): + """Return this platform's string for platform-specific distributions + + XXX Currently this is the same as ``distutils.util.get_platform()``, but it + needs some hacks for Linux and Mac OS X. + """ + from sysconfig import get_platform + + plat = get_platform() + if sys.platform == "darwin" and not plat.startswith('macosx-'): + try: + version = _macosx_vers() + machine = os.uname()[4].replace(" ", "_") + return "macosx-%d.%d-%s" % ( + int(version[0]), int(version[1]), + _macosx_arch(machine), + ) + except ValueError: + # if someone is running a non-Mac darwin system, this will fall + # through to the default implementation + pass + return plat + + +macosVersionString = re.compile(r"macosx-(\d+)\.(\d+)-(.*)") +darwinVersionString = re.compile(r"darwin-(\d+)\.(\d+)\.(\d+)-(.*)") +# XXX backward compat +get_platform = get_build_platform + + +def compatible_platforms(provided, required): + """Can code for the `provided` platform run on the `required` platform? + + Returns true if either platform is ``None``, or the platforms are equal. + + XXX Needs compatibility checks for Linux and other unixy OSes. + """ + if provided is None or required is None or provided == required: + # easy case + return True + + # Mac OS X special cases + reqMac = macosVersionString.match(required) + if reqMac: + provMac = macosVersionString.match(provided) + + # is this a Mac package? + if not provMac: + # this is backwards compatibility for packages built before + # setuptools 0.6. All packages built after this point will + # use the new macosx designation. + provDarwin = darwinVersionString.match(provided) + if provDarwin: + dversion = int(provDarwin.group(1)) + macosversion = "%s.%s" % (reqMac.group(1), reqMac.group(2)) + if dversion == 7 and macosversion >= "10.3" or \ + dversion == 8 and macosversion >= "10.4": + return True + # egg isn't macosx or legacy darwin + return False + + # are they the same major version and machine type? + if provMac.group(1) != reqMac.group(1) or \ + provMac.group(3) != reqMac.group(3): + return False + + # is the required OS major update >= the provided one? + if int(provMac.group(2)) > int(reqMac.group(2)): + return False + + return True + + # XXX Linux and other platforms' special cases should go here + return False + + +def run_script(dist_spec, script_name): + """Locate distribution `dist_spec` and run its `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + require(dist_spec)[0].run_script(script_name, ns) + + +# backward compatibility +run_main = run_script + + +def get_distribution(dist): + """Return a current distribution object for a Requirement or string""" + if isinstance(dist, six.string_types): + dist = Requirement.parse(dist) + if isinstance(dist, Requirement): + dist = get_provider(dist) + if not isinstance(dist, Distribution): + raise TypeError("Expected string, Requirement, or Distribution", dist) + return dist + + +def load_entry_point(dist, group, name): + """Return `name` entry point of `group` for `dist` or raise ImportError""" + return get_distribution(dist).load_entry_point(group, name) + + +def get_entry_map(dist, group=None): + """Return the entry point map for `group`, or the full entry map""" + return get_distribution(dist).get_entry_map(group) + + +def get_entry_info(dist, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return get_distribution(dist).get_entry_info(group, name) + + +class IMetadataProvider: + def has_metadata(name): + """Does the package's distribution contain the named metadata?""" + + def get_metadata(name): + """The named metadata resource as a string""" + + def get_metadata_lines(name): + """Yield named metadata resource as list of non-blank non-comment lines + + Leading and trailing whitespace is stripped from each line, and lines + with ``#`` as the first non-blank character are omitted.""" + + def metadata_isdir(name): + """Is the named metadata a directory? (like ``os.path.isdir()``)""" + + def metadata_listdir(name): + """List of metadata names in the directory (like ``os.listdir()``)""" + + def run_script(script_name, namespace): + """Execute the named script in the supplied namespace dictionary""" + + +class IResourceProvider(IMetadataProvider): + """An object that provides access to package resources""" + + def get_resource_filename(manager, resource_name): + """Return a true filesystem path for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_stream(manager, resource_name): + """Return a readable file-like object for `resource_name` + + `manager` must be an ``IResourceManager``""" + + def get_resource_string(manager, resource_name): + """Return a string containing the contents of `resource_name` + + `manager` must be an ``IResourceManager``""" + + def has_resource(resource_name): + """Does the package contain the named resource?""" + + def resource_isdir(resource_name): + """Is the named resource a directory? (like ``os.path.isdir()``)""" + + def resource_listdir(resource_name): + """List of resource names in the directory (like ``os.listdir()``)""" + + +class WorkingSet: + """A collection of active distributions on sys.path (or a similar list)""" + + def __init__(self, entries=None): + """Create working set from list of path entries (default=sys.path)""" + self.entries = [] + self.entry_keys = {} + self.by_key = {} + self.callbacks = [] + + if entries is None: + entries = sys.path + + for entry in entries: + self.add_entry(entry) + + @classmethod + def _build_master(cls): + """ + Prepare the master working set. + """ + ws = cls() + try: + from __main__ import __requires__ + except ImportError: + # The main program does not list any requirements + return ws + + # ensure the requirements are met + try: + ws.require(__requires__) + except VersionConflict: + return cls._build_from_requirements(__requires__) + + return ws + + @classmethod + def _build_from_requirements(cls, req_spec): + """ + Build a working set from a requirement spec. Rewrites sys.path. + """ + # try it without defaults already on sys.path + # by starting with an empty path + ws = cls([]) + reqs = parse_requirements(req_spec) + dists = ws.resolve(reqs, Environment()) + for dist in dists: + ws.add(dist) + + # add any missing entries from sys.path + for entry in sys.path: + if entry not in ws.entries: + ws.add_entry(entry) + + # then copy back to sys.path + sys.path[:] = ws.entries + return ws + + def add_entry(self, entry): + """Add a path item to ``.entries``, finding any distributions on it + + ``find_distributions(entry, True)`` is used to find distributions + corresponding to the path entry, and they are added. `entry` is + always appended to ``.entries``, even if it is already present. + (This is because ``sys.path`` can contain the same value more than + once, and the ``.entries`` of the ``sys.path`` WorkingSet should always + equal ``sys.path``.) + """ + self.entry_keys.setdefault(entry, []) + self.entries.append(entry) + for dist in find_distributions(entry, True): + self.add(dist, entry, False) + + def __contains__(self, dist): + """True if `dist` is the active distribution for its project""" + return self.by_key.get(dist.key) == dist + + def find(self, req): + """Find a distribution matching requirement `req` + + If there is an active distribution for the requested project, this + returns it as long as it meets the version requirement specified by + `req`. But, if there is an active distribution for the project and it + does *not* meet the `req` requirement, ``VersionConflict`` is raised. + If there is no active distribution for the requested project, ``None`` + is returned. + """ + dist = self.by_key.get(req.key) + if dist is not None and dist not in req: + # XXX add more info + raise VersionConflict(dist, req) + return dist + + def iter_entry_points(self, group, name=None): + """Yield entry point objects from `group` matching `name` + + If `name` is None, yields all entry points in `group` from all + distributions in the working set, otherwise only ones matching + both `group` and `name` are yielded (in distribution order). + """ + return ( + entry + for dist in self + for entry in dist.get_entry_map(group).values() + if name is None or name == entry.name + ) + + def run_script(self, requires, script_name): + """Locate distribution for `requires` and run `script_name` script""" + ns = sys._getframe(1).f_globals + name = ns['__name__'] + ns.clear() + ns['__name__'] = name + self.require(requires)[0].run_script(script_name, ns) + + def __iter__(self): + """Yield distributions for non-duplicate projects in the working set + + The yield order is the order in which the items' path entries were + added to the working set. + """ + seen = {} + for item in self.entries: + if item not in self.entry_keys: + # workaround a cache issue + continue + + for key in self.entry_keys[item]: + if key not in seen: + seen[key] = 1 + yield self.by_key[key] + + def add(self, dist, entry=None, insert=True, replace=False): + """Add `dist` to working set, associated with `entry` + + If `entry` is unspecified, it defaults to the ``.location`` of `dist`. + On exit from this routine, `entry` is added to the end of the working + set's ``.entries`` (if it wasn't already present). + + `dist` is only added to the working set if it's for a project that + doesn't already have a distribution in the set, unless `replace=True`. + If it's added, any callbacks registered with the ``subscribe()`` method + will be called. + """ + if insert: + dist.insert_on(self.entries, entry, replace=replace) + + if entry is None: + entry = dist.location + keys = self.entry_keys.setdefault(entry, []) + keys2 = self.entry_keys.setdefault(dist.location, []) + if not replace and dist.key in self.by_key: + # ignore hidden distros + return + + self.by_key[dist.key] = dist + if dist.key not in keys: + keys.append(dist.key) + if dist.key not in keys2: + keys2.append(dist.key) + self._added_new(dist) + + def resolve(self, requirements, env=None, installer=None, + replace_conflicting=False, extras=None): + """List all distributions needed to (recursively) meet `requirements` + + `requirements` must be a sequence of ``Requirement`` objects. `env`, + if supplied, should be an ``Environment`` instance. If + not supplied, it defaults to all distributions available within any + entry or distribution in the working set. `installer`, if supplied, + will be invoked with each requirement that cannot be met by an + already-installed distribution; it should return a ``Distribution`` or + ``None``. + + Unless `replace_conflicting=True`, raises a VersionConflict exception + if + any requirements are found on the path that have the correct name but + the wrong version. Otherwise, if an `installer` is supplied it will be + invoked to obtain the correct version of the requirement and activate + it. + + `extras` is a list of the extras to be used with these requirements. + This is important because extra requirements may look like `my_req; + extra = "my_extra"`, which would otherwise be interpreted as a purely + optional requirement. Instead, we want to be able to assert that these + requirements are truly required. + """ + + # set up the stack + requirements = list(requirements)[::-1] + # set of processed requirements + processed = {} + # key -> dist + best = {} + to_activate = [] + + req_extras = _ReqExtras() + + # Mapping of requirement to set of distributions that required it; + # useful for reporting info about conflicts. + required_by = collections.defaultdict(set) + + while requirements: + # process dependencies breadth-first + req = requirements.pop(0) + if req in processed: + # Ignore cyclic or redundant dependencies + continue + + if not req_extras.markers_pass(req, extras): + continue + + dist = best.get(req.key) + if dist is None: + # Find the best distribution and add it to the map + dist = self.by_key.get(req.key) + if dist is None or (dist not in req and replace_conflicting): + ws = self + if env is None: + if dist is None: + env = Environment(self.entries) + else: + # Use an empty environment and workingset to avoid + # any further conflicts with the conflicting + # distribution + env = Environment([]) + ws = WorkingSet([]) + dist = best[req.key] = env.best_match( + req, ws, installer, + replace_conflicting=replace_conflicting + ) + if dist is None: + requirers = required_by.get(req, None) + raise DistributionNotFound(req, requirers) + to_activate.append(dist) + if dist not in req: + # Oops, the "best" so far conflicts with a dependency + dependent_req = required_by[req] + raise VersionConflict(dist, req).with_context(dependent_req) + + # push the new requirements onto the stack + new_requirements = dist.requires(req.extras)[::-1] + requirements.extend(new_requirements) + + # Register the new requirements needed by req + for new_requirement in new_requirements: + required_by[new_requirement].add(req.project_name) + req_extras[new_requirement] = req.extras + + processed[req] = True + + # return list of distros to activate + return to_activate + + def find_plugins( + self, plugin_env, full_env=None, installer=None, fallback=True): + """Find all activatable distributions in `plugin_env` + + Example usage:: + + distributions, errors = working_set.find_plugins( + Environment(plugin_dirlist) + ) + # add plugins+libs to sys.path + map(working_set.add, distributions) + # display errors + print('Could not load', errors) + + The `plugin_env` should be an ``Environment`` instance that contains + only distributions that are in the project's "plugin directory" or + directories. The `full_env`, if supplied, should be an ``Environment`` + contains all currently-available distributions. If `full_env` is not + supplied, one is created automatically from the ``WorkingSet`` this + method is called on, which will typically mean that every directory on + ``sys.path`` will be scanned for distributions. + + `installer` is a standard installer callback as used by the + ``resolve()`` method. The `fallback` flag indicates whether we should + attempt to resolve older versions of a plugin if the newest version + cannot be resolved. + + This method returns a 2-tuple: (`distributions`, `error_info`), where + `distributions` is a list of the distributions found in `plugin_env` + that were loadable, along with any other distributions that are needed + to resolve their dependencies. `error_info` is a dictionary mapping + unloadable plugin distributions to an exception instance describing the + error that occurred. Usually this will be a ``DistributionNotFound`` or + ``VersionConflict`` instance. + """ + + plugin_projects = list(plugin_env) + # scan project names in alphabetic order + plugin_projects.sort() + + error_info = {} + distributions = {} + + if full_env is None: + env = Environment(self.entries) + env += plugin_env + else: + env = full_env + plugin_env + + shadow_set = self.__class__([]) + # put all our entries in shadow_set + list(map(shadow_set.add, self)) + + for project_name in plugin_projects: + + for dist in plugin_env[project_name]: + + req = [dist.as_requirement()] + + try: + resolvees = shadow_set.resolve(req, env, installer) + + except ResolutionError as v: + # save error info + error_info[dist] = v + if fallback: + # try the next older version of project + continue + else: + # give up on this project, keep going + break + + else: + list(map(shadow_set.add, resolvees)) + distributions.update(dict.fromkeys(resolvees)) + + # success, no need to try any more versions of this project + break + + distributions = list(distributions) + distributions.sort() + + return distributions, error_info + + def require(self, *requirements): + """Ensure that distributions matching `requirements` are activated + + `requirements` must be a string or a (possibly-nested) sequence + thereof, specifying the distributions and versions required. The + return value is a sequence of the distributions that needed to be + activated to fulfill the requirements; all relevant distributions are + included, even if they were already activated in this working set. + """ + needed = self.resolve(parse_requirements(requirements)) + + for dist in needed: + self.add(dist) + + return needed + + def subscribe(self, callback, existing=True): + """Invoke `callback` for all distributions + + If `existing=True` (default), + call on all existing ones, as well. + """ + if callback in self.callbacks: + return + self.callbacks.append(callback) + if not existing: + return + for dist in self: + callback(dist) + + def _added_new(self, dist): + for callback in self.callbacks: + callback(dist) + + def __getstate__(self): + return ( + self.entries[:], self.entry_keys.copy(), self.by_key.copy(), + self.callbacks[:] + ) + + def __setstate__(self, e_k_b_c): + entries, keys, by_key, callbacks = e_k_b_c + self.entries = entries[:] + self.entry_keys = keys.copy() + self.by_key = by_key.copy() + self.callbacks = callbacks[:] + + +class _ReqExtras(dict): + """ + Map each requirement to the extras that demanded it. + """ + + def markers_pass(self, req, extras=None): + """ + Evaluate markers for req against each extra that + demanded it. + + Return False if the req has a marker and fails + evaluation. Otherwise, return True. + """ + extra_evals = ( + req.marker.evaluate({'extra': extra}) + for extra in self.get(req, ()) + (extras or (None,)) + ) + return not req.marker or any(extra_evals) + + +class Environment: + """Searchable snapshot of distributions on a search path""" + + def __init__( + self, search_path=None, platform=get_supported_platform(), + python=PY_MAJOR): + """Snapshot distributions available on a search path + + Any distributions found on `search_path` are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. + + `platform` is an optional string specifying the name of the platform + that platform-specific distributions must be compatible with. If + unspecified, it defaults to the current platform. `python` is an + optional string naming the desired version of Python (e.g. ``'3.6'``); + it defaults to the current version. + + You may explicitly set `platform` (and/or `python`) to ``None`` if you + wish to map *all* distributions, not just those compatible with the + running platform or Python version. + """ + self._distmap = {} + self.platform = platform + self.python = python + self.scan(search_path) + + def can_add(self, dist): + """Is distribution `dist` acceptable for this environment? + + The distribution must match the platform and python version + requirements specified when this environment was created, or False + is returned. + """ + py_compat = ( + self.python is None + or dist.py_version is None + or dist.py_version == self.python + ) + return py_compat and compatible_platforms(dist.platform, self.platform) + + def remove(self, dist): + """Remove `dist` from the environment""" + self._distmap[dist.key].remove(dist) + + def scan(self, search_path=None): + """Scan `search_path` for distributions usable in this environment + + Any distributions found are added to the environment. + `search_path` should be a sequence of ``sys.path`` items. If not + supplied, ``sys.path`` is used. Only distributions conforming to + the platform/python version defined at initialization are added. + """ + if search_path is None: + search_path = sys.path + + for item in search_path: + for dist in find_distributions(item): + self.add(dist) + + def __getitem__(self, project_name): + """Return a newest-to-oldest list of distributions for `project_name` + + Uses case-insensitive `project_name` comparison, assuming all the + project's distributions use their project's name converted to all + lowercase as their key. + + """ + distribution_key = project_name.lower() + return self._distmap.get(distribution_key, []) + + def add(self, dist): + """Add `dist` if we ``can_add()`` it and it has not already been added + """ + if self.can_add(dist) and dist.has_version(): + dists = self._distmap.setdefault(dist.key, []) + if dist not in dists: + dists.append(dist) + dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) + + def best_match( + self, req, working_set, installer=None, replace_conflicting=False): + """Find distribution best matching `req` and usable on `working_set` + + This calls the ``find(req)`` method of the `working_set` to see if a + suitable distribution is already active. (This may raise + ``VersionConflict`` if an unsuitable version of the project is already + active in the specified `working_set`.) If a suitable distribution + isn't active, this method returns the newest distribution in the + environment that meets the ``Requirement`` in `req`. If no suitable + distribution is found, and `installer` is supplied, then the result of + calling the environment's ``obtain(req, installer)`` method will be + returned. + """ + try: + dist = working_set.find(req) + except VersionConflict: + if not replace_conflicting: + raise + dist = None + if dist is not None: + return dist + for dist in self[req.key]: + if dist in req: + return dist + # try to download/install + return self.obtain(req, installer) + + def obtain(self, requirement, installer=None): + """Obtain a distribution matching `requirement` (e.g. via download) + + Obtain a distro that matches requirement (e.g. via download). In the + base ``Environment`` class, this routine just returns + ``installer(requirement)``, unless `installer` is None, in which case + None is returned instead. This method is a hook that allows subclasses + to attempt other ways of obtaining a distribution before falling back + to the `installer` argument.""" + if installer is not None: + return installer(requirement) + + def __iter__(self): + """Yield the unique project names of the available distributions""" + for key in self._distmap.keys(): + if self[key]: + yield key + + def __iadd__(self, other): + """In-place addition of a distribution or environment""" + if isinstance(other, Distribution): + self.add(other) + elif isinstance(other, Environment): + for project in other: + for dist in other[project]: + self.add(dist) + else: + raise TypeError("Can't add %r to environment" % (other,)) + return self + + def __add__(self, other): + """Add an environment or distribution to an environment""" + new = self.__class__([], platform=None, python=None) + for env in self, other: + new += env + return new + + +# XXX backward compatibility +AvailableDistributions = Environment + + +class ExtractionError(RuntimeError): + """An error occurred extracting a resource + + The following attributes are available from instances of this exception: + + manager + The resource manager that raised this exception + + cache_path + The base directory for resource extraction + + original_error + The exception instance that caused extraction to fail + """ + + +class ResourceManager: + """Manage resource extraction and packages""" + extraction_path = None + + def __init__(self): + self.cached_files = {} + + def resource_exists(self, package_or_requirement, resource_name): + """Does the named resource exist?""" + return get_provider(package_or_requirement).has_resource(resource_name) + + def resource_isdir(self, package_or_requirement, resource_name): + """Is the named resource an existing directory?""" + return get_provider(package_or_requirement).resource_isdir( + resource_name + ) + + def resource_filename(self, package_or_requirement, resource_name): + """Return a true filesystem path for specified resource""" + return get_provider(package_or_requirement).get_resource_filename( + self, resource_name + ) + + def resource_stream(self, package_or_requirement, resource_name): + """Return a readable file-like object for specified resource""" + return get_provider(package_or_requirement).get_resource_stream( + self, resource_name + ) + + def resource_string(self, package_or_requirement, resource_name): + """Return specified resource as a string""" + return get_provider(package_or_requirement).get_resource_string( + self, resource_name + ) + + def resource_listdir(self, package_or_requirement, resource_name): + """List the contents of the named resource directory""" + return get_provider(package_or_requirement).resource_listdir( + resource_name + ) + + def extraction_error(self): + """Give an error message for problems extracting file(s)""" + + old_exc = sys.exc_info()[1] + cache_path = self.extraction_path or get_default_cache() + + tmpl = textwrap.dedent(""" + Can't extract file(s) to egg cache + + The following error occurred while trying to extract file(s) + to the Python egg cache: + + {old_exc} + + The Python egg cache directory is currently set to: + + {cache_path} + + Perhaps your account does not have write access to this directory? + You can change the cache directory by setting the PYTHON_EGG_CACHE + environment variable to point to an accessible directory. + """).lstrip() + err = ExtractionError(tmpl.format(**locals())) + err.manager = self + err.cache_path = cache_path + err.original_error = old_exc + raise err + + def get_cache_path(self, archive_name, names=()): + """Return absolute location in cache for `archive_name` and `names` + + The parent directory of the resulting path will be created if it does + not already exist. `archive_name` should be the base filename of the + enclosing egg (which may not be the name of the enclosing zipfile!), + including its ".egg" extension. `names`, if provided, should be a + sequence of path name parts "under" the egg's extraction location. + + This method should only be called by resource providers that need to + obtain an extraction location, and only for names they intend to + extract, as it tracks the generated names for possible cleanup later. + """ + extract_path = self.extraction_path or get_default_cache() + target_path = os.path.join(extract_path, archive_name + '-tmp', *names) + try: + _bypass_ensure_directory(target_path) + except Exception: + self.extraction_error() + + self._warn_unsafe_extraction_path(extract_path) + + self.cached_files[target_path] = 1 + return target_path + + @staticmethod + def _warn_unsafe_extraction_path(path): + """ + If the default extraction path is overridden and set to an insecure + location, such as /tmp, it opens up an opportunity for an attacker to + replace an extracted file with an unauthorized payload. Warn the user + if a known insecure location is used. + + See Distribute #375 for more details. + """ + if os.name == 'nt' and not path.startswith(os.environ['windir']): + # On Windows, permissions are generally restrictive by default + # and temp directories are not writable by other users, so + # bypass the warning. + return + mode = os.stat(path).st_mode + if mode & stat.S_IWOTH or mode & stat.S_IWGRP: + msg = ( + "%s is writable by group/others and vulnerable to attack " + "when " + "used with get_resource_filename. Consider a more secure " + "location (set with .set_extraction_path or the " + "PYTHON_EGG_CACHE environment variable)." % path + ) + warnings.warn(msg, UserWarning) + + def postprocess(self, tempname, filename): + """Perform any platform-specific postprocessing of `tempname` + + This is where Mac header rewrites should be done; other platforms don't + have anything special they should do. + + Resource providers should call this method ONLY after successfully + extracting a compressed resource. They must NOT call it on resources + that are already in the filesystem. + + `tempname` is the current (temporary) name of the file, and `filename` + is the name it will be renamed to by the caller after this routine + returns. + """ + + if os.name == 'posix': + # Make the resource executable + mode = ((os.stat(tempname).st_mode) | 0o555) & 0o7777 + os.chmod(tempname, mode) + + def set_extraction_path(self, path): + """Set the base path where resources will be extracted to, if needed. + + If you do not call this routine before any extractions take place, the + path defaults to the return value of ``get_default_cache()``. (Which + is based on the ``PYTHON_EGG_CACHE`` environment variable, with various + platform-specific fallbacks. See that routine's documentation for more + details.) + + Resources are extracted to subdirectories of this path based upon + information given by the ``IResourceProvider``. You may set this to a + temporary directory, but then you must call ``cleanup_resources()`` to + delete the extracted files when done. There is no guarantee that + ``cleanup_resources()`` will be able to remove all extracted files. + + (Note: you may not change the extraction path for a given resource + manager once resources have been extracted, unless you first call + ``cleanup_resources()``.) + """ + if self.cached_files: + raise ValueError( + "Can't change extraction path, files already extracted" + ) + + self.extraction_path = path + + def cleanup_resources(self, force=False): + """ + Delete all extracted resource files and directories, returning a list + of the file and directory names that could not be successfully removed. + This function does not have any concurrency protection, so it should + generally only be called when the extraction path is a temporary + directory exclusive to a single process. This method is not + automatically called; you must call it explicitly or register it as an + ``atexit`` function if you wish to ensure cleanup of a temporary + directory used for extractions. + """ + # XXX + + +def get_default_cache(): + """ + Return the ``PYTHON_EGG_CACHE`` environment variable + or a platform-relevant user cache dir for an app + named "Python-Eggs". + """ + return ( + os.environ.get('PYTHON_EGG_CACHE') + or appdirs.user_cache_dir(appname='Python-Eggs') + ) + + +def safe_name(name): + """Convert an arbitrary string to a standard distribution name + + Any runs of non-alphanumeric/. characters are replaced with a single '-'. + """ + return re.sub('[^A-Za-z0-9.]+', '-', name) + + +def safe_version(version): + """ + Convert an arbitrary string to a standard version string + """ + try: + # normalize the version + return str(packaging.version.Version(version)) + except packaging.version.InvalidVersion: + version = version.replace(' ', '.') + return re.sub('[^A-Za-z0-9.]+', '-', version) + + +def safe_extra(extra): + """Convert an arbitrary string to a standard 'extra' name + + Any runs of non-alphanumeric characters are replaced with a single '_', + and the result is always lowercased. + """ + return re.sub('[^A-Za-z0-9.-]+', '_', extra).lower() + + +def to_filename(name): + """Convert a project or version name to its filename-escaped form + + Any '-' characters are currently replaced with '_'. + """ + return name.replace('-', '_') + + +def invalid_marker(text): + """ + Validate text as a PEP 508 environment marker; return an exception + if invalid or False otherwise. + """ + try: + evaluate_marker(text) + except SyntaxError as e: + e.filename = None + e.lineno = None + return e + return False + + +def evaluate_marker(text, extra=None): + """ + Evaluate a PEP 508 environment marker. + Return a boolean indicating the marker result in this environment. + Raise SyntaxError if marker is invalid. + + This implementation uses the 'pyparsing' module. + """ + try: + marker = packaging.markers.Marker(text) + return marker.evaluate() + except packaging.markers.InvalidMarker as e: + raise SyntaxError(e) + + +class NullProvider: + """Try to implement resources and metadata for arbitrary PEP 302 loaders""" + + egg_name = None + egg_info = None + loader = None + + def __init__(self, module): + self.loader = getattr(module, '__loader__', None) + self.module_path = os.path.dirname(getattr(module, '__file__', '')) + + def get_resource_filename(self, manager, resource_name): + return self._fn(self.module_path, resource_name) + + def get_resource_stream(self, manager, resource_name): + return io.BytesIO(self.get_resource_string(manager, resource_name)) + + def get_resource_string(self, manager, resource_name): + return self._get(self._fn(self.module_path, resource_name)) + + def has_resource(self, resource_name): + return self._has(self._fn(self.module_path, resource_name)) + + def has_metadata(self, name): + return self.egg_info and self._has(self._fn(self.egg_info, name)) + + def get_metadata(self, name): + if not self.egg_info: + return "" + value = self._get(self._fn(self.egg_info, name)) + return value.decode('utf-8') if six.PY3 else value + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + def resource_isdir(self, resource_name): + return self._isdir(self._fn(self.module_path, resource_name)) + + def metadata_isdir(self, name): + return self.egg_info and self._isdir(self._fn(self.egg_info, name)) + + def resource_listdir(self, resource_name): + return self._listdir(self._fn(self.module_path, resource_name)) + + def metadata_listdir(self, name): + if self.egg_info: + return self._listdir(self._fn(self.egg_info, name)) + return [] + + def run_script(self, script_name, namespace): + script = 'scripts/' + script_name + if not self.has_metadata(script): + raise ResolutionError( + "Script {script!r} not found in metadata at {self.egg_info!r}" + .format(**locals()), + ) + script_text = self.get_metadata(script).replace('\r\n', '\n') + script_text = script_text.replace('\r', '\n') + script_filename = self._fn(self.egg_info, script) + namespace['__file__'] = script_filename + if os.path.exists(script_filename): + source = open(script_filename).read() + code = compile(source, script_filename, 'exec') + exec(code, namespace, namespace) + else: + from linecache import cache + cache[script_filename] = ( + len(script_text), 0, script_text.split('\n'), script_filename + ) + script_code = compile(script_text, script_filename, 'exec') + exec(script_code, namespace, namespace) + + def _has(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _isdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _listdir(self, path): + raise NotImplementedError( + "Can't perform this operation for unregistered loader type" + ) + + def _fn(self, base, resource_name): + if resource_name: + return os.path.join(base, *resource_name.split('/')) + return base + + def _get(self, path): + if hasattr(self.loader, 'get_data'): + return self.loader.get_data(path) + raise NotImplementedError( + "Can't perform this operation for loaders without 'get_data()'" + ) + + +register_loader_type(object, NullProvider) + + +class EggProvider(NullProvider): + """Provider based on a virtual filesystem""" + + def __init__(self, module): + NullProvider.__init__(self, module) + self._setup_prefix() + + def _setup_prefix(self): + # we assume here that our metadata may be nested inside a "basket" + # of multiple eggs; that's why we use module_path instead of .archive + path = self.module_path + old = None + while path != old: + if _is_egg_path(path): + self.egg_name = os.path.basename(path) + self.egg_info = os.path.join(path, 'EGG-INFO') + self.egg_root = path + break + old = path + path, base = os.path.split(path) + + +class DefaultProvider(EggProvider): + """Provides access to package resources in the filesystem""" + + def _has(self, path): + return os.path.exists(path) + + def _isdir(self, path): + return os.path.isdir(path) + + def _listdir(self, path): + return os.listdir(path) + + def get_resource_stream(self, manager, resource_name): + return open(self._fn(self.module_path, resource_name), 'rb') + + def _get(self, path): + with open(path, 'rb') as stream: + return stream.read() + + @classmethod + def _register(cls): + loader_names = 'SourceFileLoader', 'SourcelessFileLoader', + for name in loader_names: + loader_cls = getattr(importlib_machinery, name, type(None)) + register_loader_type(loader_cls, cls) + + +DefaultProvider._register() + + +class EmptyProvider(NullProvider): + """Provider that returns nothing for all requests""" + + module_path = None + + _isdir = _has = lambda self, path: False + + def _get(self, path): + return '' + + def _listdir(self, path): + return [] + + def __init__(self): + pass + + +empty_provider = EmptyProvider() + + +class ZipManifests(dict): + """ + zip manifest builder + """ + + @classmethod + def build(cls, path): + """ + Build a dictionary similar to the zipimport directory + caches, except instead of tuples, store ZipInfo objects. + + Use a platform-specific path separator (os.sep) for the path keys + for compatibility with pypy on Windows. + """ + with zipfile.ZipFile(path) as zfile: + items = ( + ( + name.replace('/', os.sep), + zfile.getinfo(name), + ) + for name in zfile.namelist() + ) + return dict(items) + + load = build + + +class MemoizedZipManifests(ZipManifests): + """ + Memoized zipfile manifests. + """ + manifest_mod = collections.namedtuple('manifest_mod', 'manifest mtime') + + def load(self, path): + """ + Load a manifest at path or return a suitable manifest already loaded. + """ + path = os.path.normpath(path) + mtime = os.stat(path).st_mtime + + if path not in self or self[path].mtime != mtime: + manifest = self.build(path) + self[path] = self.manifest_mod(manifest, mtime) + + return self[path].manifest + + +class ZipProvider(EggProvider): + """Resource support for zips and eggs""" + + eagers = None + _zip_manifests = MemoizedZipManifests() + + def __init__(self, module): + EggProvider.__init__(self, module) + self.zip_pre = self.loader.archive + os.sep + + def _zipinfo_name(self, fspath): + # Convert a virtual filename (full path to file) into a zipfile subpath + # usable with the zipimport directory cache for our target archive + fspath = fspath.rstrip(os.sep) + if fspath == self.loader.archive: + return '' + if fspath.startswith(self.zip_pre): + return fspath[len(self.zip_pre):] + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.zip_pre) + ) + + def _parts(self, zip_path): + # Convert a zipfile subpath into an egg-relative path part list. + # pseudo-fs path + fspath = self.zip_pre + zip_path + if fspath.startswith(self.egg_root + os.sep): + return fspath[len(self.egg_root) + 1:].split(os.sep) + raise AssertionError( + "%s is not a subpath of %s" % (fspath, self.egg_root) + ) + + @property + def zipinfo(self): + return self._zip_manifests.load(self.loader.archive) + + def get_resource_filename(self, manager, resource_name): + if not self.egg_name: + raise NotImplementedError( + "resource_filename() only supported for .egg, not .zip" + ) + # no need to lock for extraction, since we use temp names + zip_path = self._resource_to_zip(resource_name) + eagers = self._get_eager_resources() + if '/'.join(self._parts(zip_path)) in eagers: + for name in eagers: + self._extract_resource(manager, self._eager_to_zip(name)) + return self._extract_resource(manager, zip_path) + + @staticmethod + def _get_date_and_size(zip_stat): + size = zip_stat.file_size + # ymdhms+wday, yday, dst + date_time = zip_stat.date_time + (0, 0, -1) + # 1980 offset already done + timestamp = time.mktime(date_time) + return timestamp, size + + def _extract_resource(self, manager, zip_path): + + if zip_path in self._index(): + for name in self._index()[zip_path]: + last = self._extract_resource( + manager, os.path.join(zip_path, name) + ) + # return the extracted directory name + return os.path.dirname(last) + + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + + if not WRITE_SUPPORT: + raise IOError('"os.rename" and "os.unlink" are not supported ' + 'on this platform') + try: + + real_path = manager.get_cache_path( + self.egg_name, self._parts(zip_path) + ) + + if self._is_current(real_path, zip_path): + return real_path + + outf, tmpnam = _mkstemp( + ".$extract", + dir=os.path.dirname(real_path), + ) + os.write(outf, self.loader.get_data(zip_path)) + os.close(outf) + utime(tmpnam, (timestamp, timestamp)) + manager.postprocess(tmpnam, real_path) + + try: + rename(tmpnam, real_path) + + except os.error: + if os.path.isfile(real_path): + if self._is_current(real_path, zip_path): + # the file became current since it was checked above, + # so proceed. + return real_path + # Windows, del old file and retry + elif os.name == 'nt': + unlink(real_path) + rename(tmpnam, real_path) + return real_path + raise + + except os.error: + # report a user-friendly error + manager.extraction_error() + + return real_path + + def _is_current(self, file_path, zip_path): + """ + Return True if the file_path is current for this zip_path + """ + timestamp, size = self._get_date_and_size(self.zipinfo[zip_path]) + if not os.path.isfile(file_path): + return False + stat = os.stat(file_path) + if stat.st_size != size or stat.st_mtime != timestamp: + return False + # check that the contents match + zip_contents = self.loader.get_data(zip_path) + with open(file_path, 'rb') as f: + file_contents = f.read() + return zip_contents == file_contents + + def _get_eager_resources(self): + if self.eagers is None: + eagers = [] + for name in ('native_libs.txt', 'eager_resources.txt'): + if self.has_metadata(name): + eagers.extend(self.get_metadata_lines(name)) + self.eagers = eagers + return self.eagers + + def _index(self): + try: + return self._dirindex + except AttributeError: + ind = {} + for path in self.zipinfo: + parts = path.split(os.sep) + while parts: + parent = os.sep.join(parts[:-1]) + if parent in ind: + ind[parent].append(parts[-1]) + break + else: + ind[parent] = [parts.pop()] + self._dirindex = ind + return ind + + def _has(self, fspath): + zip_path = self._zipinfo_name(fspath) + return zip_path in self.zipinfo or zip_path in self._index() + + def _isdir(self, fspath): + return self._zipinfo_name(fspath) in self._index() + + def _listdir(self, fspath): + return list(self._index().get(self._zipinfo_name(fspath), ())) + + def _eager_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.egg_root, resource_name)) + + def _resource_to_zip(self, resource_name): + return self._zipinfo_name(self._fn(self.module_path, resource_name)) + + +register_loader_type(zipimport.zipimporter, ZipProvider) + + +class FileMetadata(EmptyProvider): + """Metadata handler for standalone PKG-INFO files + + Usage:: + + metadata = FileMetadata("/path/to/PKG-INFO") + + This provider rejects all data and metadata requests except for PKG-INFO, + which is treated as existing, and will be the contents of the file at + the provided location. + """ + + def __init__(self, path): + self.path = path + + def has_metadata(self, name): + return name == 'PKG-INFO' and os.path.isfile(self.path) + + def get_metadata(self, name): + if name != 'PKG-INFO': + raise KeyError("No metadata except PKG-INFO is available") + + with io.open(self.path, encoding='utf-8', errors="replace") as f: + metadata = f.read() + self._warn_on_replacement(metadata) + return metadata + + def _warn_on_replacement(self, metadata): + # Python 2.7 compat for: replacement_char = '�' + replacement_char = b'\xef\xbf\xbd'.decode('utf-8') + if replacement_char in metadata: + tmpl = "{self.path} could not be properly decoded in UTF-8" + msg = tmpl.format(**locals()) + warnings.warn(msg) + + def get_metadata_lines(self, name): + return yield_lines(self.get_metadata(name)) + + +class PathMetadata(DefaultProvider): + """Metadata provider for egg directories + + Usage:: + + # Development eggs: + + egg_info = "/path/to/PackageName.egg-info" + base_dir = os.path.dirname(egg_info) + metadata = PathMetadata(base_dir, egg_info) + dist_name = os.path.splitext(os.path.basename(egg_info))[0] + dist = Distribution(basedir, project_name=dist_name, metadata=metadata) + + # Unpacked egg directories: + + egg_path = "/path/to/PackageName-ver-pyver-etc.egg" + metadata = PathMetadata(egg_path, os.path.join(egg_path,'EGG-INFO')) + dist = Distribution.from_filename(egg_path, metadata=metadata) + """ + + def __init__(self, path, egg_info): + self.module_path = path + self.egg_info = egg_info + + +class EggMetadata(ZipProvider): + """Metadata provider for .egg files""" + + def __init__(self, importer): + """Create a metadata provider from a zipimporter""" + + self.zip_pre = importer.archive + os.sep + self.loader = importer + if importer.prefix: + self.module_path = os.path.join(importer.archive, importer.prefix) + else: + self.module_path = importer.archive + self._setup_prefix() + + +_declare_state('dict', _distribution_finders={}) + + +def register_finder(importer_type, distribution_finder): + """Register `distribution_finder` to find distributions in sys.path items + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `distribution_finder` is a callable that, passed a path + item and the importer instance, yields ``Distribution`` instances found on + that path item. See ``pkg_resources.find_on_path`` for an example.""" + _distribution_finders[importer_type] = distribution_finder + + +def find_distributions(path_item, only=False): + """Yield distributions accessible via `path_item`""" + importer = get_importer(path_item) + finder = _find_adapter(_distribution_finders, importer) + return finder(importer, path_item, only) + + +def find_eggs_in_zip(importer, path_item, only=False): + """ + Find eggs in zip files; possibly multiple nested eggs. + """ + if importer.archive.endswith('.whl'): + # wheels are not supported with this finder + # they don't have PKG-INFO metadata, and won't ever contain eggs + return + metadata = EggMetadata(importer) + if metadata.has_metadata('PKG-INFO'): + yield Distribution.from_filename(path_item, metadata=metadata) + if only: + # don't yield nested distros + return + for subitem in metadata.resource_listdir('/'): + if _is_egg_path(subitem): + subpath = os.path.join(path_item, subitem) + dists = find_eggs_in_zip(zipimport.zipimporter(subpath), subpath) + for dist in dists: + yield dist + elif subitem.lower().endswith('.dist-info'): + subpath = os.path.join(path_item, subitem) + submeta = EggMetadata(zipimport.zipimporter(subpath)) + submeta.egg_info = subpath + yield Distribution.from_location(path_item, subitem, submeta) + + +register_finder(zipimport.zipimporter, find_eggs_in_zip) + + +def find_nothing(importer, path_item, only=False): + return () + + +register_finder(object, find_nothing) + + +def _by_version_descending(names): + """ + Given a list of filenames, return them in descending order + by version number. + + >>> names = 'bar', 'foo', 'Python-2.7.10.egg', 'Python-2.7.2.egg' + >>> _by_version_descending(names) + ['Python-2.7.10.egg', 'Python-2.7.2.egg', 'foo', 'bar'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.egg', 'Setuptools-1.2.3b1.egg'] + >>> names = 'Setuptools-1.2.3b1.egg', 'Setuptools-1.2.3.post1.egg' + >>> _by_version_descending(names) + ['Setuptools-1.2.3.post1.egg', 'Setuptools-1.2.3b1.egg'] + """ + def _by_version(name): + """ + Parse each component of the filename + """ + name, ext = os.path.splitext(name) + parts = itertools.chain(name.split('-'), [ext]) + return [packaging.version.parse(part) for part in parts] + + return sorted(names, key=_by_version, reverse=True) + + +def find_on_path(importer, path_item, only=False): + """Yield distributions accessible on a sys.path directory""" + path_item = _normalize_cached(path_item) + + if _is_unpacked_egg(path_item): + yield Distribution.from_filename( + path_item, metadata=PathMetadata( + path_item, os.path.join(path_item, 'EGG-INFO') + ) + ) + return + + entries = safe_listdir(path_item) + + # for performance, before sorting by version, + # screen entries for only those that will yield + # distributions + filtered = ( + entry + for entry in entries + if dist_factory(path_item, entry, only) + ) + + # scan for .egg and .egg-info in directory + path_item_entries = _by_version_descending(filtered) + for entry in path_item_entries: + fullpath = os.path.join(path_item, entry) + factory = dist_factory(path_item, entry, only) + for dist in factory(fullpath): + yield dist + + +def dist_factory(path_item, entry, only): + """ + Return a dist_factory for a path_item and entry + """ + lower = entry.lower() + is_meta = any(map(lower.endswith, ('.egg-info', '.dist-info'))) + return ( + distributions_from_metadata + if is_meta else + find_distributions + if not only and _is_egg_path(entry) else + resolve_egg_link + if not only and lower.endswith('.egg-link') else + NoDists() + ) + + +class NoDists: + """ + >>> bool(NoDists()) + False + + >>> list(NoDists()('anything')) + [] + """ + def __bool__(self): + return False + if six.PY2: + __nonzero__ = __bool__ + + def __call__(self, fullpath): + return iter(()) + + +def safe_listdir(path): + """ + Attempt to list contents of path, but suppress some exceptions. + """ + try: + return os.listdir(path) + except (PermissionError, NotADirectoryError): + pass + except OSError as e: + # Ignore the directory if does not exist, not a directory or + # permission denied + ignorable = ( + e.errno in (errno.ENOTDIR, errno.EACCES, errno.ENOENT) + # Python 2 on Windows needs to be handled this way :( + or getattr(e, "winerror", None) == 267 + ) + if not ignorable: + raise + return () + + +def distributions_from_metadata(path): + root = os.path.dirname(path) + if os.path.isdir(path): + if len(os.listdir(path)) == 0: + # empty metadata dir; skip + return + metadata = PathMetadata(root, path) + else: + metadata = FileMetadata(path) + entry = os.path.basename(path) + yield Distribution.from_location( + root, entry, metadata, precedence=DEVELOP_DIST, + ) + + +def non_empty_lines(path): + """ + Yield non-empty lines from file at path + """ + with open(path) as f: + for line in f: + line = line.strip() + if line: + yield line + + +def resolve_egg_link(path): + """ + Given a path to an .egg-link, resolve distributions + present in the referenced path. + """ + referenced_paths = non_empty_lines(path) + resolved_paths = ( + os.path.join(os.path.dirname(path), ref) + for ref in referenced_paths + ) + dist_groups = map(find_distributions, resolved_paths) + return next(dist_groups, ()) + + +register_finder(pkgutil.ImpImporter, find_on_path) + +if hasattr(importlib_machinery, 'FileFinder'): + register_finder(importlib_machinery.FileFinder, find_on_path) + +_declare_state('dict', _namespace_handlers={}) +_declare_state('dict', _namespace_packages={}) + + +def register_namespace_handler(importer_type, namespace_handler): + """Register `namespace_handler` to declare namespace packages + + `importer_type` is the type or class of a PEP 302 "Importer" (sys.path item + handler), and `namespace_handler` is a callable like this:: + + def namespace_handler(importer, path_entry, moduleName, module): + # return a path_entry to use for child packages + + Namespace handlers are only called if the importer object has already + agreed that it can handle the relevant path item, and they should only + return a subpath if the module __path__ does not already contain an + equivalent subpath. For an example namespace handler, see + ``pkg_resources.file_ns_handler``. + """ + _namespace_handlers[importer_type] = namespace_handler + + +def _handle_ns(packageName, path_item): + """Ensure that named package includes a subpath of path_item (if needed)""" + + importer = get_importer(path_item) + if importer is None: + return None + + # capture warnings due to #1111 + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + loader = importer.find_module(packageName) + + if loader is None: + return None + module = sys.modules.get(packageName) + if module is None: + module = sys.modules[packageName] = types.ModuleType(packageName) + module.__path__ = [] + _set_parent_ns(packageName) + elif not hasattr(module, '__path__'): + raise TypeError("Not a package:", packageName) + handler = _find_adapter(_namespace_handlers, importer) + subpath = handler(importer, path_item, packageName, module) + if subpath is not None: + path = module.__path__ + path.append(subpath) + loader.load_module(packageName) + _rebuild_mod_path(path, packageName, module) + return subpath + + +def _rebuild_mod_path(orig_path, package_name, module): + """ + Rebuild module.__path__ ensuring that all entries are ordered + corresponding to their sys.path order + """ + sys_path = [_normalize_cached(p) for p in sys.path] + + def safe_sys_path_index(entry): + """ + Workaround for #520 and #513. + """ + try: + return sys_path.index(entry) + except ValueError: + return float('inf') + + def position_in_sys_path(path): + """ + Return the ordinal of the path based on its position in sys.path + """ + path_parts = path.split(os.sep) + module_parts = package_name.count('.') + 1 + parts = path_parts[:-module_parts] + return safe_sys_path_index(_normalize_cached(os.sep.join(parts))) + + new_path = sorted(orig_path, key=position_in_sys_path) + new_path = [_normalize_cached(p) for p in new_path] + + if isinstance(module.__path__, list): + module.__path__[:] = new_path + else: + module.__path__ = new_path + + +def declare_namespace(packageName): + """Declare that package 'packageName' is a namespace package""" + + _imp.acquire_lock() + try: + if packageName in _namespace_packages: + return + + path = sys.path + parent, _, _ = packageName.rpartition('.') + + if parent: + declare_namespace(parent) + if parent not in _namespace_packages: + __import__(parent) + try: + path = sys.modules[parent].__path__ + except AttributeError: + raise TypeError("Not a package:", parent) + + # Track what packages are namespaces, so when new path items are added, + # they can be updated + _namespace_packages.setdefault(parent or None, []).append(packageName) + _namespace_packages.setdefault(packageName, []) + + for path_item in path: + # Ensure all the parent's path items are reflected in the child, + # if they apply + _handle_ns(packageName, path_item) + + finally: + _imp.release_lock() + + +def fixup_namespace_packages(path_item, parent=None): + """Ensure that previously-declared namespace packages include path_item""" + _imp.acquire_lock() + try: + for package in _namespace_packages.get(parent, ()): + subpath = _handle_ns(package, path_item) + if subpath: + fixup_namespace_packages(subpath, package) + finally: + _imp.release_lock() + + +def file_ns_handler(importer, path_item, packageName, module): + """Compute an ns-package subpath for a filesystem or zipfile importer""" + + subpath = os.path.join(path_item, packageName.split('.')[-1]) + normalized = _normalize_cached(subpath) + for item in module.__path__: + if _normalize_cached(item) == normalized: + break + else: + # Only return the path if it's not already there + return subpath + + +register_namespace_handler(pkgutil.ImpImporter, file_ns_handler) +register_namespace_handler(zipimport.zipimporter, file_ns_handler) + +if hasattr(importlib_machinery, 'FileFinder'): + register_namespace_handler(importlib_machinery.FileFinder, file_ns_handler) + + +def null_ns_handler(importer, path_item, packageName, module): + return None + + +register_namespace_handler(object, null_ns_handler) + + +def normalize_path(filename): + """Normalize a file/dir name for comparison purposes""" + return os.path.normcase(os.path.realpath(os.path.normpath(_cygwin_patch(filename)))) + + +def _cygwin_patch(filename): # pragma: nocover + """ + Contrary to POSIX 2008, on Cygwin, getcwd (3) contains + symlink components. Using + os.path.abspath() works around this limitation. A fix in os.getcwd() + would probably better, in Cygwin even more so, except + that this seems to be by design... + """ + return os.path.abspath(filename) if sys.platform == 'cygwin' else filename + + +def _normalize_cached(filename, _cache={}): + try: + return _cache[filename] + except KeyError: + _cache[filename] = result = normalize_path(filename) + return result + + +def _is_egg_path(path): + """ + Determine if given path appears to be an egg. + """ + return path.lower().endswith('.egg') + + +def _is_unpacked_egg(path): + """ + Determine if given path appears to be an unpacked egg. + """ + return ( + _is_egg_path(path) and + os.path.isfile(os.path.join(path, 'EGG-INFO', 'PKG-INFO')) + ) + + +def _set_parent_ns(packageName): + parts = packageName.split('.') + name = parts.pop() + if parts: + parent = '.'.join(parts) + setattr(sys.modules[parent], name, sys.modules[packageName]) + + +def yield_lines(strs): + """Yield non-empty/non-comment lines of a string or sequence""" + if isinstance(strs, six.string_types): + for s in strs.splitlines(): + s = s.strip() + # skip blank lines/comments + if s and not s.startswith('#'): + yield s + else: + for ss in strs: + for s in yield_lines(ss): + yield s + + +MODULE = re.compile(r"\w+(\.\w+)*$").match +EGG_NAME = re.compile( + r""" + (?P<name>[^-]+) ( + -(?P<ver>[^-]+) ( + -py(?P<pyver>[^-]+) ( + -(?P<plat>.+) + )? + )? + )? + """, + re.VERBOSE | re.IGNORECASE, +).match + + +class EntryPoint: + """Object representing an advertised importable object""" + + def __init__(self, name, module_name, attrs=(), extras=(), dist=None): + if not MODULE(module_name): + raise ValueError("Invalid module name", module_name) + self.name = name + self.module_name = module_name + self.attrs = tuple(attrs) + self.extras = tuple(extras) + self.dist = dist + + def __str__(self): + s = "%s = %s" % (self.name, self.module_name) + if self.attrs: + s += ':' + '.'.join(self.attrs) + if self.extras: + s += ' [%s]' % ','.join(self.extras) + return s + + def __repr__(self): + return "EntryPoint.parse(%r)" % str(self) + + def load(self, require=True, *args, **kwargs): + """ + Require packages for this EntryPoint, then resolve it. + """ + if not require or args or kwargs: + warnings.warn( + "Parameters to load are deprecated. Call .resolve and " + ".require separately.", + PkgResourcesDeprecationWarning, + stacklevel=2, + ) + if require: + self.require(*args, **kwargs) + return self.resolve() + + def resolve(self): + """ + Resolve the entry point from its module and attrs. + """ + module = __import__(self.module_name, fromlist=['__name__'], level=0) + try: + return functools.reduce(getattr, self.attrs, module) + except AttributeError as exc: + raise ImportError(str(exc)) + + def require(self, env=None, installer=None): + if self.extras and not self.dist: + raise UnknownExtra("Can't require() without a distribution", self) + + # Get the requirements for this entry point with all its extras and + # then resolve them. We have to pass `extras` along when resolving so + # that the working set knows what extras we want. Otherwise, for + # dist-info distributions, the working set will assume that the + # requirements for that extra are purely optional and skip over them. + reqs = self.dist.requires(self.extras) + items = working_set.resolve(reqs, env, installer, extras=self.extras) + list(map(working_set.add, items)) + + pattern = re.compile( + r'\s*' + r'(?P<name>.+?)\s*' + r'=\s*' + r'(?P<module>[\w.]+)\s*' + r'(:\s*(?P<attr>[\w.]+))?\s*' + r'(?P<extras>\[.*\])?\s*$' + ) + + @classmethod + def parse(cls, src, dist=None): + """Parse a single entry point from string `src` + + Entry point syntax follows the form:: + + name = some.module:some.attr [extra1, extra2] + + The entry name and module name are required, but the ``:attrs`` and + ``[extras]`` parts are optional + """ + m = cls.pattern.match(src) + if not m: + msg = "EntryPoint must be in 'name=module:attrs [extras]' format" + raise ValueError(msg, src) + res = m.groupdict() + extras = cls._parse_extras(res['extras']) + attrs = res['attr'].split('.') if res['attr'] else () + return cls(res['name'], res['module'], attrs, extras, dist) + + @classmethod + def _parse_extras(cls, extras_spec): + if not extras_spec: + return () + req = Requirement.parse('x' + extras_spec) + if req.specs: + raise ValueError() + return req.extras + + @classmethod + def parse_group(cls, group, lines, dist=None): + """Parse an entry point group""" + if not MODULE(group): + raise ValueError("Invalid group name", group) + this = {} + for line in yield_lines(lines): + ep = cls.parse(line, dist) + if ep.name in this: + raise ValueError("Duplicate entry point", group, ep.name) + this[ep.name] = ep + return this + + @classmethod + def parse_map(cls, data, dist=None): + """Parse a map of entry point groups""" + if isinstance(data, dict): + data = data.items() + else: + data = split_sections(data) + maps = {} + for group, lines in data: + if group is None: + if not lines: + continue + raise ValueError("Entry points must be listed in groups") + group = group.strip() + if group in maps: + raise ValueError("Duplicate group name", group) + maps[group] = cls.parse_group(group, lines, dist) + return maps + + +def _remove_md5_fragment(location): + if not location: + return '' + parsed = urllib.parse.urlparse(location) + if parsed[-1].startswith('md5='): + return urllib.parse.urlunparse(parsed[:-1] + ('',)) + return location + + +def _version_from_file(lines): + """ + Given an iterable of lines from a Metadata file, return + the value of the Version field, if present, or None otherwise. + """ + def is_version_line(line): + return line.lower().startswith('version:') + version_lines = filter(is_version_line, lines) + line = next(iter(version_lines), '') + _, _, value = line.partition(':') + return safe_version(value.strip()) or None + + +class Distribution: + """Wrap an actual or potential sys.path entry w/metadata""" + PKG_INFO = 'PKG-INFO' + + def __init__( + self, location=None, metadata=None, project_name=None, + version=None, py_version=PY_MAJOR, platform=None, + precedence=EGG_DIST): + self.project_name = safe_name(project_name or 'Unknown') + if version is not None: + self._version = safe_version(version) + self.py_version = py_version + self.platform = platform + self.location = location + self.precedence = precedence + self._provider = metadata or empty_provider + + @classmethod + def from_location(cls, location, basename, metadata=None, **kw): + project_name, version, py_version, platform = [None] * 4 + basename, ext = os.path.splitext(basename) + if ext.lower() in _distributionImpl: + cls = _distributionImpl[ext.lower()] + + match = EGG_NAME(basename) + if match: + project_name, version, py_version, platform = match.group( + 'name', 'ver', 'pyver', 'plat' + ) + return cls( + location, metadata, project_name=project_name, version=version, + py_version=py_version, platform=platform, **kw + )._reload_version() + + def _reload_version(self): + return self + + @property + def hashcmp(self): + return ( + self.parsed_version, + self.precedence, + self.key, + _remove_md5_fragment(self.location), + self.py_version or '', + self.platform or '', + ) + + def __hash__(self): + return hash(self.hashcmp) + + def __lt__(self, other): + return self.hashcmp < other.hashcmp + + def __le__(self, other): + return self.hashcmp <= other.hashcmp + + def __gt__(self, other): + return self.hashcmp > other.hashcmp + + def __ge__(self, other): + return self.hashcmp >= other.hashcmp + + def __eq__(self, other): + if not isinstance(other, self.__class__): + # It's not a Distribution, so they are not equal + return False + return self.hashcmp == other.hashcmp + + def __ne__(self, other): + return not self == other + + # These properties have to be lazy so that we don't have to load any + # metadata until/unless it's actually needed. (i.e., some distributions + # may not know their name or version without loading PKG-INFO) + + @property + def key(self): + try: + return self._key + except AttributeError: + self._key = key = self.project_name.lower() + return key + + @property + def parsed_version(self): + if not hasattr(self, "_parsed_version"): + self._parsed_version = parse_version(self.version) + + return self._parsed_version + + def _warn_legacy_version(self): + LV = packaging.version.LegacyVersion + is_legacy = isinstance(self._parsed_version, LV) + if not is_legacy: + return + + # While an empty version is technically a legacy version and + # is not a valid PEP 440 version, it's also unlikely to + # actually come from someone and instead it is more likely that + # it comes from setuptools attempting to parse a filename and + # including it in the list. So for that we'll gate this warning + # on if the version is anything at all or not. + if not self.version: + return + + tmpl = textwrap.dedent(""" + '{project_name} ({version})' is being parsed as a legacy, + non PEP 440, + version. You may find odd behavior and sort order. + In particular it will be sorted as less than 0.0. It + is recommended to migrate to PEP 440 compatible + versions. + """).strip().replace('\n', ' ') + + warnings.warn(tmpl.format(**vars(self)), PEP440Warning) + + @property + def version(self): + try: + return self._version + except AttributeError: + version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if version is None: + tmpl = "Missing 'Version:' header and/or %s file" + raise ValueError(tmpl % self.PKG_INFO, self) + return version + + @property + def _dep_map(self): + """ + A map of extra to its list of (direct) requirements + for this distribution, including the null extra. + """ + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._filter_extras(self._build_dep_map()) + return self.__dep_map + + @staticmethod + def _filter_extras(dm): + """ + Given a mapping of extras to dependencies, strip off + environment markers and filter out any dependencies + not matching the markers. + """ + for extra in list(filter(None, dm)): + new_extra = extra + reqs = dm.pop(extra) + new_extra, _, marker = extra.partition(':') + fails_marker = marker and ( + invalid_marker(marker) + or not evaluate_marker(marker) + ) + if fails_marker: + reqs = [] + new_extra = safe_extra(new_extra) or None + + dm.setdefault(new_extra, []).extend(reqs) + return dm + + def _build_dep_map(self): + dm = {} + for name in 'requires.txt', 'depends.txt': + for extra, reqs in split_sections(self._get_metadata(name)): + dm.setdefault(extra, []).extend(parse_requirements(reqs)) + return dm + + def requires(self, extras=()): + """List of Requirements needed for this distro if `extras` are used""" + dm = self._dep_map + deps = [] + deps.extend(dm.get(None, ())) + for ext in extras: + try: + deps.extend(dm[safe_extra(ext)]) + except KeyError: + raise UnknownExtra( + "%s has no such extra feature %r" % (self, ext) + ) + return deps + + def _get_metadata(self, name): + if self.has_metadata(name): + for line in self.get_metadata_lines(name): + yield line + + def activate(self, path=None, replace=False): + """Ensure distribution is importable on `path` (default=sys.path)""" + if path is None: + path = sys.path + self.insert_on(path, replace=replace) + if path is sys.path: + fixup_namespace_packages(self.location) + for pkg in self._get_metadata('namespace_packages.txt'): + if pkg in sys.modules: + declare_namespace(pkg) + + def egg_name(self): + """Return what this distribution's standard .egg filename should be""" + filename = "%s-%s-py%s" % ( + to_filename(self.project_name), to_filename(self.version), + self.py_version or PY_MAJOR + ) + + if self.platform: + filename += '-' + self.platform + return filename + + def __repr__(self): + if self.location: + return "%s (%s)" % (self, self.location) + else: + return str(self) + + def __str__(self): + try: + version = getattr(self, 'version', None) + except ValueError: + version = None + version = version or "[unknown version]" + return "%s %s" % (self.project_name, version) + + def __getattr__(self, attr): + """Delegate all unrecognized public attributes to .metadata provider""" + if attr.startswith('_'): + raise AttributeError(attr) + return getattr(self._provider, attr) + + def __dir__(self): + return list( + set(super(Distribution, self).__dir__()) + | set( + attr for attr in self._provider.__dir__() + if not attr.startswith('_') + ) + ) + + if not hasattr(object, '__dir__'): + # python 2.7 not supported + del __dir__ + + @classmethod + def from_filename(cls, filename, metadata=None, **kw): + return cls.from_location( + _normalize_cached(filename), os.path.basename(filename), metadata, + **kw + ) + + def as_requirement(self): + """Return a ``Requirement`` that matches this distribution exactly""" + if isinstance(self.parsed_version, packaging.version.Version): + spec = "%s==%s" % (self.project_name, self.parsed_version) + else: + spec = "%s===%s" % (self.project_name, self.parsed_version) + + return Requirement.parse(spec) + + def load_entry_point(self, group, name): + """Return the `name` entry point of `group` or raise ImportError""" + ep = self.get_entry_info(group, name) + if ep is None: + raise ImportError("Entry point %r not found" % ((group, name),)) + return ep.load() + + def get_entry_map(self, group=None): + """Return the entry point map for `group`, or the full entry map""" + try: + ep_map = self._ep_map + except AttributeError: + ep_map = self._ep_map = EntryPoint.parse_map( + self._get_metadata('entry_points.txt'), self + ) + if group is not None: + return ep_map.get(group, {}) + return ep_map + + def get_entry_info(self, group, name): + """Return the EntryPoint object for `group`+`name`, or ``None``""" + return self.get_entry_map(group).get(name) + + def insert_on(self, path, loc=None, replace=False): + """Ensure self.location is on path + + If replace=False (default): + - If location is already in path anywhere, do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent. + - Else: add to the end of path. + If replace=True: + - If location is already on path anywhere (not eggs) + or higher priority than its parent (eggs) + do nothing. + - Else: + - If it's an egg and its parent directory is on path, + insert just ahead of the parent, + removing any lower-priority entries. + - Else: add it to the front of path. + """ + + loc = loc or self.location + if not loc: + return + + nloc = _normalize_cached(loc) + bdir = os.path.dirname(nloc) + npath = [(p and _normalize_cached(p) or p) for p in path] + + for p, item in enumerate(npath): + if item == nloc: + if replace: + break + else: + # don't modify path (even removing duplicates) if + # found and not replace + return + elif item == bdir and self.precedence == EGG_DIST: + # if it's an .egg, give it precedence over its directory + # UNLESS it's already been added to sys.path and replace=False + if (not replace) and nloc in npath[p:]: + return + if path is sys.path: + self.check_version_conflict() + path.insert(p, loc) + npath.insert(p, nloc) + break + else: + if path is sys.path: + self.check_version_conflict() + if replace: + path.insert(0, loc) + else: + path.append(loc) + return + + # p is the spot where we found or inserted loc; now remove duplicates + while True: + try: + np = npath.index(nloc, p + 1) + except ValueError: + break + else: + del npath[np], path[np] + # ha! + p = np + + return + + def check_version_conflict(self): + if self.key == 'setuptools': + # ignore the inevitable setuptools self-conflicts :( + return + + nsp = dict.fromkeys(self._get_metadata('namespace_packages.txt')) + loc = normalize_path(self.location) + for modname in self._get_metadata('top_level.txt'): + if (modname not in sys.modules or modname in nsp + or modname in _namespace_packages): + continue + if modname in ('pkg_resources', 'setuptools', 'site'): + continue + fn = getattr(sys.modules[modname], '__file__', None) + if fn and (normalize_path(fn).startswith(loc) or + fn.startswith(self.location)): + continue + issue_warning( + "Module %s was already imported from %s, but %s is being added" + " to sys.path" % (modname, fn, self.location), + ) + + def has_version(self): + try: + self.version + except ValueError: + issue_warning("Unbuilt egg for " + repr(self)) + return False + return True + + def clone(self, **kw): + """Copy this distribution, substituting in any changed keyword args""" + names = 'project_name version py_version platform location precedence' + for attr in names.split(): + kw.setdefault(attr, getattr(self, attr, None)) + kw.setdefault('metadata', self._provider) + return self.__class__(**kw) + + @property + def extras(self): + return [dep for dep in self._dep_map if dep] + + +class EggInfoDistribution(Distribution): + def _reload_version(self): + """ + Packages installed by distutils (e.g. numpy or scipy), + which uses an old safe_version, and so + their version numbers can get mangled when + converted to filenames (e.g., 1.11.0.dev0+2329eae to + 1.11.0.dev0_2329eae). These distributions will not be + parsed properly + downstream by Distribution and safe_version, so + take an extra step and try to get the version number from + the metadata file itself instead of the filename. + """ + md_version = _version_from_file(self._get_metadata(self.PKG_INFO)) + if md_version: + self._version = md_version + return self + + +class DistInfoDistribution(Distribution): + """ + Wrap an actual or potential sys.path entry + w/metadata, .dist-info style. + """ + PKG_INFO = 'METADATA' + EQEQ = re.compile(r"([\(,])\s*(\d.*?)\s*([,\)])") + + @property + def _parsed_pkg_info(self): + """Parse and cache metadata""" + try: + return self._pkg_info + except AttributeError: + metadata = self.get_metadata(self.PKG_INFO) + self._pkg_info = email.parser.Parser().parsestr(metadata) + return self._pkg_info + + @property + def _dep_map(self): + try: + return self.__dep_map + except AttributeError: + self.__dep_map = self._compute_dependencies() + return self.__dep_map + + def _compute_dependencies(self): + """Recompute this distribution's dependencies.""" + dm = self.__dep_map = {None: []} + + reqs = [] + # Including any condition expressions + for req in self._parsed_pkg_info.get_all('Requires-Dist') or []: + reqs.extend(parse_requirements(req)) + + def reqs_for_extra(extra): + for req in reqs: + if not req.marker or req.marker.evaluate({'extra': extra}): + yield req + + common = frozenset(reqs_for_extra(None)) + dm[None].extend(common) + + for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []: + s_extra = safe_extra(extra.strip()) + dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common) + + return dm + + +_distributionImpl = { + '.egg': Distribution, + '.egg-info': EggInfoDistribution, + '.dist-info': DistInfoDistribution, +} + + +def issue_warning(*args, **kw): + level = 1 + g = globals() + try: + # find the first stack frame that is *not* code in + # the pkg_resources module, to use for the warning + while sys._getframe(level).f_globals is g: + level += 1 + except ValueError: + pass + warnings.warn(stacklevel=level + 1, *args, **kw) + + +class RequirementParseError(ValueError): + def __str__(self): + return ' '.join(self.args) + + +def parse_requirements(strs): + """Yield ``Requirement`` objects for each specification in `strs` + + `strs` must be a string, or a (possibly-nested) iterable thereof. + """ + # create a steppable iterator, so we can handle \-continuations + lines = iter(yield_lines(strs)) + + for line in lines: + # Drop comments -- a hash without a space may be in a URL. + if ' #' in line: + line = line[:line.find(' #')] + # If there is a line continuation, drop it, and append the next line. + if line.endswith('\\'): + line = line[:-2].strip() + try: + line += next(lines) + except StopIteration: + return + yield Requirement(line) + + +class Requirement(packaging.requirements.Requirement): + def __init__(self, requirement_string): + """DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!""" + try: + super(Requirement, self).__init__(requirement_string) + except packaging.requirements.InvalidRequirement as e: + raise RequirementParseError(str(e)) + self.unsafe_name = self.name + project_name = safe_name(self.name) + self.project_name, self.key = project_name, project_name.lower() + self.specs = [ + (spec.operator, spec.version) for spec in self.specifier] + self.extras = tuple(map(safe_extra, self.extras)) + self.hashCmp = ( + self.key, + self.specifier, + frozenset(self.extras), + str(self.marker) if self.marker else None, + ) + self.__hash = hash(self.hashCmp) + + def __eq__(self, other): + return ( + isinstance(other, Requirement) and + self.hashCmp == other.hashCmp + ) + + def __ne__(self, other): + return not self == other + + def __contains__(self, item): + if isinstance(item, Distribution): + if item.key != self.key: + return False + + item = item.version + + # Allow prereleases always in order to match the previous behavior of + # this method. In the future this should be smarter and follow PEP 440 + # more accurately. + return self.specifier.contains(item, prereleases=True) + + def __hash__(self): + return self.__hash + + def __repr__(self): + return "Requirement.parse(%r)" % str(self) + + @staticmethod + def parse(s): + req, = parse_requirements(s) + return req + + +def _always_object(classes): + """ + Ensure object appears in the mro even + for old-style classes. + """ + if object not in classes: + return classes + (object,) + return classes + + +def _find_adapter(registry, ob): + """Return an adapter factory for `ob` from `registry`""" + types = _always_object(inspect.getmro(getattr(ob, '__class__', type(ob)))) + for t in types: + if t in registry: + return registry[t] + + +def ensure_directory(path): + """Ensure that the parent directory of `path` exists""" + dirname = os.path.dirname(path) + py31compat.makedirs(dirname, exist_ok=True) + + +def _bypass_ensure_directory(path): + """Sandbox-bypassing version of ensure_directory()""" + if not WRITE_SUPPORT: + raise IOError('"os.mkdir" not supported on this platform.') + dirname, filename = split(path) + if dirname and filename and not isdir(dirname): + _bypass_ensure_directory(dirname) + try: + mkdir(dirname, 0o755) + except FileExistsError: + pass + + +def split_sections(s): + """Split a string or iterable thereof into (section, content) pairs + + Each ``section`` is a stripped version of the section header ("[section]") + and each ``content`` is a list of stripped lines excluding blank lines and + comment-only lines. If there are any such lines before the first section + header, they're returned in a first ``section`` of ``None``. + """ + section = None + content = [] + for line in yield_lines(s): + if line.startswith("["): + if line.endswith("]"): + if section or content: + yield section, content + section = line[1:-1].strip() + content = [] + else: + raise ValueError("Invalid section heading", line) + else: + content.append(line) + + # wrap up last segment + yield section, content + + +def _mkstemp(*args, **kw): + old_open = os.open + try: + # temporarily bypass sandboxing + os.open = os_open + return tempfile.mkstemp(*args, **kw) + finally: + # and then put it back + os.open = old_open + + +# Silence the PEP440Warning by default, so that end users don't get hit by it +# randomly just because they use pkg_resources. We want to append the rule +# because we want earlier uses of filterwarnings to take precedence over this +# one. +warnings.filterwarnings("ignore", category=PEP440Warning, append=True) + + +# from jaraco.functools 1.3 +def _call_aside(f, *args, **kwargs): + f(*args, **kwargs) + return f + + +@_call_aside +def _initialize(g=globals()): + "Set up global resource manager (deliberately not state-saved)" + manager = ResourceManager() + g['_manager'] = manager + g.update( + (name, getattr(manager, name)) + for name in dir(manager) + if not name.startswith('_') + ) + + +@_call_aside +def _initialize_master_working_set(): + """ + Prepare the master working set and make the ``require()`` + API available. + + This function has explicit effects on the global state + of pkg_resources. It is intended to be invoked once at + the initialization of this module. + + Invocation by other packages is unsupported and done + at their own risk. + """ + working_set = WorkingSet._build_master() + _declare_state('object', working_set=working_set) + + require = working_set.require + iter_entry_points = working_set.iter_entry_points + add_activation_listener = working_set.subscribe + run_script = working_set.run_script + # backward compatibility + run_main = run_script + # Activate all distributions already on sys.path with replace=False and + # ensure that all distributions added to the working set in the future + # (e.g. by calling ``require()``) will get activated as well, + # with higher priority (replace=True). + tuple( + dist.activate(replace=False) + for dist in working_set + ) + add_activation_listener( + lambda dist: dist.activate(replace=True), + existing=False, + ) + working_set.entries = [] + # match order + list(map(working_set.add_entry, sys.path)) + globals().update(locals()) + +class PkgResourcesDeprecationWarning(Warning): + """ + Base class for warning about deprecations in ``pkg_resources`` + + This class is not derived from ``DeprecationWarning``, and as such is + visible by default. + """ diff --git a/env/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..132b9897e62e85da0b60f8a3ce131dff71e005c5 GIT binary patch literal 96825 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%0DqP?TO=6fusm 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/__pycache__/py31compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..498d04aeb914013d96b66a36b4fdd8751fa22360 GIT binary patch literal 594 zcmYjO&2AGh5T3DjlTDO_o;dUYkoM4q{u~jiic+-_Do8=lu8=|$o3cN#x8n^YC~!c$ z2XN$-eC3o^;KVqnh_U>6#xtJzJagLbcY!7Q_Tcrt0QeP*JCUrM@OEz)6ez49`+H)B zTU%s82_-8zkFp3sbyTccUoneyRJ7`+s;x!QjzB_*_FN?;m`DIZmgt0D>exgYicZ#1 zIEJ*l;VN*sLB<rlbougZ#+0@as05-<c)N3k)u4gzxP~8y@CwXv1dS-Wbc*mvAbh;P zMtZmwg=}OIm68s>a1>K!?`LrZ*I*bGa9O-eV=t`p$$VOBm6P-BXX6o(B_C@dV|{Bh zy1E#@NTrYJY4gq}dYQXsVoNXea`qFb$Ao^L44Zj9tn+#=H?Emh)!yvGjVYSj<Dt{d zqHe6M+^{ZhCZwHR&`h(nIy#uyIcMFkSH3s7qcAx-NWxFIvq6Ca+~Gw7zDva>G-DG5 zUD7>1XeU5uRf=b6mx7Dh4BW((%UXKbXfhO@ZBuyp{QA)M-fMEXHIv-DwSHi<R_-4G jibHVt*MHCtDU(NYs}_}h9OmQ#qXc=0p6vEoxGVku@#Tl) literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2de1fcf30f440e5b685ff1ef0281a5e2d08d4c3 GIT binary patch literal 157 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd<h9ZzKg81d8Uy@s(Uyxa# zo0(T!l9-dDn_QlrmsL_|qF<a^Qd&@wpPy5#Uyz+1UzA#$Us{x$TC5*mmYSE6U!)%& epP83g5+AQuP<e~PCO1E&G$+*#WPULaGXMa$-6xFz literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..72890db66be44ba56aae53ffb4b6ca990439553c GIT binary patch literal 20645 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..14ee0d7b5b0c90e1b47c7f1ae7e406cd70e4f372 GIT binary patch literal 203000 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..252e7a0c08d6522e7dacc8aba932bbb98b10ddac GIT binary patch literal 24358 zcmb_^3w#{MdEegN6Ndu`f#5?DC7m9W2#GvOe299G6rZAKkq|^suao5S;bs9GaJW0p z?vcP5kZeJ==$A}8soSQlO}c4ow~kw<O`4`oAF<ts+oVn7w9VE@nx;wXCQaWj_2K^i z-|X()0U%W=z5DI%H?uR}%zX3BH{X2o%^n*V$XfUnzjW^_pKn>#Z!r-5jsiG>%bgvx zEM*lf6;pOCHg6a07~yy=UX05#QB24)Sxm|^RZPh<T}-P)F{6^jJ|{JsRk52bm724Q z{ZS~5P|k!@>SH$EXXcW{0Vk(_)ES(L6*o9TxZmUq<G#@uERHyvikp#sOL1%cHRooN z!ntM2W*R3wdn=%g&NieQlytXUy<PQPi|Ow=Ln^xxL$0SzS*l;<-n3NCxnm_>%r6c) zcRKkMYb6%5Ua;!7CoJc#x$KpgPQ@(#!<;W!_3Vob4G_=Ec{QjuylEBhRzvD0JnsSC zVYLx>HwxbE2#=^u2yb$>qnvvY-mJDDyan~V4>3CsvsK-Un42ZVD8jd>TM@ohFx>Cl z?>vCAb|QY8x()HSIXjSVmoutv$NvtMUr7MIQ{AQRR`;koSCR;AN9Znfui7r5`_vA+ z8&&s7=zfGAScxOmPRX-N?UeX}+KvB%svx0<BveojNobE?*sJzPXrJ2Q3|z7Gh}vJb z)x+w5)Zh`Mc~tN|rXE)Z)gg(^tGoh*QQBerpAhJXIubxf)zJXj+f%|Zso8OLOv*bU ztvRVqAapNUvSY=@^GS6|o=>UM^8A2$TAcy@d(~Mrrp^lVj2c(Z3Up3QsPh6nr=C|Y z2=t<QNfiZpS-qlO73hPiq&_52Sxu^nKuS4kN}y>qqpAYUs#!HBP)*eWXkN_+P+iqk zL*6#k1*x4@t~@=}lIKNrNnMl_3u;kf+Umn<Nn)1OYwC4@KB7LV-VkU-y{SGX(8twV z>asweP@hzv66n+FGwN-DKC7;%&k6K-^&{#>1^Pqk3+fLG^heYm4KV+h`eW*kOWdDO zUsPWb=&HIFl<{Tf0re-hSn9_m{!bzFrxE%y68Z{4U)^GvyTtri_2<;r1o{c}b@k^3 z`U~nC>L*v?(}#-%jMUrIU!1eAB=k9_fd2VQ>Zexh>DU3QSXg+>DV(rg-BaA{Jm~Cl zcF#WK>|TjuyzOyzJNK?I&x_8^t9zZ@>Zkd3i**fh=St$ji!WF&?*_JAC0wY>U*3YT zTihpU_o<&@DvX%FqJ9=5=4WNZ><172RrO72)2RBn2>NRg^w%TkZ$!}FjG%8u(9cKE zw<74<5p+m>B`D)N5%jkr=x;~R--)2V8$sWVpuZPEe?P+f3la2-5%dot=pPzrdQ0)) zg>BBmpz4TFb$^GdSCSXLE_8d?*$=vruKPhd^z=$h{gV1e*Fbqt?U&W}K(+4))eeAa zzoP!J^!=#%ClT~dQ9tm*biDWoN_!+K?Lb#)sSDerv`3r+L1_n2+OJA!zWQfDY2R1B zhSGjbN_!Ng{W{9{4e-#Y`sWe!n-TOcP_B9VTM_gxBj~rIbiWfp|0;t1bp-t&g8oee z{cZ&PUIhKy2>Sg9`galZ?<43xM9_bXp#Ky>|2cyGO9cJb2>Ndk^xq@se?-tb5%fQ! zR{pOD`ri@se<J9I2AaOJ_!xTTv8ZPr?dqBIg`bw5dCYk<=$S{I2d>1F#lFFlmu>n7 zP#jm{O^bKwrN^C7z)AHL+*9l+Jkvd)Oi!pU3{5AB2T`YkQJo&|s#E5|2c%91oyUVZ zJuY?126gI3DY>Xl0|*UDod%^&holx8j3k<l6%V7F!%;bhddm4pDd(_rC@ANUlrt2R za}zKRN9AlpXhg~x31;jkWZXOv$UjnQlgOl)+6)+Td+`XKTXA7lFCKMrSNima5W1y! z4EI}$$8q0QJc0Xd#gn+-UVIYwJBp|3_u!eARCh|MyCl`!lIk8wwY_+1G2=W{JPjS? zF6by9fR56qzixCC<h~czeJJ%b^b{L<%IV@$NdI*4>7Mkz9;M%b^rJ}sbdWxGC99$J zsQYm}fcP_L^V#AULOXHoLd-MH9mVnbVT1}{8a#L7dJu1!@*!N3@)S8{53apJzrCW* zjI%b*-Od@r?^}VCc9K`0b&g$&70(HD9MFV7Cjgxn=p>-$1bPzC^8%d$^a5y`)xQT! z`*A&t@?XUB0Io*>zl7(bxE=#s#Pe}n2LZo~{I38$1PreR@L|9o4B#gKm+I${g8dj` zJqkF)%6<&7vNyZ2veqG1);q+?nwQXS))0CN+I_df8a@@ktReImiGLaJ2L#St$>|J2 zPvbg+x|5I2;u-^7b|#Az(Xdq!3d&Un@y}d~%}y1kUsh<#jEbSms*{|ZEzUW$;=H7- z7wb-awoz>0-YhneXS{fUx;LO_Z)T4@I~TjsuipW5uBdUJD7y6=p64a>973}QJ&!A_ z(F=f0jVi?oYBh~8+xZe|S;doWdl~SY6Tj*?iP@HO@tPgfhc#);HWF5`A+>p>cmb)S zl0hZ5`PG0jWxyXKjAsegIIv#AlWEQaUci%So&&rH?#SuyIc;a(?1vFIxndWW@Z?p& zrQVDcm+Q9xTE<1{O(AB<;rnT>17t-KH!Bjv%|L@0&_nXR%J+3@Hd)o3B7qcpB*m<x zAl>G0)li?;qMFRBI5hazo!3=-E`uBjDeAZyNcH+EoXt54DL(1EUi=7BkTxdO-41K5 zg)XwHidIfc|MO0K_M^Don6i<|#pR)GEA<rOR*EYKw{TrVd2ixL3N8Tt7@mu`+JHYk zZ57{g9w=URKCxn5{Ul;Pd<`?fT;G*JJvePSpDKMCHT?`i#f8Jp+k{tQkhc%MVi!MK zyn=Pum6h1+1L{^#ZBXCkT!CiyKma4H^VvhzxOHXl!d;NXpMCiX^I!d(v-2A0s^SyY zj@M$A)qeOnuUe~mRmaUwHFW-x23()cR~pL6doyJ(uUmCD->B!u7rhxg_T<ZTmEZdV zE?!4t{)Y0T+o-iXr&OJ9Hnca^zV8^=zC2$=4##t}i#!J>gQz1-K~iYw>BH^RLxqPP zEIjxF8<>6&Cpudv2=nGAX3H1L)gS)whp$%<jDAdf1eZI4n`0F*pB8P5IvezivsI%B zKlWk;Et4OgypH2?iC4vt#2%}$JpOF!t87NXb!t;Og9y33b9A>i-`w4-Hg{F)u2-(r zc2zD-*Jr&8`*ypI*J^r=M$O&boSQCb$8EH9#c_9+E;?9|=-qC0q0n6P)1^|)sh3KJ zfz)NStysJ7#X=A}hI(d7rFwbZDV6+esWjhEts3E6sdS-Lu9-KwKde%xa+;O|oyP4T zE<v5KC0t7);)k!Bf7+@@sfgl}mr#MZmtsp+DWF9=e^g-s*{HPUow`@{s^~DUkuT?` zTJ;J;g)tBatwEAfY1H-;eBs9tTvaDDsI0KIYgC>_8K%v)9tPagA5l&C#<P~hAmGJj z?Ir7G3%wI-A2=<%ls7clnb#n>u9Gdj87GL%m#4s85>YF=9va{kM&qQUVMI_e?k>81 z+8}Y+$)xG(IuC~FO}cT`oQz`GnV8;!XN7_A$GRWE<!-}mE&EZ0gNY`IR-{msGv)T; z3CFGIckKyjH|VT4124uwA07g)t}b|{TCaMg(u=GGs{^*$*eMD8W!_gp4rgP?*wXpO z04!Not!vhD+>4P7Kz2yVn6)_U#g}5U3C2+3L7N##SYC22s}CAo#^^6g9AmLDv@avP zU%Tk|X^e@o=V__2pH@zdA-}Iws-SONbj9FNL{ujsCr)bJ(4z@yp&xHd&ic03^ivo{ zt(v#GwcxsG2aSCh)plVVLt`_s!I&K%#yu5l5BD@&l8%igbq)#j0B_8rZ|3bT-l73+ zAQ?zo@#1-0((4&J6W5IC>2=`;CMn<+^?K$lYYKu##oz3M=s~Yb-=|a>&*WQH!YZaf zsy@H}Y~!M%&dT^6tAx1tWEb&r_u%GP=n!kgzG^Q)sfbx#T<=(lD{C&J^GmVi_);8W zHc?M4VVsl_D&Ux;pLAPIN9((RLR#v_$6wm($HC44l})e28#U#}>&_)G*=<ZKv=9oA zK2=;U>1M@-VhK<gm)#!es(OdBx`it_@Hq1l69@BbY=t5g9AeAx(f8s7$`p?7&|eC^ z1+O$S2YlRH93?BbD;hhb7%wS~-5D^l4Z4A5D>hgfv;k8KLx+qS*DS_QgFA#rZ$&8N zzl88<IuO2o@?yExS|cI)g$bFmRD$W&a@h(pVm6kGwYT(=C@2Mj5)??U%ZbwJT|nUv z1Ouev)M}+thdaYA5+bo<r*XL{+%ooHA2^h86<pCT9zgC603nA8e{yQfaB4KN2`Wd2 zH<Nz93?Rds5uw=|M99m%9k<o2iC&IVQgpGQz6a^_Zr)_L35#t&uv?gg?doN{*O1DH zT(Dkyq^m}2SuU*FapuY6#;JeWUWO<$EkxC<6PQsBSd0TBCdV|ZAw3aILm`?8qTw_& z4Q6^Z%Ph0j=j;oK2{S%WVIz=zyYQgCpLlv%_?_&*TGjO`jrr!`H;IgxQ&#)F-d3n8 zc&Bi%)~J+g?qL979?VKNf%_mIN@OsRkZwRSKglR}Rf#ea6WtpujyyqD90?}@)0H5c z6nPyE+=on>GDlOObqWakNBE9?xr8g=yIdlZlK!nAF8Xmi^5=4thkU0}>q$nDh@2VI z{-BJRqhW)`D$)#K;4|Vpg}`dggHU{Gtx#M_ikLjI1hEKlc@W|<Sx+n_mXk|KaA~r> z)d<bteG%{RmTy8anlk*mA4MAe-A;&&l3pK8b!KEg4M|Fg;in-@1;{Xlo#kg3MJOa? zFROnB2t{@1NZAy6FB41Il(&Qvp-73y^Dd)+3>pgF<rpL&C-wM>ZG>>5BZT#6)EuK= z_$jmkN@s@wjA}^%^(EF+dKY3Y5OQ5L3S=`hX=no1mvT2?FOvFGVIdG}!<sQY%tcN( z!X%uYBj$=hm~qmjqGcxCq%xCkN^MkqDvMQETFK56cEko~!7BEt4QdF_thz}J<Js@@ z7jr5D5{>vHrHSgoSxgS&WpBnPo{nz+Vm6Q8(fmAK<ePYtH)<tS&PD*|sp)g@y0Rv! zdT!orO&XfIg{)vWKT~z{q6INi&7qEs<oWTF<9i?6lb@>A6;N_XRcn+17V@XPygSoq z)l`1c!7^+fg;ytQj$pe~MMc7eSYf~9!{Q|GEI^=8KfZ_s7gTmE*rtMXdnIF!Y^RJm zPPz`^W|jg~4D}M$Qif@4qcRN4)f<=U!Q>c8r449x5GTu*)!akz{}aS+xCdI=ZR=6E z!_}+~e@xE>%qd(VPZsh^HkP|vq5F`hQN>x9O}AJ}@hw>TTu8lONrmk(KURRu<Z8%> zYolGt@b&wqS~Xcrxqc=DS5+CaAlEIX<G#VtBgW6KU-eG%9>S7gg|J+l_S6`)mbHyN zrnw&MscoR`A3^-uiczOE75gc?4;7{BRI8JCEK>hjr>Mg@)frmOrS#wux;yOhn2>KY zZsgn%r1KMG`!zKp#|Aa}8Keqkpe*Iq`nBrH&_gUrMj_UN02Z@CF6>)RfDgPFRvq`7 zRflIQ%*wPIzY#Mlkf77scgol@!v@PgjKX@u%adorB_f(brtmXQJBzaJ@cYdGH;a%P z5FU&04l#d@?PPVWm<?$-7;E3TK3jC<iJD6KM@>D4z+%<|A1{SXwb9hudlp#MRq*?@ z*s|><mTWJ%V(Y_8_SF=YY&NuiYsoI95id9nB4mbaMw93CCf-is=C9is-L3MoRacA~ z^@?Lw527by0c}VM6}F2T%v>n5ncS!%`29>7FvGVHAx0Sx$tICfAQk?Y)G&dpTbn{x z_K05ORSrL44GJjEZC61rn8u*vqqTPXiz3q~pwEeAAn)mxvol|v5_14o`6^@qNMFkD z%3OKc2}CmUz2M~Q4pMm(&yevm4Zw{&`WzxxYo`Js+;l2=tWN>Ec?#aB&_Dq1E$qwh za2<!TeBb_uMx*yM>~QRewIn@LcBv5Pr_h#A89oAd^~geZAeU71m+;yQ^>q7=by=;G zwuf+JHX$6>y<8rdrKB->wI2_tHP)y*W_B_pywIv@M+yBpc=I4kG-El6wuyIZL54$y zhC`qA7a5vB->)zJ!?au{4XoB6L}QnA#8IHq$9Oxz8>^scUD9K`J%gK{B`RZt>!NAI zrTTFs`f*&sotbpP&Lr@UXOo#!W-!wSwU#L=xS}6dxJPiUvN9IqSUx2bnJ|t?L$uh_ zo-^;ZZ=<P4rf|-}n0!U257}oOn}oFR42oE{%Fp7(Z?k+7F$3LDGsf?$Okj;rpFaJJ zZ&w?BCJLpdsx?@{{JtvgVw?0clP$zyfcxoc@V4JPr?3Wb{9F)gLdj~q+49h)QjiTc zn?7B>1Y;88Q`I^U*G0y_v`}vPi7M|YkiK$B`F6uCa)AxFB`a+JlYUZ{>(h>(S}@N6 z?Q{)z)K!dpwd$lF2S^hTU-PM26^9cy?2ojw`u*-q%~^n1wBb3$B&@QI3$q8~{G>$s znde+bpQu*Qgi51U!<eNOWTMYNH}bPgVCdz?+f_Dz_kP?U?@&#o$uX)Esx<0T)#+wg zBd4D`E}?M~N>>`qMeR)c83M3_O~dLnIbWKtxBSF3pf-aA1_w&2H9x;t!c^*@b-A9< z;Ed-rF=QHZRcE%0{xcwG(w0|+&Z}HkQrAx%mppBW4N|%Oz>GIvD?!5)d%h18^Dsdp zw5XgZw=J&=(d&Lm9keg|)cLb#OzYb6q7b}5fK{wjk<U*vz}iV{A&4Du=F8PuX}$_u z_B^b3Rb=(r8zr`I_Vn44XQN1yw7{f=D5<}t3qie6k6yGlcW^*xb<mg$22FPce?u20 z&sp%=gB=X#88!(_PA2HdF<Ew<?i|M$?#{sk{ve~DI)8qA!qL#T16qJd5by_%pE})n z=MPPY4DE_ZSH`QAxf+H=(>%e!PRsF=&&ngMou=lPND%OIZlf~icmeX<goI4FFa!iV zl?t9|Z%)RkpFSS|gFy_e0p(g_+E1O3XFH591o6XRI!Fj7h|4|+I7lD9FLb>h3G=|d z%^|0RoVkf0B-9Sm6nfHxu_afC6O@-TqzXz5(-eBr^oM17)dfF(zPiv3V+xE310~O! z^W(U6y++JUVQ!3UZ0cYk=J%hUivsQNJ;qb?KFk7VGe3EL4v!8_#)b97Ag(oZWv0<U zU-_W#afXkZa63!|%w4I%Smd3bZ`1=iNM43lQ=%tTl-HZ<>XV!|*XcDMA>oJ8R0Cr- zg?D(i!`OnvhCN%FcU%`b(qv<S`OccqvBp9>Oi}1cu{p%-&GqyT>fYUpey*i!U}oqw z5TfmkX0cr8i42k$aT8^LLA#+>XE2dr1_}8ogRDK!gWDet%FvC;h8Ie*u0T6TQ0R*D z2NvdQx>*T@U7rb3+y!q!ffptWhUKtn^NVNCoEtxG24|EbNRqr%t?%9Ar|^);qGW(J zEHE%16xu0MeLpGT^>q;{!@X7z(L-)KYjzIJvK-h-J@h?rL(L?QZQ96+(bF;5pj=lg z6TPZ)6I0=LP_rY@nM7yBUL?bQ|2RASob2oP8PrL-!SA2I1mcC!5?8w5`h6i(^ZSq% z^OY`RQUy5MsMaOF%Zz>&QLVbcW#AxQ6oFE+)`G^<svET+7XT)jh@HA9s9DJb$*ULr zjKCg>>l3KO5j=pqTVf?>vGMyQSa&>_aDxD<P@Z>DA0{-IOeW|tFxgym+QX)EQEF!l z^u!sa|Nqn5W^lZZ-j<B-rMJJ2-ks^{ZHA#~ojY@qgI4+s?cL+|an>_&Bha2a(D8hu zF);%#0f}8TybDs1RYY4S&ZK)!M7!g9Lqt31IM-`G`rZdgkoCO~?l(cGr7prTEaYl5 zoqBuF@JS&+><<Q>2PM9x21?CbMIkOQxzgQ(Y$7)IgfX%pYU;)Ud^-H}InzXc@EJjK z0!uw;)!N^}-Z|k+m7$wScRU3nBy7R{M!q-)Er1DoB8|>Dt{d=naDgHRaA7e_(l2UJ zfMf%ajAQTjQbVh=)7rmdRm2NePzR--bIP@Of9ugn*VE;S2Q<~n(Uvz8A|7GZHL;td z@HNplhiFbzsnd7k*+e{Rqc;npwekH-9@Zhpz(g48=Oh~jvQKuBZ8%=8%s5>UgU{8) zh#DpyCLSSohm8H`L3lXms)Ma`inL12Dc4&~zYk+7=={Ma%k|1)C!A}N^rgwgCTQH= z)HC^o9Mm4^kv}1?_r!*2-_vl)Uw=5cO{h*z`?2>ko=o2NGN9nLV8Jmnns*rX(=g6X zisBv(D1+J0;Z3Cm1r1u+oTRJPry711(FBmZy?Heyg9dF{MauP}K}!?;o``w(b&1(g zUD}7<2R%F4-wR1IAmO*VNXoFk;T(~X>BnXL+rD`fnL1^)xAs!%dT+WFuO52EArz0` za%te{R(EK6agtY4aGJ&jk3exi8G#aj`UFY>$_kVM)DNfW3^sgnst?Li*2iwWxLK`M zmfEL}V|ng5`SKcdC{HQt!ZH{7!#S=qj|~}DjE$i!u#;-l3?`b&syH*N^$bMV5X@9` z9ZtJ0Su5xu`SF>=bsU%Y%5ZC(o8l@tEe=Uze$uE-Nh#mQQd5fbGa=*ZZz8W4q+sn^ z&tZcb$G;JB2ON*CH?fBM&(|~U(eMTLAY%bSZN$LW55zjh+W>Eayh(**ySk%tb}V~Y zB>5FwvXMnIS;E+y#qO;6ww>!{#~xbIv?jFTrij^RrVAQ<p#pp9%}3!FSFYz_RGX)D zxT7eK!8A@k5;4n}Jtw%Av8XO{o|wop5H7HgUvz$l^|X=4vh_`Xd+I_jKdB47x)uk+ zU2pNiI)VKVZW5d`n*@tFPkb*9(L)RV>EfYvrfaVRPDz`)c1wai6R}ygZ$0O*E~Z6O zx-s9?ruI-BO>9+W#CEwezg=@{cN;2XT1iI`{cYT6-c~TR!DHnlf?ySHL9cFjzm}q; z?Z3;m(<E)#Hg*Q!zy;5l!I<8Ncw(ca4+cj-bi)J$J0t~lOVc3|(bU-iVOItV18OYv zDWhLbtuYB}CIac|yr3x(AeLfIum)(1HBs;s2joSFC`cDz>gg5smh=ia&Nv%Eh`?S= zS3=m1@U*LIeAb4_>LMm<IK;waT866C4?Mxf9d~+qdp_bqI-Pmq&hn;l1cO5)9a+Si zDn1rfjFpPxa(OWm99M>xv2{z=mATaOaCg0cEi+Wq7Rq6JxKyI`ei%h#|AD)0esYd} zd8@kYoxX$9&@>mC`tV3t<%HF~6+SDqG6Y_i|4Nt+X7G5qzUU{s#U|VU;l-*ObbZoy zpp;eUVJi&~Z49wnF}-~?K@c`XCuO)p34#kIP#f#I$wsTLR%0IF4nXiuxPaE*tzD(u z$5Kc+{`kCpDYoW1+mBajtLfu!s>mD>m1OpfZtE&%^t!E~XA8GD0|wH!ASLK@FCME} zqgmOzI!Jr!9SL}|GlqRJ?&pG4t_5zHaX-nvz`7JJ4cOH>kAV35q3fAv-JaPPG)#yK zOAs?|@6<r=WV1*%{`icl!9neDdk!1P*lP+ZVRQ4=(huMk7Q2HH9T_fW15#^8r<e+{ zhd-8b1lOt^m>xgx4EA1Rghhh`2xV}{s5Nz?dok;GE%Hjd8>u)nID~~+*PH3KA<?c* z-P!|TSp{ZWN26kft_F4{sa<&SK!^#(5r*4)PhqE#&djpO0dCDVS|0a}uvyt~T{wI! z<^zU~l0>Z}Z8$o_%i1skT_dK@18;Y{FR{Y`^7x54XA!;|ehj-bbC<emXr?EoVT!|H z4KXJ7qK5CWFufaj{FL}l(o^Ii1oa-?dixxk&M43%JK9y`{`XsC68PqCSfcESNvacF z1s-_c1=4r#-3yddr@9J!l*D+Dw|%@lyt;hKbm>q!;ZjnV?hNGx`{V|6l|CEq6xY*z z?}D1NzY%J_pLl<$N#z@%=KJU0A8OL`MyUDzr4DL8bFu1NBB%RVLWTwXKElEr?T3Qh zaij2wT**_RlVQq?W_VKb!FVm}#X@`Ujk1^$)@FL*Mwxb?pq+WiItsUis$QqmWABdO zWmEX8*TWI92Z+=Wn3M=qb9ktY`omZ|O-p8d*F%_lQ^s-%D7I!|j7`pUD6O9W(w+iX zh)CqMQ@TEkm#bw&tX1zqN5gX4K77m{g35y3?c>k@ypud4^8+F-4x8w6<thxZ=bULM zFvX2QoP^GnJs4$N|E4tw{r;|We~>Cmo8RbEx(8P@S(=3gy;-<4yN1P?__HL&+V(52 zv=gu3R~&5BtD^1V*hsnQKyX9pkr=Mmnl&s#p*E~THBCBw{5n;j1dtw}aG^sDzYrpt zB^=U7MRaQ%mO4D_$u-@ZnOyXoJ=jY6R0q92jch$S!J0DY;uM|*i0M;EkJiK|TT_0l zy1L7=^n+YrIqutCg<xG{6@z|1O+hdH-p(CE!aQ~ZF#XrsIc_zEp@{OV4llZh$oi1Y z_TWJTeaU`1QU>S~3m0s|2OZW5T%Y_zSx;lPeeM#Ut17LJqIN&lsqOnJdN?S$i+w}4 zt1+P0&+yhehw9^q`{Ez4++0{Lhse8@cmgGUxl^K_a2A|OkBec{`}c#OaK@(}HXICB z#0?*=oAz9vzH5n^7|b_sKxKWS<88`w5H$TdlW>2+T5gcuR-G8sE)S%7C%ek_CRdSz z<3e-rf0Y%a45LH5@jlbfqvBCLDSo1Q9zy{2jG><QQ-h^hiHB@vd6)nTD8%23P<+{b zEnd$BF%QFY9Bz3SxUs-WkZ5l^30mM_lQ}Yp{j_q&7E~D1$54az?W9-UEMvLlCJR@$ zv@;KHlZsoyktKTX!6Jf%4ECJn>HQKeZsE4dR9NQH1c0L}#gsu*Ob2KXA!z)h<Xugl zBnvNngVdn};=#5o=tCNrgFgCY*6~rSh;h<RNV&sn2D8x4yf=A>4r8N_iGQ2C&iA~| zVj3oCHEG+{f`<Kp-LuC04w;E|<_VX~yk-!=S+5gEXEPRJUePPflp`6s%9XI>>&l#M zAOC+WvkU1OBt5bW^ypssN4zSeMRSD}vz_{{CV5s$5(4}}XV~ahffq(NxNvzDlpsGc zEU8C_Fqf(!1_{J7&qH3bKVe<AlnqwAg-&O3s)FZuGRw9~(kmJ%X%Dq|oB`?Z5d<9K zOLz(RjE<@Fa=gw%eF^%Ix*zgVDnln)$<-&ha6CeCeF3SGlIzVVS5k6)0lDxwC+5;$ z2HY=j-2L{#wk3<7eppT+Z%Xohjd{nd3txKy9@^T+Fv+dNmeY9RLr%+?dPe1z(`sNj zBX!N_-(Sk0-mF1Jzq6EHPA=^9(p;_qZ~hf~xo<hO)Q8VQ-Gaj#2@W_sQ+!^DT}Yq| zdnqZykfyD{_P+C2P2u##F4tSEIe8&+v~-fA&5_^yKJlC1Q`ld?SymXedyOmXjE(FJ zg<CjjxWhbJhGrn<GLGhfz|YG&lKT0})+|q;^dT;V4ufP{iOZ2BO2MZTC5m-5%~V(; z+snXkHNzDtWC#rc@iAyu+&jfggFP@Pn4^9AG)nig+{j>5eHy1(;Y3;jgXoiFqm1Zd zcwvrp91_;z>22x^303yW`a_80j6T&g{7F{R4kCY*JV}XTK@w!(t;>H-4xhled6Uqt z>$s9&eG(OLn&;cwaL>=TaN-un6F6q`I5l3*hn2(;==L_;uA8KNPqmI=Tvd6fy4)Si zV``P7$1tcjOuy|I^<&w0V)@aGA8$6AMmT~r3X5bRjF3Qc!u9)T;W#Nf&wWlEh@iPU zqgmaVJ=x-7?h^ccV7U=hN^|>KSD8JI(&Zpety+f@me~3A(|pZI7pm4YVNwnbTO7Eh zUncR+ka+eWNoMDA2_YVZD#+Ob8v#r5CIWGr6*IM*uSDFi2x6E*T@(|_QF34;9~j^z zddxup-SS}>+RRls4g<D|!(SY4-{we(>qjtUktOlGn!IKOtd<xP7Q##cKZ%(qaf&yN zDaZJZ&$Fd9-27BYnyNikD$zwsAqHbt2|THOKjeQf{|<r(ayoL;IWwWqjP5K{oTeNo zUo#^kr(wvqthZus*;D-59gZz>K9=zjsa7ajj88H^X`ANMec8TjU54?=4A9FMs3ly; z2vcob&moncyrj!bxO<gK1e!Q*2P>r?n}Pu|1KqDWU3YMvtJTD~ArK_$44W`YZ($?l zxSI4`d$S<!m_|)bZMY|)x!teZynUFrW!{9b;$5+lNCxL6yx+tU*yENxl+cWcT2C^u zY@Yp>6EdeTC%hG#g1SO-Df@B^f(K^<sAh5Nr)pipQO40^dwaCKMTrs|NTQmRFUt`p zIiXaj0B`hTVf?u~77%X4br;7&r9hr&-zoYU%!XxyCOYRBMOCCdz!P$_^dA=^moc+k z2EVQt(_u(AF&A=M!Ozk~za(-{tV)n>NeN-U1toTO5lwoRN~QZy^T6KT9(~uUVXI1V ztz**rXw+M_ex2|~!U!V}`l9x24~v9-?+qmKH(;@X&tbqyV2;3>cG>!FVjx~HreG7i z%o3*P6eL2&=)zG!c@`wZOm0r-H<2%54u~buZrN|L;OQLy<y^#Z)PDFl?f!Y?;E)5i zCS+a|<1gLT%h%-#lq0{M?yDh+hN`PE98IBG0XF2Zl|b;EfMNh$8S~@LC47l)*<RQz z$GHYYaY-&=^A=kbdoYp5u0jb=^3^$k;|2y>ShG0rGMmQXZsD{sep0}#HMspF`x!Ez zo${P^uxm7$F>wiT&Tf&WoJ3`s5V<D)Y(ydagA55xKJ)t;x;hQz6!ULVu)`5d3PBWR zfT(xO=}3;@0=prcKq>Q$?5Ehnk?`AP&u{H;=#dSEQMx2TP>}TcKo5qUQK#Fve*I~b zA9Xt5&XQ&i0v^uv;=mNl!E<T74Tq;731{PGLlBTT^eSh;Ate!_bSPtXutdu~+Ql03 z@fRr8m>1nVPQC|riION!=ms8#501{buvPOIW29jTvgf+v_F~U5I;1rNZVS&xa?i2J zFULf=rGUM1<OVE>GfLCY=V%kjv)^{2imVe}^;W_x6FOfCp;3V6Dk1J+OqYW`9lnRA zLF>DbSCW&vSJI~TOTkxaN_(P4caCA^E9E+mnL+s>;wsM&HS*hCL{!Rf1q_>6zYond z6%Fw27%i;nwh8o@Y>b-SMH+@e(_6CTP3?LF(hhT0M0-s&4=lOPj)k8&SS!y@s`B9v zkX?Y-YVT^w=XTa@NN36l^HCWXe`${yMA_&0DFo50j2q}@P_lm86rU&DYn1SBy+K(A zStHs1&2Wc40gaPGMt>f7WY-r*tvDg$n-Mrq{CPRB&o8-5weZ~+Z2W4<HkrsZj{^G{ zctwf)GKvc~o0z-|r?CdOk|cxSmIq-G$b}$%eDJX?VA@V334A7FpV1+6Mtd!powGQ! zJbwT;m`1dT6S<9}CGs^Bld6yI?(!D%5$#rf|74YBVH200FE6;&Ha11i9({4*bn&E~ zWGxdsYf|hJF)UkiMwf?O&qL+r{Ve>_wdZoy@>AyUnS9yDkHd4-A9x0BnW{A|nSSAF z-W>1dKCqnO!?vF|xCrjujOD3nIpAcvaRb}W!$ju%|NVr-lR@_IMP43d+_!oA4sQPK zJ^sY9pWpql0{#7-M6!-qo9H*0C?8@998cCJi<3roc9I!?s<r7dOm|O|uH$61HYvS8 z#Nont8)RjBQ#OggGMHCq#9II+s2+ELY!KvOwm}19G>hj!m^APh(6aHzeSN=g43-<y zHQQM#H*#eYR5nmCl_1F7KX{zsKp^yP?$2$+GuU#Ka;PBt8@eLt%;3uoceqy=`bPLS zF<B>;mEF`671g;ne^_;HDrs)-Xl}%4ZkhNw(xjodSC77YjPZ~2c96Fxcsqg{_Qz*5 zobNFy@QLx$!r80Tgn8oRaAnTVU<mEu(2z~Pc~lJT6}zz<5yMJ#Uemy9_6}v6P6m>u zRMh9mF=-ll-P6zLvrIS6+p{b^4M!#qM_KfTn3SevF~*8zRMS{#7R4{{Esa}Z2Nd&* ztW@+xBH8%DxufIbC(o6RPE4FWHFoyo*!c;6Lm2to_=%(EPfmyeE{c{+ydttRSAP^T z!EsHxpM)e8wc|&K{+8%l0N}7Pj)sU8kKGGzcPeypMpQRgy{DNW6S_nBDK1fZ+#E#M zifWKKI4>idTL6~(T}Z~n<{V6V!Jn(k1YK-~0j1=R7~6bXf~!!hSM6+kC_zV@A$u^M z!Pk^BI0`v*)6k~j4MR5%9nQpu(sa+^p9gu(e=}e%>dfE7nKHw;^`BuH3jE$b&5yiH zEFoeYmhfOa2PdJyILpt)w&F-}%7$(gA4>J&xN&F@6U~U^#Y#QMyI$OlvE2A=2j39t zw>f1fGaQv{VuyOdTL)O5Tr$@$J%l6D{Iicz0i254=+PneVhANtzz-_Om5ZaSBzhBg zy6P8an&6Lq9z^O+C`Sr1hvbr!;1T(r7HCfT(<IFQ2rl6mJD13jqlibW9ZbhR`vULq zPsIl9;mlCZ#+S1;$7~$<#of*#=Mb>w_HSnHbj}_D{*iPlp3CKia+_Fll#;-gYm%T4 JN~R^{{{pGe>>U6A literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py new file mode 100644 index 0000000..ae67001 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/appdirs.py @@ -0,0 +1,608 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (c) 2005-2010 ActiveState Software Inc. +# Copyright (c) 2013 Eddy Petrișor + +"""Utilities for determining application-specific dirs. + +See <http://github.com/ActiveState/appdirs> for details and usage. +""" +# Dev Notes: +# - MSDN on where to store app data files: +# http://support.microsoft.com/default.aspx?scid=kb;en-us;310294#XSLTH3194121123120121120120 +# - Mac OS X: http://developer.apple.com/documentation/MacOSX/Conceptual/BPFileSystem/index.html +# - XDG spec for Un*x: http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + +__version_info__ = (1, 4, 3) +__version__ = '.'.join(map(str, __version_info__)) + + +import sys +import os + +PY3 = sys.version_info[0] == 3 + +if PY3: + unicode = str + +if sys.platform.startswith('java'): + import platform + os_name = platform.java_ver()[3][0] + if os_name.startswith('Windows'): # "Windows XP", "Windows 7", etc. + system = 'win32' + elif os_name.startswith('Mac'): # "Mac OS X", etc. + system = 'darwin' + else: # "Linux", "SunOS", "FreeBSD", etc. + # Setting this to "linux2" is not ideal, but only Windows or Mac + # are actually checked for and the rest of the module expects + # *sys.platform* style strings. + system = 'linux2' +else: + system = sys.platform + + + +def user_data_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user data directories are: + Mac OS X: ~/Library/Application Support/<AppName> + Unix: ~/.local/share/<AppName> # or in $XDG_DATA_HOME, if defined + Win XP (not roaming): C:\Documents and Settings\<username>\Application Data\<AppAuthor>\<AppName> + Win XP (roaming): C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName> + Win 7 (not roaming): C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName> + Win 7 (roaming): C:\Users\<username>\AppData\Roaming\<AppAuthor>\<AppName> + + For Unix, we follow the XDG spec and support $XDG_DATA_HOME. + That means, by default "~/.local/share/<AppName>". + """ + if system == "win32": + if appauthor is None: + appauthor = appname + const = roaming and "CSIDL_APPDATA" or "CSIDL_LOCAL_APPDATA" + path = os.path.normpath(_get_win_folder(const)) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('~/Library/Application Support/') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_DATA_HOME', os.path.expanduser("~/.local/share")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_data_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of data dirs should be + returned. By default, the first item from XDG_DATA_DIRS is + returned, or '/usr/local/share/<AppName>', + if XDG_DATA_DIRS is not set + + Typical site data directories are: + Mac OS X: /Library/Application Support/<AppName> + Unix: /usr/local/share/<AppName> or /usr/share/<AppName> + Win XP: C:\Documents and Settings\All Users\Application Data\<AppAuthor>\<AppName> + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + Win 7: C:\ProgramData\<AppAuthor>\<AppName> # Hidden, but writeable on Win 7. + + For Unix, this is using the $XDG_DATA_DIRS[0] default. + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_COMMON_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + elif system == 'darwin': + path = os.path.expanduser('/Library/Application Support') + if appname: + path = os.path.join(path, appname) + else: + # XDG default for $XDG_DATA_DIRS + # only first, if multipath is False + path = os.getenv('XDG_DATA_DIRS', + os.pathsep.join(['/usr/local/share', '/usr/share'])) + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + if appname and version: + path = os.path.join(path, version) + return path + + +def user_config_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific config dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user config directories are: + Mac OS X: same as user_data_dir + Unix: ~/.config/<AppName> # or in $XDG_CONFIG_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow the XDG spec and support $XDG_CONFIG_HOME. + That means, by default "~/.config/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_CONFIG_HOME', os.path.expanduser("~/.config")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def site_config_dir(appname=None, appauthor=None, version=None, multipath=False): + r"""Return full path to the user-shared data dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "multipath" is an optional parameter only applicable to *nix + which indicates that the entire list of config dirs should be + returned. By default, the first item from XDG_CONFIG_DIRS is + returned, or '/etc/xdg/<AppName>', if XDG_CONFIG_DIRS is not set + + Typical site config directories are: + Mac OS X: same as site_data_dir + Unix: /etc/xdg/<AppName> or $XDG_CONFIG_DIRS[i]/<AppName> for each value in + $XDG_CONFIG_DIRS + Win *: same as site_data_dir + Vista: (Fail! "C:\ProgramData" is a hidden *system* directory on Vista.) + + For Unix, this is using the $XDG_CONFIG_DIRS[0] default, if multipath=False + + WARNING: Do not use this on Windows. See the Vista-Fail note above for why. + """ + if system in ["win32", "darwin"]: + path = site_data_dir(appname, appauthor) + if appname and version: + path = os.path.join(path, version) + else: + # XDG default for $XDG_CONFIG_DIRS + # only first, if multipath is False + path = os.getenv('XDG_CONFIG_DIRS', '/etc/xdg') + pathlist = [os.path.expanduser(x.rstrip(os.sep)) for x in path.split(os.pathsep)] + if appname: + if version: + appname = os.path.join(appname, version) + pathlist = [os.sep.join([x, appname]) for x in pathlist] + + if multipath: + path = os.pathsep.join(pathlist) + else: + path = pathlist[0] + return path + + +def user_cache_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific cache dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Cache" to the base app data dir for Windows. See + discussion below. + + Typical user cache directories are: + Mac OS X: ~/Library/Caches/<AppName> + Unix: ~/.cache/<AppName> (XDG default) + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Cache + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Cache + + On Windows the only suggestion in the MSDN docs is that local settings go in + the `CSIDL_LOCAL_APPDATA` directory. This is identical to the non-roaming + app data dir (the default returned by `user_data_dir` above). Apps typically + put cache data somewhere *under* the given dir here. Some examples: + ...\Mozilla\Firefox\Profiles\<ProfileName>\Cache + ...\Acme\SuperApp\Cache\1.0 + OPINION: This function appends "Cache" to the `CSIDL_LOCAL_APPDATA` value. + This can be disabled with the `opinion=False` option. + """ + if system == "win32": + if appauthor is None: + appauthor = appname + path = os.path.normpath(_get_win_folder("CSIDL_LOCAL_APPDATA")) + if appname: + if appauthor is not False: + path = os.path.join(path, appauthor, appname) + else: + path = os.path.join(path, appname) + if opinion: + path = os.path.join(path, "Cache") + elif system == 'darwin': + path = os.path.expanduser('~/Library/Caches') + if appname: + path = os.path.join(path, appname) + else: + path = os.getenv('XDG_CACHE_HOME', os.path.expanduser('~/.cache')) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_state_dir(appname=None, appauthor=None, version=None, roaming=False): + r"""Return full path to the user-specific state dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "roaming" (boolean, default False) can be set True to use the Windows + roaming appdata directory. That means that for users on a Windows + network setup for roaming profiles, this user data will be + sync'd on login. See + <http://technet.microsoft.com/en-us/library/cc766489(WS.10).aspx> + for a discussion of issues. + + Typical user state directories are: + Mac OS X: same as user_data_dir + Unix: ~/.local/state/<AppName> # or in $XDG_STATE_HOME, if defined + Win *: same as user_data_dir + + For Unix, we follow this Debian proposal <https://wiki.debian.org/XDGBaseDirectorySpecification#state> + to extend the XDG spec and support $XDG_STATE_HOME. + + That means, by default "~/.local/state/<AppName>". + """ + if system in ["win32", "darwin"]: + path = user_data_dir(appname, appauthor, None, roaming) + else: + path = os.getenv('XDG_STATE_HOME', os.path.expanduser("~/.local/state")) + if appname: + path = os.path.join(path, appname) + if appname and version: + path = os.path.join(path, version) + return path + + +def user_log_dir(appname=None, appauthor=None, version=None, opinion=True): + r"""Return full path to the user-specific log dir for this application. + + "appname" is the name of application. + If None, just the system directory is returned. + "appauthor" (only used on Windows) is the name of the + appauthor or distributing body for this application. Typically + it is the owning company name. This falls back to appname. You may + pass False to disable it. + "version" is an optional version path element to append to the + path. You might want to use this if you want multiple versions + of your app to be able to run independently. If used, this + would typically be "<major>.<minor>". + Only applied when appname is present. + "opinion" (boolean) can be False to disable the appending of + "Logs" to the base app data dir for Windows, and "log" to the + base cache dir for Unix. See discussion below. + + Typical user log directories are: + Mac OS X: ~/Library/Logs/<AppName> + Unix: ~/.cache/<AppName>/log # or under $XDG_CACHE_HOME if defined + Win XP: C:\Documents and Settings\<username>\Local Settings\Application Data\<AppAuthor>\<AppName>\Logs + Vista: C:\Users\<username>\AppData\Local\<AppAuthor>\<AppName>\Logs + + On Windows the only suggestion in the MSDN docs is that local settings + go in the `CSIDL_LOCAL_APPDATA` directory. (Note: I'm interested in + examples of what some windows apps use for a logs dir.) + + OPINION: This function appends "Logs" to the `CSIDL_LOCAL_APPDATA` + value for Windows and appends "log" to the user cache dir for Unix. + This can be disabled with the `opinion=False` option. + """ + if system == "darwin": + path = os.path.join( + os.path.expanduser('~/Library/Logs'), + appname) + elif system == "win32": + path = user_data_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "Logs") + else: + path = user_cache_dir(appname, appauthor, version) + version = False + if opinion: + path = os.path.join(path, "log") + if appname and version: + path = os.path.join(path, version) + return path + + +class AppDirs(object): + """Convenience wrapper for getting application dirs.""" + def __init__(self, appname=None, appauthor=None, version=None, + roaming=False, multipath=False): + self.appname = appname + self.appauthor = appauthor + self.version = version + self.roaming = roaming + self.multipath = multipath + + @property + def user_data_dir(self): + return user_data_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_data_dir(self): + return site_data_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_config_dir(self): + return user_config_dir(self.appname, self.appauthor, + version=self.version, roaming=self.roaming) + + @property + def site_config_dir(self): + return site_config_dir(self.appname, self.appauthor, + version=self.version, multipath=self.multipath) + + @property + def user_cache_dir(self): + return user_cache_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_state_dir(self): + return user_state_dir(self.appname, self.appauthor, + version=self.version) + + @property + def user_log_dir(self): + return user_log_dir(self.appname, self.appauthor, + version=self.version) + + +#---- internal support stuff + +def _get_win_folder_from_registry(csidl_name): + """This is a fallback technique at best. I'm not sure if using the + registry for this guarantees us the correct answer for all CSIDL_* + names. + """ + if PY3: + import winreg as _winreg + else: + import _winreg + + shell_folder_name = { + "CSIDL_APPDATA": "AppData", + "CSIDL_COMMON_APPDATA": "Common AppData", + "CSIDL_LOCAL_APPDATA": "Local AppData", + }[csidl_name] + + key = _winreg.OpenKey( + _winreg.HKEY_CURRENT_USER, + r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" + ) + dir, type = _winreg.QueryValueEx(key, shell_folder_name) + return dir + + +def _get_win_folder_with_pywin32(csidl_name): + from win32com.shell import shellcon, shell + dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0) + # Try to make this a unicode path because SHGetFolderPath does + # not return unicode strings when there is unicode data in the + # path. + try: + dir = unicode(dir) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + try: + import win32api + dir = win32api.GetShortPathName(dir) + except ImportError: + pass + except UnicodeError: + pass + return dir + + +def _get_win_folder_with_ctypes(csidl_name): + import ctypes + + csidl_const = { + "CSIDL_APPDATA": 26, + "CSIDL_COMMON_APPDATA": 35, + "CSIDL_LOCAL_APPDATA": 28, + }[csidl_name] + + buf = ctypes.create_unicode_buffer(1024) + ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in buf: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf2 = ctypes.create_unicode_buffer(1024) + if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): + buf = buf2 + + return buf.value + +def _get_win_folder_with_jna(csidl_name): + import array + from com.sun import jna + from com.sun.jna.platform import win32 + + buf_size = win32.WinDef.MAX_PATH * 2 + buf = array.zeros('c', buf_size) + shell = win32.Shell32.INSTANCE + shell.SHGetFolderPath(None, getattr(win32.ShlObj, csidl_name), None, win32.ShlObj.SHGFP_TYPE_CURRENT, buf) + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + # Downgrade to short path name if have highbit chars. See + # <http://bugs.activestate.com/show_bug.cgi?id=85099>. + has_high_char = False + for c in dir: + if ord(c) > 255: + has_high_char = True + break + if has_high_char: + buf = array.zeros('c', buf_size) + kernel = win32.Kernel32.INSTANCE + if kernel.GetShortPathName(dir, buf, buf_size): + dir = jna.Native.toString(buf.tostring()).rstrip("\0") + + return dir + +if system == "win32": + try: + import win32com.shell + _get_win_folder = _get_win_folder_with_pywin32 + except ImportError: + try: + from ctypes import windll + _get_win_folder = _get_win_folder_with_ctypes + except ImportError: + try: + import com.sun.jna + _get_win_folder = _get_win_folder_with_jna + except ImportError: + _get_win_folder = _get_win_folder_from_registry + + +#---- self test code + +if __name__ == "__main__": + appname = "MyApp" + appauthor = "MyCompany" + + props = ("user_data_dir", + "user_config_dir", + "user_cache_dir", + "user_state_dir", + "user_log_dir", + "site_data_dir", + "site_config_dir") + + print("-- app dirs %s --" % __version__) + + print("-- app dirs (with optional 'version')") + dirs = AppDirs(appname, appauthor, version="1.0") + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'version')") + dirs = AppDirs(appname, appauthor) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (without optional 'appauthor')") + dirs = AppDirs(appname) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) + + print("\n-- app dirs (with disabled 'appauthor')") + dirs = AppDirs(appname, appauthor=False) + for prop in props: + print("%s: %s" % (prop, getattr(dirs, prop))) diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py new file mode 100644 index 0000000..95d330e --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__about__.py @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "16.8" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2016 %s" % __author__ diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py new file mode 100644 index 0000000..5ee6220 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__init__.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0fc54a5ac1953bc9d74402dc02481eb7b0c643bf GIT binary patch literal 693 zcmYL{&1xGl5XX1D{#dW=#BD>)YM=!}<4r;crIeB;IhK-Q=s^_3dPiO>*_Bj%xY#e# zbKj<CUwi5+^wd#Ih=hL3h|ym&BVCO~S%icBeEscrD~kRE=W(QHT;j5~2#6rAqb8<t z)1s{=p-CJ;3leBU2fEOM6#7+4+mO)?3}_dIv<D-a!XE9zKFwfE2k?yd4<kB+=d)<? z;xDR3lVrPJ%&n@u<4iPK8MjSAtb`RxZuhhi(y@h?r3-$aF(+Kj8QTsRv%YBxvqq=K zm^Wg#yW%FCMJHpd@NTIL+IW&Tg{XHiwJ5o?L1x5Qsr1^2YUx6lF3S6&60+JHT`R+h zccK<fa7z}-klQuNNwN##cJp%SoVM@syb^Bd=hIR(xnAocf0AjRUQFL^CO1kJHISL} zi-jYF1R`W86MRvVQb}jT+&g9LW(*IZm-ZoaD%9raYIZ~L_K&E#<mA&X`8VY2u2OO~ zJ=q*yKUP7`PEOB{5f|i@{X7|kHY~jJ2Fo@0#F0q?+KAA%qQ;(>PT1-O^a8@mn|?s} z9cB<PMEr`(IM@OIzT~daxfc3ZNb6ANxcpJcJNNxOx7>N{l&Wp6?<;1wRo;}`=4{0! pDD%{x95a|JkG-Gj^)`LqDDXA^5VEreh=U}Hv!os4Y~c)y{{wp&&zb-L literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6ca5cea8c61a7f78f5d8e58feaa19cd0ae59fa10 GIT binary patch literal 531 zcmYk2OODhq5Qd$kJI~G_B+h{7#gGk4gb)WnNW;oPDrI6%#*AP1(Wp<unk!|?YOcVF zs%e2J$)Bq1di<^r<JdDa{^RABqGaqB1%ItY=RKbI86lV`G&2P+Ovy`A@v2~=6qVkY zJ>Q#}*QVi(X?bfp-kF~FX5fQ4@B`-U#9q{*5v}M%FNU?{qd45K<M@c3*|FN5&9~9% zoFpjYT}WFi)Ja9<>~`gYvI*|8T@uER1y!_L4>0F+?*hO!0xZs-gIezsh8=)3v(o4e z09q~5MtKQhHf9dzOHxuv(|rSwgSsS~WT2@4VZb?omJ<$ykx&z8EukYch>yoB(sGwm z4%jT<5?QDSI|ON&Z(T-NmtrdUuftRSr%C^Ykepeg_@691r)<LSPg62}^2%Q;8xy`? zFW*=DHGO+CMVYcs&gnS$hZTa1E{8?N2~N@q7bZV15A&+*IsquFP|It7-rBduiLB*2 O(i!PzFUnVSU;F_G$&PaX literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b82d2cce5de0ab2004641eacb298b948f420d8bd GIT binary patch literal 983 zcmah{OK%e~5cXq}Y(ttJs4DR|giECynw5ZKRUts)R*;a8SXHvzwUchUuiD;LsmiI9 z+J6BY`AfcX>R;f*jMIi94vaM8nX&!NH)FqEUF{Q)^y}u{9w+1{26w{1c?D`efl)-! zf|N9+B}-Y!Q%*6*iYSeAbl6ek5mEezrQKx|LDbVd^H#@Gnyyq`-N#jRRQHmk4;1@I z#=RTBCS&f`<i4$o)@hNKO>LZyReqA&ysrGPF?r?0w5>7+@$L;0y8*T&qj(zxgDz+f z)NX=#N3O^foiargyNngPrWgDRbL1O6XNs#RC*LC|-#JVABak;nOQ%P2v@fk5WrehM zbeg*Z$dua2keGy%8GtVZ%c9uFU^GdoA}PCHIOU2%nds~pqKQ9P+eMwp!tP9#sVoXm zgy4$$5Y!I9T+?%UP0slRLebqHfaiHuSRYlg)V}Wyax0Ly^;C_S?=1WXp$$&t*Zahk zP15AeR$f^ri()G~omGeK_+?_XYa3VBg-x2HnK0Vct;w`a#EGs{ZIVW2M{<@|vqWTd z*+@5O=DsIHrB8);iX8Dd2t6DBx5dfrtzBp!1|Qf9;rl|AwQ39W2SOaTvRLexHNXuG zjG4hfnAN+48G`3mmcx4jVc-!{gLCt1PUAO{W-h|x-NN|D%^Mwn$9w@7fbq`1l|qr> z-)*g9rSMd}4Q@6d8V|6AY3o`8Ef}1J!H;3^l;?JC{oq6!{K_J)rnToEK0inE0ydrT q128aNfy}J$hsO(<fF4-gGl5gQy_nbzmav#wXE7hrVHDArb@^`-x%e{x literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8e0efa0e184525d5a9890ad1f57d569cfd48eb3b GIT binary patch literal 2835 zcmcImOK;Oa5Z<*D$4S#Rh4L0iTtJp6kq}5oAXFX#amfWv7ShUix2cO`ySwY6R=tG- z|AI4r$yZMN1y0OtYDg*@hu20sv-a%nH#<A?IZswsdjy*Q>BgInZ9=}_L)ls|*oLm2 zf#8JGm`tcoCzfwbY~QBj1>qLAKM-z<*3|afqCF*k8{W2f8{W3fTSqwX*5S@8;&r~l zPQ<f|_28{a<6H|CO|n$#!sXFHq@pw_)-o9-n(gFCsNp%p6=kzvunk?k1|f(~Iq@w{ zx%GkgHn({TG+=WFbeng$3)<mb-UHp?E4&Zd<*R%RbeFI50q7pz;AcRu@U!6IX5qd} zcA_NGham+JY^bq6g|09toWe|NBq3nrGx2EAQX<}w4m=w1?bT3EvSAiwTT!BP5XW2L z`*E_T_wNps(0QiQG*-jx-Iz(C(p-i@4cUQ6cq)fk5WWk>Q8FGfrDY!K9Om544hxsT z>`XG&ML#eUgdS~_-rg>)3vSym$++EzfhL+BlPR5|`*h@4MQb-uyG0AP^{DK?oS%n~ zE<7SA&S4BUr~;i?L*ouiL0uKA=VoKiG9X1e)w@ET#&Q^oHDl{@Nb7UQL)-7+$W_>? z3Pmt>rVa&c3n-^Tcnl%jqf@I4VGptv?>GrX(S@aPpcG>#2d#5J>@#+*#sRcdJFo^T zG$|eElM@%@08hCAq5(C5qg|{)McV>u)g`{3zr?z;jp3TE)S#g4AEAK1*XmI4Ea*Qr z)C*_PCvl_2U?j$Yjt)ebWHmL=VJs12#;(IwWeE(*HBfiPIP&^fEJ-i{^rFYuB;|RG z<33~ic@WPm5{p-2F-g2miODW87v)(Ln<y|d<OLKz7-crXiZrBym8x)+Yq|E~&)7pS z{b*Q{+tB|bY0C4ke|^YL`0}W`RYq-=NR^ahBIKdJhEwR#rPJ5+CsZf#GbdL-R9~{W zl3NX^OLARfnV72|&VgO1IO0-t*9?UTcBcsn3&unnCZhf|=PgAzCaLc=0RJDZGo^ID z0eUIITli{K5uPd72Mth5v0gJ2(!!%AsO6~7kVH)(An`n&gSl9dn<e8({G7;3C@!P; zYjQâ|F+|WMqI>@g(IsP+(e?6G65;Ioff3w0#-|mS}n<E-ts$$W?eK_OiN4Q2I Lv2NOfs}A(<TLbm@ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..630a5b5d8c53f216725252ee02142da16ccdc56e GIT binary patch literal 8843 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..87a21f9ab12f46ae5ccb66dbc57a4a07fe749681 GIT binary patch literal 3848 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6c318f5c6d218ec5f99e60ddd87c2adfec1801fd GIT binary patch literal 19761 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ff1326160ccd15ae68fae586e4467132c2bd9bb9 GIT binary patch literal 462 zcmY*Vy-ve05VoB(jSA&Q@C-;1N+Tgggb>VhVGAHDjZI|g*v58Rs2F(<+JS*r^2)?3 zbi%HL1Sj3+yYrpD`+PYZ4uH4v{pjuk0`L`*UyFQj;oY2gAb>y)T3Essm8gx%2!<Ns zaT(Ki*(1>kmI;YT?+uiFf^I;TeET_&MQ*p67|A<JF>967)}@5am|;@59i^GD_@NWE z_4#;_+~#<6e_Z=zHWtp<`;~XI=fQ#{B=8li&=ReHr$OU2%stBit}7u0t1HeH6l>bh zXBU}n;(A=psm`E_Mb*+zpo8Z1bzxgoD5i2IjIB7&>v<y{?bB&tsO^-MlAA(J8~>D% zovx`V@Qex~b)l+yS~W~GMQ0f|BlY6;|FH+6?XWWP0FVxGmbwA<Qf;Rx#yZ^S@W(pn ob4XLyuVt$kr#cDcFtb_p4{U|j^sJSn<MccXn$UZQ(r6I<06-*p6#xJL literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf960fe5b80a873756aa03de102e6e7574ca2180 GIT binary patch literal 10528 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py new file mode 100644 index 0000000..210bb80 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_compat.py @@ -0,0 +1,30 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, + + +def with_metaclass(meta, *bases): + """ + Create a base class with a metaclass. + """ + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py new file mode 100644 index 0000000..ccc2786 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/_structures.py @@ -0,0 +1,68 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + +NegativeInfinity = NegativeInfinity() diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py new file mode 100644 index 0000000..892e578 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/markers.py @@ -0,0 +1,301 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from pkg_resources.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from pkg_resources.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from pkg_resources.extern.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +class Variable(Node): + + def serialize(self): + return str(self) + + +class Value(Node): + + def serialize(self): + return '"{0}"'.format(self) + + +class Op(Node): + + def serialize(self): + return str(self) + + +VARIABLE = ( + L("implementation_version") | + L("platform_python_implementation") | + L("implementation_name") | + L("python_full_version") | + L("platform_release") | + L("platform_version") | + L("platform_machine") | + L("platform_system") | + L("python_version") | + L("sys_platform") | + L("os_name") | + L("os.name") | # PEP-345 + L("sys.platform") | # PEP-345 + L("platform.version") | # PEP-345 + L("platform.machine") | # PEP-345 + L("platform.python_implementation") | # PEP-345 + L("python_implementation") | # undocumented setuptools legacy + L("extra") +) +ALIASES = { + 'os.name': 'os_name', + 'sys.platform': 'sys_platform', + 'platform.version': 'platform_version', + 'platform.machine': 'platform_machine', + 'platform.python_implementation': 'platform_python_implementation', + 'python_implementation': 'platform_python_implementation' +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # where the single item is itself it's own list. In that case we want skip + # the rest of this function so that we don't get extraneous () on the + # outside. + if (isinstance(marker, list) and len(marker) == 1 and + isinstance(marker[0], (list, tuple))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "sys_platform": sys.platform, + } + + +class Marker(object): + + def __init__(self, marker): + try: + self._markers = _coerce_parse_result(MARKER.parseString(marker)) + except ParseException as e: + err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( + marker, marker[e.loc:e.loc + 8]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py new file mode 100644 index 0000000..0c8c4a3 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/requirements.py @@ -0,0 +1,127 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from pkg_resources.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from pkg_resources.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from pkg_resources.extern.pyparsing import Literal as L # noqa +from pkg_resources.extern.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) +VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) + +VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY +VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), + joinString=",", adjacent=False)("_raw_spec") +_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') + +VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") +VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) + +MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") +MARKER_EXPR.setParseAction( + lambda s, l, t: Marker(s[t._original_start:t._original_end]) +) +MARKER_SEPERATOR = SEMICOLON +MARKER = MARKER_SEPERATOR + MARKER_EXPR + +VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) +URL_AND_MARKER = URL + Optional(MARKER) + +NAMED_REQUIREMENT = \ + NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + req = REQUIREMENT.parseString(requirement_string) + except ParseException as e: + raise InvalidRequirement( + "Invalid requirement, parse error at \"{0!r}\"".format( + requirement_string[e.loc:e.loc + 8])) + + self.name = req.name + if req.url: + parsed_url = urlparse.urlparse(req.url) + if not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc): + raise InvalidRequirement("Invalid URL given") + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..7f5a76c --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/specifiers.py @@ -0,0 +1,774 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=None): + match = self._regex.search(spec) + if not match: + raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) + + self._spec = ( + match.group("operator").strip(), + match.group("version").strip(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format( + self.__class__.__name__, + str(self), + pre, + ) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Determine if prereleases are to be allowed or not. + if prereleases is None: + prereleases = self.prereleases + + # Normalize item to a Version or LegacyVersion, this allows us to have + # a shortcut for ``"2.0" in Specifier(">=2") + item = self._coerce_version(item) + + # Determine if we should be supporting prereleases in this specifier + # or not, if we do not support prereleases than we can short circuit + # logic if this version is a prereleases. + if item.is_prerelease and not prereleases: + return False + + # Actually do the comparison to determine if this item is contained + # within this Specifier or not. + return self._get_operator(self.operator)(item, self.version) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # If our version is a prerelease, and we were not set to allow + # prereleases, then we'll store it for later incase nothing + # else matches this specifier. + if (parsed_version.is_prerelease and not + (prereleases or self.prereleases)): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the begining. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # Compatible releases have an equivalent combination of >= and ==. That + # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to + # implement this in terms of the other specifiers instead of + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not + x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return (self._get_operator(">=")(prospective, spec) and + self._get_operator("==")(prospective, prefix)) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # We need special logic to handle prefix matching + if spec.endswith(".*"): + # In the case of prefix matching we want to ignore local segment. + prospective = Version(prospective.public) + # Split the spec out by dots, and pretend that there is an implicit + # dot in between a release segment and a pre-release segment. + spec = _version_split(spec[:-2]) # Remove the trailing .* + + # Split the prospective version out by dots, and pretend that there + # is an implicit dot in between a release segment and a pre-release + # segment. + prospective = _version_split(str(prospective)) + + # Shorten the prospective version to be the same length as the spec + # so that we can determine if the specifier is a prefix of the + # prospective version or not. + prospective = prospective[:len(spec)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = Version(spec) + + # If the specifier does not have a local segment, then we want to + # act as if the prospective version also does not have a local + # segment. + if not spec.local: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is less than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is greater than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # Ensure that we do not allow a local version of the version mentioned + # in the specifier, which is techincally greater than, to match. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) + + # Get the rest of our versions + left_split.append(left[len(left_split[0]):]) + right_split.append(right[len(right_split[0]):]) + + # Insert our padding + left_split.insert( + 1, + ["0"] * max(0, len(right_split[0]) - len(left_split[0])), + ) + right_split.insert( + 1, + ["0"] * max(0, len(left_split[0]) - len(right_split[0])), + ) + + return ( + list(itertools.chain(*left_split)), + list(itertools.chain(*right_split)), + ) + + +class SpecifierSet(BaseSpecifier): + + def __init__(self, specifiers="", prereleases=None): + # Split on , to break each indidivual specifier into it's own item, and + # strip each item to remove leading/trailing whitespace. + specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + + # Parsed each individual specifier, attempting first to make it a + # Specifier and falling back to a LegacySpecifier. + parsed = set() + for specifier in specifiers: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # given version is contained within all of them. + # Note: This use of all() here means that an empty set of specifiers + # will always return True, this is an explicit design decision. + return all( + s.contains(item, prereleases=prereleases) + for s in self._specs + ) + + def filter(self, iterable, prereleases=None): + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # which will filter out any pre-releases, unless there are no final + # releases, and which will filter out LegacyVersion in general. + else: + filtered = [] + found_prereleases = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py new file mode 100644 index 0000000..942387c --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/utils.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py new file mode 100644 index 0000000..83b5ee8 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/packaging/version.py @@ -0,0 +1,393 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(version): + """ + Parse the given version string and return either a :class:`Version` object + or a :class:`LegacyVersion` object depending on if the given version is + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def base_version(self): + return self._version + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + @property + def is_postrelease(self): + return False + + +_legacy_version_component_re = re.compile( + r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, +) + +_legacy_version_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch + # greater than or equal to 0. This will effectively put the LegacyVersion, + # which uses the defacto standard originally implemented by setuptools, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + return epoch, parts + +# Deliberately not anchored to the start and end of the string, to make it +# easier for 3rd party code to reuse +VERSION_PATTERN = r""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _regex = re.compile( + r"^\s*" + VERSION_PATTERN + r"\s*$", + re.VERBOSE | re.IGNORECASE, + ) + + def __init__(self, version): + # Validate the version and parse it into pieces + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + self._version = _Version( + epoch=int(match.group("epoch")) if match.group("epoch") else 0, + release=tuple(int(i) for i in match.group("release").split(".")), + pre=_parse_letter_version( + match.group("pre_l"), + match.group("pre_n"), + ), + post=_parse_letter_version( + match.group("post_l"), + match.group("post_n1") or match.group("post_n2"), + ), + dev=_parse_letter_version( + match.group("dev_l"), + match.group("dev_n"), + ), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self._version.epoch != 0: + parts.append("{0}!".format(self._version.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self._version.release)) + + # Pre-release + if self._version.pre is not None: + parts.append("".join(str(x) for x in self._version.pre)) + + # Post-release + if self._version.post is not None: + parts.append(".post{0}".format(self._version.post[1])) + + # Development release + if self._version.dev is not None: + parts.append(".dev{0}".format(self._version.dev[1])) + + # Local version segment + if self._version.local is not None: + parts.append( + "+{0}".format(".".join(str(x) for x in self._version.local)) + ) + + return "".join(parts) + + @property + def public(self): + return str(self).split("+", 1)[0] + + @property + def base_version(self): + parts = [] + + # Epoch + if self._version.epoch != 0: + parts.append("{0}!".format(self._version.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self._version.release)) + + return "".join(parts) + + @property + def local(self): + version_string = str(self) + if "+" in version_string: + return version_string.split("+", 1)[1] + + @property + def is_prerelease(self): + return bool(self._version.dev or self._version.pre) + + @property + def is_postrelease(self): + return bool(self._version.post) + + +def _parse_letter_version(letter, number): + if letter: + # We consider there to be an implicit 0 in a pre-release if there is + # not a numeral associated with it. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_seperators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_seperators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # When we compare a release version, we want to compare it with all of the + # trailing zeros removed. So we'll use a reverse the list, drop all the now + # leading zeros until we come to something non zero, then take the rest + # re-reverse it back into the correct order and make it a tuple and use + # that for our sorting key. + release = tuple( + reversed(list( + itertools.dropwhile( + lambda x: x == 0, + reversed(release), + ) + )) + ) + + # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # if there is not a pre or a post segment. If we have one of those then + # the normal sorting rules will handle this case correctly. + if pre is None and post is None and dev is not None: + pre = -Infinity + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - Numeric segments sort numerically + # - Shorter versions sort before longer versions when the prefixes + # match exactly + local = tuple( + (i, "") if isinstance(i, int) else (-Infinity, i) + for i in local + ) + + return epoch, release, pre, post, dev, local diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py new file mode 100644 index 0000000..cf75e1e --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/pyparsing.py @@ -0,0 +1,5742 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2018 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars +============================================================================= + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements +(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to +L{Literal} expressions):: + + from pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments + + +Getting Started - +----------------- +Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing +classes inherit from. Use the docstrings for examples of how to: + - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes + - construct character word-group expressions using the L{Word} class + - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes + - use L{'+'<And>}, L{'|'<MatchFirst>}, L{'^'<Or>}, and L{'&'<Each>} operators to combine simple expressions into more complex ones + - associate names with your parsed results using L{ParserElement.setResultsName} + - find some helpful expression short-cuts like L{delimitedList} and L{oneOf} + - find more useful common expressions in the L{pyparsing_common} namespace class +""" + +__version__ = "2.2.1" +__versionTime__ = "18 Sep 2018 00:49 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + # Python 3 + from collections.abc import Iterable + from collections.abc import MutableMapping +except ImportError: + # Python 2.7 + from collections import Iterable + from collections import MutableMapping + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', +'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', +'CloseMatch', 'tokenMap', 'pyparsing_common', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # build list of single arg builtins, tolerant of Python version, that can be used as parse actions + singleArgBuiltins = [] + import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + from_symbols = '&><"\'' + to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) + for from_,to_ in zip(from_symbols, to_symbols): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +alphas = string.ascii_uppercase + string.ascii_lowercase +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join(c for c in string.printable if c not in string.whitespace) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + + Example:: + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + Expected integer (at char 0), (line:1, col:1) + column: 1 + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like L{ParseFatalException}, but thrown internally when an + L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop + immediately because an unbacktrackable syntax error has been found""" + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup[0]) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """ + Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) + + Example:: + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + prints:: + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v, isinstance=isinstance ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,(int,slice)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return ( not not self.__toklist ) + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( self.__toklist[::-1] ) + def _iterkeys( self ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys (Python 3.x only).""" + + values = _itervalues + """Returns an iterator of all named result values (Python 3.x only).""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples (Python 3.x only).""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + def keys( self ): + """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iterkeys()) + + def values( self ): + """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.itervalues()) + + def items( self ): + """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iteritems()) + + def haskeys( self ): + """Since keys() returns an iterator, this method is helpful in bypassing + code that looks for the existence of any defined results names.""" + return bool(self.__tokdict) + + def pop( self, *args, **kwargs): + """ + Removes and returns item at specified index (default=C{last}). + Supports both C{list} and C{dict} semantics for C{pop()}. If passed no + argument or an integer argument, it will use C{list} semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use C{dict} + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in C{dict.pop()}. + + Example:: + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + prints:: + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + for k,v in kwargs.items(): + if k == 'default': + args = (args[0], v) + else: + raise TypeError("pop() got an unexpected keyword argument '%s'" % k) + if (isinstance(args[0], int) or + len(args) == 1 or + args[0] in self): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified. + + Similar to C{dict.get()}. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to C{list.insert()}. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def append( self, item ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + def __getattr__( self, name ): + try: + return self[name] + except KeyError: + return "" + + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = lambda a: offset if a<0 else a+offset + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + # useful for merging many ParseResults using sum() builtin + return self.copy() + else: + # this may raise a TypeError - so be it + return other + self + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + result_list = result.asList() + print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] + """ + return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a C{ParseResults} object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """ + (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. + """ + nl = "\n" + out = [] + namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + for i,res in enumerate(self.__toklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + prints:: + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + next(iter(self.__tokdict.values()))[0][1] in (0,-1)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + prints:: + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + items = sorted((str(k), v) for k,v in self.items()) + for k,v in items: + if out: + out.append(NL) + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + elif any(isinstance(vv,ParseResults) for vv in self): + v = self + for i,vv in enumerate(v): + if isinstance(vv,ParseResults): + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) + + Example:: + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + prints:: + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + s = strg + return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'decorator to trim function calls to match the arity of the target' +def _trim_arity(func, maxargs=2): + if func in singleArgBuiltins: + return lambda s,l,t: func(t) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + if system_version[:2] >= (3,5): + def extract_stack(limit=0): + # special handling for Python 3.5.0 - extra deep call stack by 1 + offset = -3 if system_version == (3,5,0) else -2 + frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] + return [frame_summary[:2]] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [frame_summary[:2]] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND + # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! + this_line = extract_stack(limit=2)[-1] + pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element. + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") + integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + prints:: + [5120, 100, 655360, 268435456] + Equivalent form of C{expr.copy()} is just C{expr()}:: + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + + Example:: + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def setParseAction( self, *fns, **kwargs ): + """ + Define one or more actions to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{parseString}<parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + + Example:: + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # note that integer fields are now ints, not strings + date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] + """ + self.parseAction = list(map(_trim_arity, list(fns))) + self.callDuringTry = kwargs.get("callDuringTry", False) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. + + See examples in L{I{copy}<copy>}. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, + functions passed to C{addCondition} need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) + """ + msg = kwargs.get("message", "failed user-defined condition") + exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException + for fn in fns: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + C{fn(s,loc,expr,err)} where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException as err: + #~ print ("Exception raised:", err) + if self.debugActions[2]: + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or preloc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException as err: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + - cache_size_limit - (default=C{128}) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + + Example:: + import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + def parseString( self, instring, parseAll=False ): + """ + Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}<parseWithTabs>}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + + Example:: + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + se._parse( instring, loc ) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): + """ + Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}<parseString>} for more information on parsing + strings with embedded tabs. + + Example:: + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def transformString( self, instring ): + """ + Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string. + + Example:: + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + Prints:: + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + out = [o for o in out if o] + return "".join(map(_ustr,_flatten(out))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + + Example:: + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + prints:: + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional C{maxsplit} argument, to limit the number of splits; + and the optional C{includeSeparators} argument (default=C{False}), if the separating + matching text should be included in the split results. + + Example:: + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + prints:: + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + for t,s,e in self.scanString(instring, maxMatches=maxsplit): + yield instring[last:s] + if includeSeparators: + yield t[0] + last = e + yield instring[last:] + + def __add__(self, other ): + """ + Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement + converts them to L{Literal}s by default. + + Example:: + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + Prints:: + Hello, World! -> ['Hello', ',', 'World', '!'] + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """ + Implementation of + operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns C{L{And}} with error stop + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns C{L{MatchFirst}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns C{L{Or}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns C{L{Each}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns C{L{NotAny}} + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + + Example:: + # these are equivalent + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + """ + if name is not None: + return self.setResultsName(name) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{<TAB>} characters. + """ + self.keepTabs = True + return self + + def ignore( self, other ): + """ + Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + + Example:: + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable. + + Example:: + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using L{setDebugActions}. Prior to attempting + to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} + is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} + message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """ + Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + + Example:: + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): + """ + Execute the parse expression on a series of test strings, showing each + test, the parsed results or where the parse failed. Quick and easy way to + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + - comment - (default=C{'#'}) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default=C{True}) prints test output to stdout + - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTests} is True), and the results contain a list of lines of each + test's output + + Example:: + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + prints:: + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + for t in tests: + if comment is not None and comment.matches(t, False) or comments and not t: + comments.append(t) + continue + if not t: + continue + out = ['\n'.join(comments), t] + comments = [] + try: + t = t.replace(r'\n','\n') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + except ParseBaseException as pe: + fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" + if '\n' in t: + out.append(line(pe.loc, t)) + out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """ + Abstract C{ParserElement} subclass, for defining atomic matching patterns. + """ + def __init__( self ): + super(Token,self).__init__( savelist=False ) + + +class Empty(Token): + """ + An empty token, will always match. + """ + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """ + A token that will never match. + """ + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + + def parseImpl( self, instring, loc, doActions=True ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use L{CaselessLiteral}. + + For keyword matching (force word break before and after the matched string), + use L{Keyword} or L{CaselessKeyword}. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}: + - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. + - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + - C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$" + - C{caseless} allows case-insensitive matching, default is C{False}. + + Example:: + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use L{CaselessKeyword}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for L{CaselessKeyword}.) + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of L{Keyword}. + + Example:: + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for L{CaselessLiteral}.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class CloseMatch(Token): + """ + A variation on L{Literal} which matches "close" matches, that is, + strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: + - C{match_string} - string to be matched + - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match + + The results from a successful parse will contain the matched text from the input string and the following named results: + - C{mismatches} - a list of the positions within the match_string where mismatches were found + - C{original} - the original match_string used to compare against the input string + + If C{mismatches} is an empty list, then the match was an exact match. + + Example:: + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """ + Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{excludeChars} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + + L{srange} is useful for defining custom character set strings for defining + C{Word} expressions, using range notation from regular expression character sets. + + A common mistake is to use C{Word} to match a specific literal string, as in + C{Word("Address")}. Remember that C{Word} uses the string argument to define + I{sets} of matchable characters. This expression would match "Add", "AAA", + "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. + To match an exact literal string, use L{Literal} or L{Keyword}. + + pyparsing includes helper strings for building Words: + - L{alphas} + - L{nums} + - L{alphanums} + - L{hexnums} + - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) + - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - L{printables} (any non-whitespace character) + + Example:: + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # any string of non-whitespace characters, except for ',' + csv_value = Word(printables, excludeChars=",") + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): + super(Word,self).__init__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.initCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc, result.group() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + if len(s)>4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + r""" + Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as + named parse results. + + Example:: + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression + roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=C{None}) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) + + Example:: + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + prints:: + [['This is the quote']] + [['This is the "quote"']] + [['This is the quote with "embedded" quotes']] + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if not quoteChar: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped whitespace + if '\\' in ret and self.convertWhitespaceEscapes: + ws_map = { + r'\t' : '\t', + r'\n' : '\n', + r'\f' : '\f', + r'\r' : '\r', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """ + Token for matching words composed of characters I{not} in a given set (will + include whitespace in matched characters if not listed in the provided exclusion set - see example). + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + + Example:: + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + prints:: + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """ + Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class. + """ + whiteStrs = { + " " : "<SPC>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) + #~ self.leaveWhitespace() + self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """ + Token to advance to a specific column of input text; useful for tabular report scraping. + """ + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """ + Matches if current position is at the beginning of a line within the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + Prints:: + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +class LineEnd(_PositionToken): + """ + Matches if current position is at the end of a line within the parse string + """ + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """ + Matches if current position is at the beginning of the parse string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc != 0: + # see if entire string up to here is just whitespace and ignoreables + if loc != self.preParse( instring, 0 ): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class StringEnd(_PositionToken): + """ + Matches if current position is at the end of the parse string + """ + def __init__( self ): + super(StringEnd,self).__init__() + self.errmsg = "Expected end of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc < len(instring): + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """ + Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """ + Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of + the string being parsed, or at the end of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class ParseExpression(ParserElement): + """ + Abstract subclass of ParserElement, for combining and post-processing parsed tokens. + """ + def __init__( self, exprs, savelist = False ): + super(ParseExpression,self).__init__(savelist) + if isinstance( exprs, _generatorType ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( exprs ) ] + elif isinstance( exprs, Iterable ): + exprs = list(exprs) + # if sequence of strings provided, wrap with Literal + if all(isinstance(expr, basestring) for expr in exprs): + exprs = map(ParserElement._literalStringClass, exprs) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on + all contained expressions.""" + self.skipWhitespace = False + self.exprs = [ e.copy() for e in self.exprs ] + for e in self.exprs: + e.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + def streamline( self ): + super(ParseExpression,self).streamline() + + for e in self.exprs: + e.streamline() + + # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) + # but only if there are no parse actions or resultsNames on the nested And's + # (likewise for Or's and MatchFirst's) + if ( len(self.exprs) == 2 ): + other = self.exprs[0] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = other.exprs[:] + [ self.exprs[1] ] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + other = self.exprs[-1] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the C{'+'} operator. + May also be constructed using the C{'-'} operator, which will suppress backtracking. + + Example:: + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + expr = And([integer("id"),name_expr("name"),integer("age")]) + # more easily written as: + expr = integer("id") + name_expr("name") + integer("age") + """ + + class _ErrorStop(Empty): + def __init__(self, *args, **kwargs): + super(And._ErrorStop,self).__init__(*args, **kwargs) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = True + + def parseImpl( self, instring, loc, doActions=True ): + # pass False as last arg to _parse for first element, since we already + # pre-parsed the string as part of our And pre-parsing + loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + loc, exprtokens = e._parse( instring, loc, doActions ) + if exprtokens or exprtokens.haskeys(): + resultlist += exprtokens + return loc, resultlist + + def __iadd__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #And( [ self, other ] ) + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the expression that matches the longest string will be used. + May be constructed using the C{'^'} operator. + + Example:: + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + prints:: + [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(Or,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + # save match among all matches, to retry longest to shortest + matches.append((loc2, e)) + + if matches: + matches.sort(key=lambda x: -x[0]) + for _,e in matches: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + + Example:: + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) + print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + + Example:: + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + prints:: + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = True + self.initExprGroups = True + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """ + Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens. + """ + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + if issubclass(ParserElement._literalStringClass, Token): + expr = ParserElement._literalStringClass(expr) + else: + expr = ParserElement._literalStringClass(Literal(expr)) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except Exception: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """ + Lookahead matching of the given parse expression. C{FollowedBy} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list. + + Example:: + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + prints:: + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. C{NotAny} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression does I{not} match at the current + position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator. + + Example:: + + """ + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr.canParseNext(instring, loc): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + def __init__( self, expr, stopOn=None): + super(_MultipleMatch, self).__init__(expr) + self.saveAsList = True + ender = stopOn + if isinstance(ender, basestring): + ender = ParserElement._literalStringClass(ender) + self.not_ender = ~ender if ender is not None else None + + def parseImpl( self, instring, loc, doActions=True ): + self_expr_parse = self.expr._parse + self_skip_ignorables = self._skipIgnorables + check_ender = self.not_ender is not None + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = (not not self.ignoreExprs) + while 1: + if check_ender: + try_not_ender(instring, loc) + if hasIgnoreExprs: + preloc = self_skip_ignorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to L{OneOrMore} + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + prints:: + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + FAIL: Expected end of text (at char 5), (line:1, col:6) + """ + def __init__( self, expr, default=_optionalNotMatched ): + super(Optional,self).__init__( expr, savelist=False ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default=C{False}) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default=C{None}) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default=C{None}) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + prints:: + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.asList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + + See L{ParseResults.pprint} for an example of a recursive parser created using + C{Forward}. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of C{ParseExpression}, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """ + Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + + Example:: + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # no match when there are internal spaces + print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """ + Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. + + Example:: + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] + + func = ident + Group(Optional(delimitedList(term))) + print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """ + Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + prints:: + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + See more examples at L{ParseResults} of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """ + Converter for ignoring the results of a parsed expression. + + Example:: + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + prints:: + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + (See also L{delimitedList}.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """ + Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """ + Decorator for debugging parse actions. + + When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} + When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. + + Example:: + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens)))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + prints:: + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +def delimitedList( expr, delim=",", combine=False ): + """ + Helper to define a delimited list of expressions - the delimiter defaults to ','. + By default, the list elements and delimiters can have intervening whitespace, and + comments, but this can be overridden by passing C{combine=True} in the constructor. + If C{combine} is set to C{True}, the matching tokens are returned as a single token + string, with the delimiters included; otherwise, the matching tokens are returned + as a list of tokens, with the delimiters suppressed. + + Example:: + delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] + delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] + """ + dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """ + Helper to define a counted list of expressions. + This helper defines a pattern of the form:: + integer expr expr expr... + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. + + If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. + + Example:: + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + intExpr = Word(nums).setParseAction(lambda t:int(t[0])) + else: + intExpr = intExpr.copy() + intExpr.setName("arrayLen") + intExpr.addParseAction(countFieldParseAction, callDuringTry=True) + return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches a + previous literal, will also match the leading C{"1:1"} in C{"1:10"}. + If this is not desired, use C{matchPreviousExpr}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches by + expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; + the expressions are evaluated first, and then compared, so + C{"1"} is compared with C{"10"}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + if theseTokens != matchTokens: + raise ParseException("",0,"") + rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def _escapeRegexRangeChars(s): + #~ escape these chars: ^-] + for c in r"\^-]": + s = s.replace(c,_bslash+c) + s = s.replace("\n",r"\n") + s = s.replace("\t",r"\t") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """ + Helper to quickly define a set of alternative Literals, and makes sure to do + longest-first testing when there is a conflict, regardless of the input order, + but returns a C{L{MatchFirst}} for best performance. + + Parameters: + - strs - a string of space-delimited literals, or a collection of string literals + - caseless - (default=C{False}) - treat all literals as caseless + - useRegex - (default=C{True}) - as an optimization, will generate a Regex + object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or + if creating a C{Regex} raises an exception) + + Example:: + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + prints:: + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + if isinstance(strs,basestring): + symbols = strs.split() + elif isinstance(strs, Iterable): + symbols = list(strs) + else: + warnings.warn("Invalid argument to oneOf, expected string or iterable", + SyntaxWarning, stacklevel=2) + if not symbols: + return NoMatch() + + i = 0 + while i < len(symbols)-1: + cur = symbols[i] + for j,other in enumerate(symbols[i+1:]): + if ( isequal(other, cur) ): + del symbols[i+j+1] + break + elif ( masks(cur, other) ): + del symbols[i+j+1] + symbols.insert(i,other) + cur = other + break + else: + i += 1 + + if not caseless and useRegex: + #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) + else: + return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) + except Exception: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) + +def dictOf( key, value ): + """ + Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + + Example:: + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + prints:: + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """ + Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. By default, returns astring containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values. + + Example:: + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + prints:: + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """ + Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """ + Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{<TAB>} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + + Example:: + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + prints:: + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) +_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +def srange(s): + r""" + Helper to easily define string ranges for use in Word construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be: + - a single character + - an escaped character with a leading backslash (such as C{\-} or C{\]}) + - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) + (C{\0x##} is also supported for backwards compatibility) + - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) + - a range of any of the above, separated by a dash (C{'a-z'}, etc.) + - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.) + """ + _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +def matchOnlyAtCol(n): + """ + Helper method for defining parse actions that require matching at a specific + column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """ + Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString<ParserElement.transformString>}()}. + + Example:: + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """ + Helper parse action for removing quotation marks from parsed quoted strings. + + Example:: + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """ + Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional + args are passed, they are forwarded to the given function as additional arguments after + the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the + parsed data to an integer using base 16. + + Example (compare the last to example in L{ParserElement.transformString}:: + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + prints:: + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + now is the winter of our discontent made glorious summer by this sun of york + ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] + """ + def pa(s,l,t): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches + tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. + + Example:: + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are also accessible as named results + print(link.link_text, '->', link.href) + prints:: + pyparsing -> http://pyparsing.wikispaces.com + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for XML, given a tag name. Matches + tags only in the given upper/lower case. + + Example: similar to L{makeHTMLTags} + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """ + Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{<TD>} or C{<DIV>}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "align":"right"}} + - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) + For attribute names with a namespace prefix, you must use the second form. Attribute + names are matched insensitive to upper/lower case. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + + Example:: + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """ + Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + + Example:: + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): + """ + Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary or + binary, left- or right-associative. Parse actions can also be attached + to operator expressions. The generated parser will also recognize the use + of parentheses to override operator precedences (see example below). + + Note: if you define a deep operator list, you may see performance issues + when using infixNotation. See L{ParserElement.enablePackrat} for a + mechanism to potentially improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted); if the parse action + is passed a tuple or list of functions, this is equivalent to + calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) + - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) + - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) + + Example:: + # simple example of four-function arithmetic with ints and variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + prints:: + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + ret = Forward() + lastExpr = baseExpr | ( lpar + ret + rpar ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" + +dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") +sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") +quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| + Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """ + Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression + - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression + - content - expression for items within the nested lists (default=C{None}) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + + Example:: + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + prints:: + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + ret.setName('nested %s%s expression' % (opener,closer)) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """ + Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single grammar + should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond the + the current level; set to False for block of left-most statements + (default=C{True}) + + A valid block must contain at least one C{blockStatement}. + + Example:: + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + funcDef = Group( funcDecl + func_body ) + + rvalue = Forward() + funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") + rvalue << (funcCall | identifier | Word(nums)) + assignment = Group(identifier + "=" + rvalue) + stmt << ( funcDef | assignment | identifier ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + prints:: + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') + PEER = Empty().setParseAction(checkPeerIndent).setName('') + UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) +_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) +commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") +def replaceHTMLEntity(t): + """Helper parser action to replace common HTML entities with their special characters""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form C{/* ... */}" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form C{<!-- ... -->}" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form C{// ... (to end of line)}" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" + +javaStyleComment = cppStyleComment +"Same as C{L{cppStyleComment}}" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form C{# ... (to end of line)}" + +_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + + Optional( Word(" \t") + + ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") +commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") +"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. + This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """ + Here are some common low-level expressions that may be useful in jump-starting parser development: + - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) + - common L{programming identifiers<identifier>} + - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) + - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} + - L{UUID<uuid>} + - L{comma-separated list<comma_separated_list>} + Parse actions: + - C{L{convertToInteger}} + - C{L{convertToFloat}} + - C{L{convertToDate}} + - C{L{convertToDatetime}} + - C{L{stripHTMLTags}} + - C{L{upcaseTokens}} + - C{L{downcaseTokens}} + + Example:: + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + prints:: + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + integer = Word(nums).setName("integer").setParseAction(convertToInteger) + """expression that parses an unsigned integer, returns an int""" + + hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" + mixed_integer.addParseAction(sum) + + real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) + """expression that parses a floating point number and returns a float""" + + sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) + """expression that parses a floating point number with optional scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) + """any int or real number, returned as float""" + + identifier = Word(alphas+'_', alphanums+'_').setName("identifier") + """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" + + ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") + "IPv4 address (C{0.0.0.0 - 255.255.255.255})" + + _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") + _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") + _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") + _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) + _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") + ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) + + Example:: + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + prints:: + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """ + Helper to create a parse action for converting parsed datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) + + Example:: + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + prints:: + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (C{yyyy-mm-dd})" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """ + Parse action to remove HTML tags from web page HTML source + + Example:: + # strip HTML links from normal text + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + td,td_end = makeHTMLTags("TD") + table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end + + print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' + """ + return pyparsing_common._html_stripper.transformString(tokens[0]) + + _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') + + Optional( White(" \t") ) ) ).streamline().setName("commaItem") + comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/env/lib/python3.7/site-packages/pkg_resources/_vendor/six.py b/env/lib/python3.7/site-packages/pkg_resources/_vendor/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/_vendor/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + if from_value is None: + raise value + raise value from from_value +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/env/lib/python3.7/site-packages/pkg_resources/extern/__init__.py b/env/lib/python3.7/site-packages/pkg_resources/extern/__init__.py new file mode 100644 index 0000000..c1eb9e9 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/extern/__init__.py @@ -0,0 +1,73 @@ +import sys + + +class VendorImporter: + """ + A PEP 302 meta path importer for finding optionally-vendored + or otherwise naturally-installed packages from root_name. + """ + + def __init__(self, root_name, vendored_names=(), vendor_pkg=None): + self.root_name = root_name + self.vendored_names = set(vendored_names) + self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') + + @property + def search_path(self): + """ + Search first the vendor package then as a natural package. + """ + yield self.vendor_pkg + '.' + yield '' + + def find_module(self, fullname, path=None): + """ + Return self when fullname starts with root_name and the + target module is one vendored through this importer. + """ + root, base, target = fullname.partition(self.root_name + '.') + if root: + return + if not any(map(target.startswith, self.vendored_names)): + return + return self + + def load_module(self, fullname): + """ + Iterate over the search path to locate and load fullname. + """ + root, base, target = fullname.partition(self.root_name + '.') + for prefix in self.search_path: + try: + extant = prefix + target + __import__(extant) + mod = sys.modules[extant] + sys.modules[fullname] = mod + # mysterious hack: + # Remove the reference to the extant package/module + # on later Python versions to cause relative imports + # in the vendor package to resolve the same modules + # as those going through this importer. + if prefix and sys.version_info > (3, 3): + del sys.modules[extant] + return mod + except ImportError: + pass + else: + raise ImportError( + "The '{target}' package is required; " + "normally this is bundled with this package so if you get " + "this warning, consult the packager of your " + "distribution.".format(**locals()) + ) + + def install(self): + """ + Install this importer into sys.meta_path if not already present. + """ + if self not in sys.meta_path: + sys.meta_path.append(self) + + +names = 'packaging', 'pyparsing', 'six', 'appdirs' +VendorImporter(__name__, names).install() diff --git a/env/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/pkg_resources/extern/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fe3338c43a9ff70e543b9e750ac7d1346be3d79 GIT binary patch literal 2376 zcmZ`)&u<(x6t?Hr&Q3OIg-}8(h%A8`R%#OjJs?r4LR+B<6jco>WmOnW*WP53+402o zHrZuzVIz)+3ul@m{|0}CublcXaN<4B?xt;2kNoVJ@sIc3_xbbJ%gYIY();V$(|_88 z{EIL1;zQ>SRDB%`C!7|fN4_E4<Nhh({?zMH9`rmxg)h9R_aZnW6h`fkZuk;rknKL& zd0DJ>2fhdbb4kzRwCD2`9`Nv#_5u;|h__D3l=dQiiO0MRUt2ukOQ)n4^A2Bzw#|Lm z;j&$MEJ`lbgJC6=5o&UpFeqQKhxZ?{&p!E-4TZ^Am6<)3&xWvpRBVu!JTG^dtV}M; ztSH7ep1XwvcMHG}Y4(IV%C%r+W=6`5$xCgZBRDMCKgf24W&<UMOi5|dG8>9bH~Vi0 zI+#U_E!MkG^))axtw~A@t-UGsyxOnUYx=_HlzV3$d<i&#(EROQB#t4Z(zepZw{B?L zi=C{mg|RDhuift2wv?!ftS@ZR{79>V-ELq5EsB8(VRzL+0~iy9P&o77{Vg-BwyM0k zF$?fU|7f?|H-|U3V3Sd0q%8CnER`yu<w*5~-fDc?O4Gc|O`2|2V;j$3kW4xPLuf=3 zI$3-C8c3V-aeazopkV7kMXKmkFg4i+4y}>L$R*EN#5<UL=Msz<?}$wG_W((y4FjxL z6Y(4w{8X|`vuuvv{7-`sE@A1WCEH!<@&OI{eV!Jz1g~~UyM0pR&?R)w0ULJc<mwwy zy)v+mxy6D>SfKwoya3V|9L3<y=u`j1KM794+E?q`+abm?ejV-yFe01+KlDxfT01^W zep`h82tZLKLr~cfhB+7&1=5cJJ(bbyC<nqXsKT<6V>%Y|VbHEHY$*At5G>bBmh<!h zwauQAquo7d;m`ckoF`2!Lm1oL$hIrkE64NWm}UK}99w^wRW@ndKrbBMx{*t*jpu&a z0Mls$bkPRSGA(S>ICUZYcv92G(>2&wcfgQvl?L#<1N8z7uT1D8r?A9Ok@I(<>Oa6- zfWbo`jtwN<yGMR{auSYj*I^y3k&_4@iKdhi6YPg|bcLL>>Xz%%Tci%v&(M#!cM!N9 zjQEn&tsOw!v<?zwC@`3kAIahR6R1DHSMKk}17g}!@;jZ<UqL-lD<|JB;CTS2J~M*J z=RzTF0JNjJlQAP%A^Z3nQ7vS~7wEr%QP+EkG*nl?O#b{H*4g-_N%G0Y{45~&N*s=I zCHNPtlxm1NH-lcYXQPs%+BrTsKFoBFY02^d8_N+xCb?fnnJPh3ud}`^^{8kL<!n62 zsT-{r&$Utcvk~%UbGw_U%jlz%COlp?0da6jou(jhW0154d~G|B4h^$FaR$;ZHIjc{ zDXDA(nm){ojW9KZ?#9hgeixTUIZ;R*^&YMtRZ0x<V<)azX@IbjUmzW(bw;`mVUk`4 zLxNS>p&pIlNoW$SKpW5%ns^?K{0lUEWr^2h4k2+gL|AHKKno69Y8BfTp#En-G<SJ= zlSk)-Xs(^tPbAAr-~wc56Yn^uPY6jV4a*88GCpPysura==f!r{SMS5Vw!N5RqpYex zp5G#Wt=Wxm2WB<W7l5Fzz9D_HL0!*f5)>7H#p?hy32+2V8xW!2Nz=no=F|$_T4~B< zKTQ=LYa3TeRzjJvLMo^$Xg)%-fyR;f+@LxuJm9FWP8Q-I@RG0-C!P2M_Xlo15GlN< zftS!7gJNmy`Z_<hEeM>$?a>WgPTUL|qRU!+jElc*R~z4I!nuw2mb>U;f8}04{|8*3 Bad`j$ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/pkg_resources/py31compat.py b/env/lib/python3.7/site-packages/pkg_resources/py31compat.py new file mode 100644 index 0000000..a381c42 --- /dev/null +++ b/env/lib/python3.7/site-packages/pkg_resources/py31compat.py @@ -0,0 +1,23 @@ +import os +import errno +import sys + +from .extern import six + + +def _makedirs_31(path, exist_ok=False): + try: + os.makedirs(path) + except OSError as exc: + if not exist_ok or exc.errno != errno.EEXIST: + raise + + +# rely on compatibility behavior until mode considerations +# and exists_ok considerations are disentangled. +# See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 +needs_makedirs = ( + six.PY2 or + (3, 4) <= sys.version_info < (3, 4, 1) +) +makedirs = _makedirs_31 if needs_makedirs else os.makedirs diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/INSTALLER b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/LICENSE b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/LICENSE new file mode 100644 index 0000000..6e0693b --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2016 Jason R Coombs <jaraco@jaraco.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/METADATA b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/METADATA new file mode 100644 index 0000000..dc811f4 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/METADATA @@ -0,0 +1,73 @@ +Metadata-Version: 2.1 +Name: setuptools +Version: 40.6.3 +Summary: Easily download, build, install, upgrade, and uninstall Python packages +Home-page: https://github.com/pypa/setuptools +Author: Python Packaging Authority +Author-email: distutils-sig@python.org +License: UNKNOWN +Project-URL: Documentation, https://setuptools.readthedocs.io/ +Keywords: CPAN PyPI distutils eggs package management +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: License :: OSI Approved :: MIT License +Classifier: Operating System :: OS Independent +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Topic :: Software Development :: Libraries :: Python Modules +Classifier: Topic :: System :: Archiving :: Packaging +Classifier: Topic :: System :: Systems Administration +Classifier: Topic :: Utilities +Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.* +Description-Content-Type: text/x-rst; charset=UTF-8 +Provides-Extra: certs +Requires-Dist: certifi (==2016.9.26) ; extra == 'certs' +Provides-Extra: ssl +Requires-Dist: wincertstore (==0.2) ; (sys_platform=='win32') and extra == 'ssl' + +.. image:: https://img.shields.io/pypi/v/setuptools.svg + :target: https://pypi.org/project/setuptools + +.. image:: https://readthedocs.org/projects/setuptools/badge/?version=latest + :target: https://setuptools.readthedocs.io + +.. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20build%20%40%20Travis%20CI + :target: https://travis-ci.org/pypa/setuptools + +.. image:: https://img.shields.io/appveyor/ci/pypa/setuptools/master.svg?label=Windows%20build%20%40%20Appveyor + :target: https://ci.appveyor.com/project/pypa/setuptools/branch/master + +.. image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg + :target: https://codecov.io/gh/pypa/setuptools + +.. image:: https://img.shields.io/pypi/pyversions/setuptools.svg + +.. image:: https://tidelift.com/badges/github/pypa/setuptools + :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme + +See the `Installation Instructions +<https://packaging.python.org/installing/>`_ in the Python Packaging +User's Guide for instructions on installing, upgrading, and uninstalling +Setuptools. + +Questions and comments should be directed to the `distutils-sig +mailing list <http://mail.python.org/pipermail/distutils-sig/>`_. +Bug reports and especially tested patches may be +submitted directly to the `bug tracker +<https://github.com/pypa/setuptools/issues>`_. + + +Code of Conduct +--------------- + +Everyone interacting in the setuptools project's codebases, issue trackers, +chat rooms, and mailing lists is expected to follow the +`PyPA Code of Conduct <https://www.pypa.io/en/latest/code-of-conduct/>`_. + + diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/RECORD b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/RECORD new file mode 100644 index 0000000..7a8a2b5 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/RECORD @@ -0,0 +1,188 @@ +easy_install.py,sha256=MDC9vt5AxDsXX5qcKlBz2TnW6Tpuv_AobnfhCJ9X3PM,126 +pkg_resources/__init__.py,sha256=d7w_yqCD39lZE0-qxhWXPYoc-pZc3G2mD7EU2xhRLpM,104720 +pkg_resources/py31compat.py,sha256=-WQ0e4c3RG_acdhwC3gLiXhP_lg4G5q7XYkZkQg0gxU,558 +pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +pkg_resources/_vendor/appdirs.py,sha256=MievUEuv3l_mQISH5SF0shDk_BNhHHzYiAPrT3ITN4I,24701 +pkg_resources/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055 +pkg_resources/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 +pkg_resources/_vendor/packaging/__about__.py,sha256=zkcCPTN_6TcLW0Nrlg0176-R1QQ_WVPTm8sz1R4-HjM,720 +pkg_resources/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 +pkg_resources/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 +pkg_resources/_vendor/packaging/_structures.py,sha256=RImECJ4c_wTlaTYYwZYLHEiebDMaAJmK1oPARhw1T5o,1416 +pkg_resources/_vendor/packaging/markers.py,sha256=uEcBBtGvzqltgnArqb9c4RrcInXezDLos14zbBHhWJo,8248 +pkg_resources/_vendor/packaging/requirements.py,sha256=SikL2UynbsT0qtY9ltqngndha_sfo0w6XGFhAhoSoaQ,4355 +pkg_resources/_vendor/packaging/specifiers.py,sha256=SAMRerzO3fK2IkFZCaZkuwZaL_EGqHNOz4pni4vhnN0,28025 +pkg_resources/_vendor/packaging/utils.py,sha256=3m6WvPm6NNxE8rkTGmn0r75B_GZSGg7ikafxHsBN1WA,421 +pkg_resources/_vendor/packaging/version.py,sha256=OwGnxYfr2ghNzYx59qWIBkrK3SnB6n-Zfd1XaLpnnM0,11556 +pkg_resources/extern/__init__.py,sha256=cHiEfHuLmm6rs5Ve_ztBfMI7Lr31vss-D4wkqF5xzlI,2498 +setuptools/__init__.py,sha256=ipsF2yFkfHmryPP8ASJEtOj9N9OuYkk8HxxIJyOHtj0,6001 +setuptools/_deprecation_warning.py,sha256=jU9-dtfv6cKmtQJOXN8nP1mm7gONw5kKEtiPtbwnZyI,218 +setuptools/archive_util.py,sha256=kw8Ib_lKjCcnPKNbS7h8HztRVK0d5RacU3r_KRdVnmM,6592 +setuptools/build_meta.py,sha256=v5rAo9IKlgjNHNcpStcUBG0ChHI-OjNOkCZ_liGuuLA,5995 +setuptools/cli-32.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536 +setuptools/cli-64.exe,sha256=KLABu5pyrnokJCv6skjXZ6GsXeyYHGcqOUT3oHI3Xpo,74752 +setuptools/cli.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536 +setuptools/config.py,sha256=nCkzIQRWTpVwvtSlFm1kOeSLMMHXmB7hENxwZUT6X9Q,19751 +setuptools/dep_util.py,sha256=fgixvC1R7sH3r13ktyf7N0FALoqEXL1cBarmNpSEoWg,935 +setuptools/depends.py,sha256=hC8QIDcM3VDpRXvRVA6OfL9AaQfxvhxHcN_w6sAyNq8,5837 +setuptools/dist.py,sha256=HyRYLlPp_gkcnvQf8o1RsGq99LtghAeAfxWxbf40KxA,44675 +setuptools/extension.py,sha256=uc6nHI-MxwmNCNPbUiBnybSyqhpJqjbhvOQ-emdvt_E,1729 +setuptools/glibc.py,sha256=X64VvGPL2AbURKwYRsWJOXXGAYOiF_v2qixeTkAULuU,3146 +setuptools/glob.py,sha256=o75cHrOxYsvn854thSxE0x9k8JrKDuhP_rRXlVB00Q4,5084 +setuptools/gui-32.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536 +setuptools/gui-64.exe,sha256=aYKMhX1IJLn4ULHgWX0sE0yREUt6B3TEHf_jOw6yNyE,75264 +setuptools/gui.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536 +setuptools/launch.py,sha256=sd7ejwhBocCDx_wG9rIs0OaZ8HtmmFU8ZC6IR_S0Lvg,787 +setuptools/lib2to3_ex.py,sha256=t5e12hbR2pi9V4ezWDTB4JM-AISUnGOkmcnYHek3xjg,2013 +setuptools/monkey.py,sha256=FGc9fffh7gAxMLFmJs2DW_OYWpBjkdbNS2n14UAK4NA,5264 +setuptools/msvc.py,sha256=uuRFaZzjJt5Fv3ZmyKUUuLtjx12_8G9RILigGec4irI,40838 +setuptools/namespaces.py,sha256=F0Nrbv8KCT2OrO7rwa03om4N4GZKAlnce-rr-cgDQa8,3199 +setuptools/package_index.py,sha256=yeifZQhJVRwPSaQmRrVPxbXRy-1lF5KdTFV8NAb3YcE,40342 +setuptools/pep425tags.py,sha256=bSGwlybcIpssx9kAv_hqAUJzfEpXSzYRp2u-nDYPdbk,10862 +setuptools/py27compat.py,sha256=3mwxRMDk5Q5O1rSXOERbQDXhFqwDJhhUitfMW_qpUCo,536 +setuptools/py31compat.py,sha256=REvrUBibUHgqI9S-ww0C9bhU-n8PyaQ8Slr1_NRxaaE,820 +setuptools/py33compat.py,sha256=OubjldHJH1KGE1CKt1kRU-Q55keftHT3ea1YoL0ZSco,1195 +setuptools/py36compat.py,sha256=VUDWxmu5rt4QHlGTRtAFu6W5jvfL6WBjeDAzeoBy0OM,2891 +setuptools/sandbox.py,sha256=9UbwfEL5QY436oMI1LtFWohhoZ-UzwHvGyZjUH_qhkw,14276 +setuptools/script (dev).tmpl,sha256=RUzQzCQUaXtwdLtYHWYbIQmOaES5Brqq1FvUA_tu-5I,218 +setuptools/script.tmpl,sha256=WGTt5piezO27c-Dbx6l5Q4T3Ff20A5z7872hv3aAhYY,138 +setuptools/site-patch.py,sha256=OumkIHMuoSenRSW1382kKWI1VAwxNE86E5W8iDd34FY,2302 +setuptools/ssl_support.py,sha256=YBDJsCZjSp62CWjxmSkke9kn9rhHHj25Cus6zhJRW3c,8492 +setuptools/unicode_utils.py,sha256=NOiZ_5hD72A6w-4wVj8awHFM3n51Kmw1Ic_vx15XFqw,996 +setuptools/version.py,sha256=og_cuZQb0QI6ukKZFfZWPlr1HgJBPPn2vO2m_bI9ZTE,144 +setuptools/wheel.py,sha256=A8hKSqHWZ5KM0-VP_DtptxpMxVF9pQwjWZcHGklxq2o,8102 +setuptools/windows_support.py,sha256=5GrfqSP2-dLGJoZTq2g6dCKkyQxxa2n5IQiXlJCoYEE,714 +setuptools/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +setuptools/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055 +setuptools/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 +setuptools/_vendor/packaging/__about__.py,sha256=zkcCPTN_6TcLW0Nrlg0176-R1QQ_WVPTm8sz1R4-HjM,720 +setuptools/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 +setuptools/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 +setuptools/_vendor/packaging/_structures.py,sha256=RImECJ4c_wTlaTYYwZYLHEiebDMaAJmK1oPARhw1T5o,1416 +setuptools/_vendor/packaging/markers.py,sha256=Gvpk9EY20yKaMTiKgQZ8yFEEpodqVgVYtfekoic1Yts,8239 +setuptools/_vendor/packaging/requirements.py,sha256=t44M2HVWtr8phIz2OhnILzuGT3rTATaovctV1dpnVIg,4343 +setuptools/_vendor/packaging/specifiers.py,sha256=SAMRerzO3fK2IkFZCaZkuwZaL_EGqHNOz4pni4vhnN0,28025 +setuptools/_vendor/packaging/utils.py,sha256=3m6WvPm6NNxE8rkTGmn0r75B_GZSGg7ikafxHsBN1WA,421 +setuptools/_vendor/packaging/version.py,sha256=OwGnxYfr2ghNzYx59qWIBkrK3SnB6n-Zfd1XaLpnnM0,11556 +setuptools/command/__init__.py,sha256=NWzJ0A1BEengZpVeqUyWLNm2bk4P3F4iL5QUErHy7kA,594 +setuptools/command/alias.py,sha256=KjpE0sz_SDIHv3fpZcIQK-sCkJz-SrC6Gmug6b9Nkc8,2426 +setuptools/command/bdist_egg.py,sha256=be-IBpr1zhS9i6GjKANJgzkbH3ChImdWY7S-j0r2BK8,18167 +setuptools/command/bdist_rpm.py,sha256=B7l0TnzCGb-0nLlm6rS00jWLkojASwVmdhW2w5Qz_Ak,1508 +setuptools/command/bdist_wininst.py,sha256=_6dz3lpB1tY200LxKPLM7qgwTCceOMgaWFF-jW2-pm0,637 +setuptools/command/build_clib.py,sha256=bQ9aBr-5ZSO-9fGsGsDLz0mnnFteHUZnftVLkhvHDq0,4484 +setuptools/command/build_ext.py,sha256=81CTgsqjBjNl_HOgCJ1lQ5vv1NIM3RBpcoVGpqT4N1M,12897 +setuptools/command/build_py.py,sha256=yWyYaaS9F3o9JbIczn064A5g1C5_UiKRDxGaTqYbtLE,9596 +setuptools/command/develop.py,sha256=Sl1iMOORbAnp5BqiXmyMBD0uuvEnhSfOCqbxIPRiJPc,8060 +setuptools/command/dist_info.py,sha256=5t6kOfrdgALT-P3ogss6PF9k-Leyesueycuk3dUyZnI,960 +setuptools/command/easy_install.py,sha256=telww7CuPsoTtvlpY-ktnZGT85cZ6xGCGZa0vHvFJ-Q,87273 +setuptools/command/egg_info.py,sha256=3lsuTHQFjmAw6slzRrB3HjLiF2TaImpWHREllAPhyv8,25541 +setuptools/command/install.py,sha256=a0EZpL_A866KEdhicTGbuyD_TYl1sykfzdrri-zazT4,4683 +setuptools/command/install_egg_info.py,sha256=bMgeIeRiXzQ4DAGPV1328kcjwQjHjOWU4FngAWLV78Q,2203 +setuptools/command/install_lib.py,sha256=11mxf0Ch12NsuYwS8PHwXBRvyh671QAM4cTRh7epzG0,3840 +setuptools/command/install_scripts.py,sha256=UD0rEZ6861mTYhIdzcsqKnUl8PozocXWl9VBQ1VTWnc,2439 +setuptools/command/launcher manifest.xml,sha256=xlLbjWrB01tKC0-hlVkOKkiSPbzMml2eOPtJ_ucCnbE,628 +setuptools/command/py36compat.py,sha256=SzjZcOxF7zdFUT47Zv2n7AM3H8koDys_0OpS-n9gIfc,4986 +setuptools/command/register.py,sha256=LO3MvYKPE8dN1m-KkrBRHC68ZFoPvA_vI8Xgp7vv6zI,534 +setuptools/command/rotate.py,sha256=co5C1EkI7P0GGT6Tqz-T2SIj2LBJTZXYELpmao6d4KQ,2164 +setuptools/command/saveopts.py,sha256=za7QCBcQimKKriWcoCcbhxPjUz30gSB74zuTL47xpP4,658 +setuptools/command/sdist.py,sha256=obDTe2BmWt2PlnFPZZh7e0LWvemEsbCCO9MzhrTZjm8,6711 +setuptools/command/setopt.py,sha256=NTWDyx-gjDF-txf4dO577s7LOzHVoKR0Mq33rFxaRr8,5085 +setuptools/command/test.py,sha256=fSl5OsZWSmFR3QJRvyy2OxbcYkuIkPvykWNOhFvAcUA,9228 +setuptools/command/upload.py,sha256=BpQCjKtJZ4kEb0qIOiTjlJtbpapmNacC27nG2ZlSxTY,6825 +setuptools/command/upload_docs.py,sha256=oXiGplM_cUKLwE4CWWw98RzCufAu8tBhMC97GegFcms,7311 +setuptools/extern/__init__.py,sha256=TxeNKFMSfBMzBpBDiHx8Dh3RzsdVmvWaXhtZ03DZMs0,2499 +setuptools-40.6.3.dist-info/LICENSE,sha256=wyo6w5WvYyHv0ovnPQagDw22q4h9HCHU_sRhKNIFbVo,1078 +setuptools-40.6.3.dist-info/METADATA,sha256=zQ7OKsTw2wXshXUxcGIuLdaogfxtuSBL0etbFqo_PoY,3094 +setuptools-40.6.3.dist-info/WHEEL,sha256=_wJFdOYk7i3xxT8ElOkUJvOdOvfNGbR9g-bf6UQT6sU,110 +setuptools-40.6.3.dist-info/dependency_links.txt,sha256=HlkCFkoK5TbZ5EMLbLKYhLcY_E31kBWD8TqW2EgmatQ,239 +setuptools-40.6.3.dist-info/entry_points.txt,sha256=jBqCYDlVjl__sjYFGXo1JQGIMAYFJE-prYWUtnMZEew,2990 +setuptools-40.6.3.dist-info/top_level.txt,sha256=2HUXVVwA4Pff1xgTFr3GsTXXKaPaO6vlG6oNJ_4u4Tg,38 +setuptools-40.6.3.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 +setuptools-40.6.3.dist-info/RECORD,, +../../../bin/easy_install,sha256=i9AMXcQNSROizXtuqR3_a2F5KS3S3g6Qsh82N-U6tpA,276 +../../../bin/easy_install-3.7,sha256=i9AMXcQNSROizXtuqR3_a2F5KS3S3g6Qsh82N-U6tpA,276 +setuptools-40.6.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +__pycache__/easy_install.cpython-37.pyc,, +setuptools/__pycache__/windows_support.cpython-37.pyc,, +setuptools/__pycache__/wheel.cpython-37.pyc,, +setuptools/__pycache__/version.cpython-37.pyc,, +setuptools/__pycache__/unicode_utils.cpython-37.pyc,, +setuptools/__pycache__/ssl_support.cpython-37.pyc,, +setuptools/__pycache__/site-patch.cpython-37.pyc,, +setuptools/__pycache__/sandbox.cpython-37.pyc,, +setuptools/__pycache__/py36compat.cpython-37.pyc,, +setuptools/__pycache__/py33compat.cpython-37.pyc,, +setuptools/__pycache__/py31compat.cpython-37.pyc,, +setuptools/__pycache__/py27compat.cpython-37.pyc,, +setuptools/__pycache__/pep425tags.cpython-37.pyc,, +setuptools/__pycache__/package_index.cpython-37.pyc,, +setuptools/__pycache__/namespaces.cpython-37.pyc,, +setuptools/__pycache__/msvc.cpython-37.pyc,, +setuptools/__pycache__/monkey.cpython-37.pyc,, +setuptools/__pycache__/lib2to3_ex.cpython-37.pyc,, +setuptools/__pycache__/launch.cpython-37.pyc,, +setuptools/__pycache__/glob.cpython-37.pyc,, +setuptools/__pycache__/glibc.cpython-37.pyc,, +setuptools/__pycache__/extension.cpython-37.pyc,, +setuptools/__pycache__/dist.cpython-37.pyc,, +setuptools/__pycache__/depends.cpython-37.pyc,, +setuptools/__pycache__/dep_util.cpython-37.pyc,, +setuptools/__pycache__/config.cpython-37.pyc,, +setuptools/__pycache__/build_meta.cpython-37.pyc,, +setuptools/__pycache__/archive_util.cpython-37.pyc,, +setuptools/__pycache__/_deprecation_warning.cpython-37.pyc,, +setuptools/__pycache__/__init__.cpython-37.pyc,, +setuptools/extern/__pycache__/__init__.cpython-37.pyc,, +setuptools/command/__pycache__/upload_docs.cpython-37.pyc,, +setuptools/command/__pycache__/upload.cpython-37.pyc,, +setuptools/command/__pycache__/test.cpython-37.pyc,, +setuptools/command/__pycache__/setopt.cpython-37.pyc,, +setuptools/command/__pycache__/sdist.cpython-37.pyc,, +setuptools/command/__pycache__/saveopts.cpython-37.pyc,, +setuptools/command/__pycache__/rotate.cpython-37.pyc,, +setuptools/command/__pycache__/register.cpython-37.pyc,, +setuptools/command/__pycache__/py36compat.cpython-37.pyc,, +setuptools/command/__pycache__/install_scripts.cpython-37.pyc,, +setuptools/command/__pycache__/install_lib.cpython-37.pyc,, +setuptools/command/__pycache__/install_egg_info.cpython-37.pyc,, +setuptools/command/__pycache__/install.cpython-37.pyc,, +setuptools/command/__pycache__/egg_info.cpython-37.pyc,, +setuptools/command/__pycache__/easy_install.cpython-37.pyc,, +setuptools/command/__pycache__/dist_info.cpython-37.pyc,, +setuptools/command/__pycache__/develop.cpython-37.pyc,, +setuptools/command/__pycache__/build_py.cpython-37.pyc,, +setuptools/command/__pycache__/build_ext.cpython-37.pyc,, +setuptools/command/__pycache__/build_clib.cpython-37.pyc,, +setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc,, +setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc,, +setuptools/command/__pycache__/bdist_egg.cpython-37.pyc,, +setuptools/command/__pycache__/alias.cpython-37.pyc,, +setuptools/command/__pycache__/__init__.cpython-37.pyc,, +setuptools/_vendor/__pycache__/six.cpython-37.pyc,, +setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc,, +setuptools/_vendor/__pycache__/__init__.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc,, +setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc,, +pkg_resources/__pycache__/py31compat.cpython-37.pyc,, +pkg_resources/__pycache__/__init__.cpython-37.pyc,, +pkg_resources/extern/__pycache__/__init__.cpython-37.pyc,, +pkg_resources/_vendor/__pycache__/six.cpython-37.pyc,, +pkg_resources/_vendor/__pycache__/pyparsing.cpython-37.pyc,, +pkg_resources/_vendor/__pycache__/appdirs.cpython-37.pyc,, +pkg_resources/_vendor/__pycache__/__init__.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/version.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/utils.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/requirements.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/markers.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/_structures.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/_compat.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/__init__.cpython-37.pyc,, +pkg_resources/_vendor/packaging/__pycache__/__about__.cpython-37.pyc,, diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/WHEEL b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/WHEEL new file mode 100644 index 0000000..c4bde30 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.32.3) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/dependency_links.txt b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/dependency_links.txt new file mode 100644 index 0000000..e87d021 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/dependency_links.txt @@ -0,0 +1,2 @@ +https://files.pythonhosted.org/packages/source/c/certifi/certifi-2016.9.26.tar.gz#md5=baa81e951a29958563689d868ef1064d +https://files.pythonhosted.org/packages/source/w/wincertstore/wincertstore-0.2.zip#md5=ae728f2f007185648d0c7a8679b361e2 diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/entry_points.txt b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/entry_points.txt new file mode 100644 index 0000000..4159fd0 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/entry_points.txt @@ -0,0 +1,65 @@ +[console_scripts] +easy_install = setuptools.command.easy_install:main +easy_install-3.6 = setuptools.command.easy_install:main + +[distutils.commands] +alias = setuptools.command.alias:alias +bdist_egg = setuptools.command.bdist_egg:bdist_egg +bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm +bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst +build_clib = setuptools.command.build_clib:build_clib +build_ext = setuptools.command.build_ext:build_ext +build_py = setuptools.command.build_py:build_py +develop = setuptools.command.develop:develop +dist_info = setuptools.command.dist_info:dist_info +easy_install = setuptools.command.easy_install:easy_install +egg_info = setuptools.command.egg_info:egg_info +install = setuptools.command.install:install +install_egg_info = setuptools.command.install_egg_info:install_egg_info +install_lib = setuptools.command.install_lib:install_lib +install_scripts = setuptools.command.install_scripts:install_scripts +register = setuptools.command.register:register +rotate = setuptools.command.rotate:rotate +saveopts = setuptools.command.saveopts:saveopts +sdist = setuptools.command.sdist:sdist +setopt = setuptools.command.setopt:setopt +test = setuptools.command.test:test +upload = setuptools.command.upload:upload +upload_docs = setuptools.command.upload_docs:upload_docs + +[distutils.setup_keywords] +convert_2to3_doctests = setuptools.dist:assert_string_list +dependency_links = setuptools.dist:assert_string_list +eager_resources = setuptools.dist:assert_string_list +entry_points = setuptools.dist:check_entry_points +exclude_package_data = setuptools.dist:check_package_data +extras_require = setuptools.dist:check_extras +include_package_data = setuptools.dist:assert_bool +install_requires = setuptools.dist:check_requirements +namespace_packages = setuptools.dist:check_nsp +package_data = setuptools.dist:check_package_data +packages = setuptools.dist:check_packages +python_requires = setuptools.dist:check_specifier +setup_requires = setuptools.dist:check_requirements +test_loader = setuptools.dist:check_importable +test_runner = setuptools.dist:check_importable +test_suite = setuptools.dist:check_test_suite +tests_require = setuptools.dist:check_requirements +use_2to3 = setuptools.dist:assert_bool +use_2to3_exclude_fixers = setuptools.dist:assert_string_list +use_2to3_fixers = setuptools.dist:assert_string_list +zip_safe = setuptools.dist:assert_bool + +[egg_info.writers] +PKG-INFO = setuptools.command.egg_info:write_pkg_info +dependency_links.txt = setuptools.command.egg_info:overwrite_arg +depends.txt = setuptools.command.egg_info:warn_depends_obsolete +eager_resources.txt = setuptools.command.egg_info:overwrite_arg +entry_points.txt = setuptools.command.egg_info:write_entries +namespace_packages.txt = setuptools.command.egg_info:overwrite_arg +requires.txt = setuptools.command.egg_info:write_requirements +top_level.txt = setuptools.command.egg_info:write_toplevel_names + +[setuptools.installation] +eggsecutable = setuptools.command.easy_install:bootstrap + diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/top_level.txt b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/top_level.txt new file mode 100644 index 0000000..4577c6a --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/top_level.txt @@ -0,0 +1,3 @@ +easy_install +pkg_resources +setuptools diff --git a/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/zip-safe b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/zip-safe new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools-40.6.3.dist-info/zip-safe @@ -0,0 +1 @@ + diff --git a/env/lib/python3.7/site-packages/setuptools/__init__.py b/env/lib/python3.7/site-packages/setuptools/__init__.py new file mode 100644 index 0000000..e438036 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/__init__.py @@ -0,0 +1,195 @@ +"""Extensions to the 'distutils' for large or complex distributions""" + +import os +import sys +import functools +import distutils.core +import distutils.filelist +from distutils.util import convert_path +from fnmatch import fnmatchcase + +from ._deprecation_warning import SetuptoolsDeprecationWarning + +from setuptools.extern.six import PY3 +from setuptools.extern.six.moves import filter, map + +import setuptools.version +from setuptools.extension import Extension +from setuptools.dist import Distribution, Feature +from setuptools.depends import Require +from . import monkey + +__metaclass__ = type + + +__all__ = [ + 'setup', 'Distribution', 'Feature', 'Command', 'Extension', 'Require', + 'SetuptoolsDeprecationWarning', + 'find_packages' +] + +if PY3: + __all__.append('find_namespace_packages') + +__version__ = setuptools.version.__version__ + +bootstrap_install_from = None + +# If we run 2to3 on .py files, should we also convert docstrings? +# Default: yes; assume that we can detect doctests reliably +run_2to3_on_doctests = True +# Standard package names for fixer packages +lib2to3_fixer_packages = ['lib2to3.fixes'] + + +class PackageFinder: + """ + Generate a list of all Python packages found within a directory + """ + + @classmethod + def find(cls, where='.', exclude=(), include=('*',)): + """Return a list all Python packages found within directory 'where' + + 'where' is the root directory which will be searched for packages. It + should be supplied as a "cross-platform" (i.e. URL-style) path; it will + be converted to the appropriate local path syntax. + + 'exclude' is a sequence of package names to exclude; '*' can be used + as a wildcard in the names, such that 'foo.*' will exclude all + subpackages of 'foo' (but not 'foo' itself). + + 'include' is a sequence of package names to include. If it's + specified, only the named packages will be included. If it's not + specified, all found packages will be included. 'include' can contain + shell style wildcard patterns just like 'exclude'. + """ + + return list(cls._find_packages_iter( + convert_path(where), + cls._build_filter('ez_setup', '*__pycache__', *exclude), + cls._build_filter(*include))) + + @classmethod + def _find_packages_iter(cls, where, exclude, include): + """ + All the packages found in 'where' that pass the 'include' filter, but + not the 'exclude' filter. + """ + for root, dirs, files in os.walk(where, followlinks=True): + # Copy dirs to iterate over it, then empty dirs. + all_dirs = dirs[:] + dirs[:] = [] + + for dir in all_dirs: + full_path = os.path.join(root, dir) + rel_path = os.path.relpath(full_path, where) + package = rel_path.replace(os.path.sep, '.') + + # Skip directory trees that are not valid packages + if ('.' in dir or not cls._looks_like_package(full_path)): + continue + + # Should this package be included? + if include(package) and not exclude(package): + yield package + + # Keep searching subdirectories, as there may be more packages + # down there, even if the parent was excluded. + dirs.append(dir) + + @staticmethod + def _looks_like_package(path): + """Does a directory look like a package?""" + return os.path.isfile(os.path.join(path, '__init__.py')) + + @staticmethod + def _build_filter(*patterns): + """ + Given a list of patterns, return a callable that will be true only if + the input matches at least one of the patterns. + """ + return lambda name: any(fnmatchcase(name, pat=pat) for pat in patterns) + + +class PEP420PackageFinder(PackageFinder): + @staticmethod + def _looks_like_package(path): + return True + + +find_packages = PackageFinder.find + +if PY3: + find_namespace_packages = PEP420PackageFinder.find + + +def _install_setup_requires(attrs): + # Note: do not use `setuptools.Distribution` directly, as + # our PEP 517 backend patch `distutils.core.Distribution`. + dist = distutils.core.Distribution(dict( + (k, v) for k, v in attrs.items() + if k in ('dependency_links', 'setup_requires') + )) + # Honor setup.cfg's options. + dist.parse_config_files(ignore_option_errors=True) + if dist.setup_requires: + dist.fetch_build_eggs(dist.setup_requires) + + +def setup(**attrs): + # Make sure we have any requirements needed to interpret 'attrs'. + _install_setup_requires(attrs) + return distutils.core.setup(**attrs) + +setup.__doc__ = distutils.core.setup.__doc__ + + +_Command = monkey.get_unpatched(distutils.core.Command) + + +class Command(_Command): + __doc__ = _Command.__doc__ + + command_consumes_arguments = False + + def __init__(self, dist, **kw): + """ + Construct the command for dist, updating + vars(self) with any keyword parameters. + """ + _Command.__init__(self, dist) + vars(self).update(kw) + + def reinitialize_command(self, command, reinit_subcommands=0, **kw): + cmd = _Command.reinitialize_command(self, command, reinit_subcommands) + vars(cmd).update(kw) + return cmd + + +def _find_all_simple(path): + """ + Find all files under 'path' + """ + results = ( + os.path.join(base, file) + for base, dirs, files in os.walk(path, followlinks=True) + for file in files + ) + return filter(os.path.isfile, results) + + +def findall(dir=os.curdir): + """ + Find all files under 'dir' and return the list of full filenames. + Unless dir is '.', return full filenames with dir prepended. + """ + files = _find_all_simple(dir) + if dir == os.curdir: + make_rel = functools.partial(os.path.relpath, start=dir) + files = map(make_rel, files) + return list(files) + + +# Apply monkey patches +monkey.patch_all() diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b35792df498f983b8ba300594f88859cdd21a0ce GIT binary patch literal 6481 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 TFs40Ymulv$SwCXeW@r8l9|Mk5 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/_deprecation_warning.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c6bda1f28a8b42cbd4572bfb138d9f04810b67d GIT binary patch literal 512 zcmZWl%}N6?5YBE(TNVo*JbK7UDA@MmQKS^1w_X&4MaZU`w2fqw?M}9(UiCc$Z@$uA zeG5;{{@4~An8`Ok-%Mtv{eD1D!jG%x0^je_`I9z+2`XHmnGr#R_l_#bTPyU0|3C(< z7&8a)5KU0w9E~JcLqcD8VXLk!E+3@JQ)jJ)dzof3=1y7j#51GJ>h&|AC{qrS#+n1r zrOoKBPEv8K2dWH>A~^JlqM)Kat`#&?1jagKWoj!0U1l~x%KxEJbWOPtlmmr4UQ-2C zr>z3D(2_3p*kZ|Z?M796K4=#`#tcs+V@1GNVnwb?e8$)&=eo&s851^U?2BX_JVj-G zW@DG6<5Z<XWx#Q*hw*M@UfkwpeB9*}vXiA*bBIy8&&o5G3O<@%r}F0mzvwoXtOCcu SHR@t*(Yvibd{@yiLVf|hH;*m= literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/archive_util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1010c808beff4ba093c509350d95f7d2aaff9343 GIT binary patch literal 5093 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/build_meta.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c5e04eb1ce82b9934dc2d5ecdf4a41ace54797e3 GIT binary patch literal 6215 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 Q<?2$kRHMJMmZ+WhH#qDjegFUf literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/config.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9b17b2f0667f14bfd57df319b1a548d11faf209f GIT binary patch literal 16961 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/dep_util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ea1109379171add7432d0446d825ed8818dd67f2 GIT binary patch literal 819 zcmY*X&2Q5%6u0wHMz>C=;xKMLkwxlK39%Chp#fJ8ATg-|RbK3-W{#8DjtWzDq5L1f z3GpxG%87pgE<DGr)V;_r@ALOQ?6c8mh=69_9=`t>BJ|rSTM9sU4#yk;V~AmiN<70D zv4DkN(JWxmTa?Csz>8Ac?JK_GdS2+NsdJa>DBheG@HY~eMJ-xm;CPKMLw#g11L+Gc z&`kg*{B&jmAG5|U(T7JjkqukaMh_sv@pYiHHuxTS+Yjib4MFRDPP@v^Q5&@3B7ok4 z>wo7|UXqK-E(z5|Q*vbu5sK7QQz^Ne5X+4fsvu%PIL(*DRE^F#>Bk_#kbbHm0kTV~ zh=BaO(wdvPQp_b<0OmF$Z@6u=GK2!S(4<-rDGWp(dqm?mV<sM}PckW4ExG2KqR`o< zp0DMRCxqru(buZL1L3@+%8K0dSWqe1+5K^vWWD|RG`UqeAyhGvcvO>+vN4uiaF0k! zP9#@_U8Zptg47M)QQ7cUT35P@HB|-I?pC`2t!u7W8qW@I!JF>R2D-be<{Ot2w^l5E zA-xX}f1gZkSx;+Gp9p0vT*OJfD%3}N^>}Jvi?yvPX?8`%>v>~^%<9kGeLt&P@=6%) z*E(?TYYYqx?%};K!Vw<BcZkP<9)b0B8g^p__u)`Xw#Dlw>I3@5cGv+Vb$d_CiZzly L!=M>A{XzU6lA-P1 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/depends.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..753142469d7873b97999b6f94354951dc59c5efa GIT binary patch literal 5228 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 BU%mhU literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/dist.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..20057504f697210d93c6beee7d67aebba31c66ef GIT binary patch literal 38403 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/extension.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7153415beb0df8c51cb330ca69826dcfdc12647a GIT binary patch literal 1939 zcmaJ>PmkO*6t|tsOeVWCUD^r(t%RXf%cyON5E2{;swfl*p+%xSK!g-!W6w-x^RKqk z-5F(1+betoXpejhzJ|q(Q@;Wy-b-e)tyJOYJwMwo&%gK2Uri=Hff4?3<CnjNg#3ex zv*ChpA4oUA1Q9eNVK>u|wrdtT?d)#nK|8Z-n2*8{CBhMI=H=sX4Dvt>pOMg)ez+sY z(pl}UCZ{x<eoMqic+ZIN<n+`DC$Jt1AJ)E{!1{uqkH~E2B_JUCGiseYu3l1DfIL}9 z6V*i(n`9|Pf+{%h)B}0|q(1>B=m}Y0Hl!hfEvRsQWh)AR+(*PEh8_CqHie%k`I!{# zCjbf;4mThB9LA5*)T-c*RV{fs=MUCqSr$Br3w{6_c~vSSMbN5l-s?_-uTyPmlV&<N zsMAbD^4QpMF9L3FuF5<Et;Y{%j`gFcGZaN?0BG&_o8v@QCM}B@4R@0EN>s`IBx(!_ z|K7W6^6GAtR(H}un>fqvBu9&4WuAO`R|DS4lx3!06#;=PG#Cu3wcU-D@lzRfc6TvG zQ((k(DPw!orBgbjY6o`ufZ{O&x(}o|Fi9}~Arlnx&4dGab%iSiFhiChd?R#Xd*|k} zUgTyO8(wRv`OP4?$>(VXVp{MjixbJqIc!(!<LyD>z*RUfDp-p@0O^l_HSTjrs$efz zLn3O}%4tYL8#Z?u=Xch)zhQa_;BfZsv|2}5nx~MbD6Z0nGuJv*S*Z!wf!O!htOt20 zQWHh9fpxXa=GHCZT-uQ?Yn4cC-B>NOWrs&?7CMH_qxOJZ1JVeRI8(a0*qaT`tR`5N zI8X^aYRhvU1Vc`V^0CevvZB>R!A@vHpR*UxKZi_R7jD7C;Dj0HxoZZip%^yog>&MV zk?|Vvd^J90rxYSFZhK|4`Ma&hu6(=5Ze8F<sabLiF_&lQ(cF~$wR5wS+<>pr^meki zSk&=Cp8po`$IDdnTqeu7NOjJk49g?Ud(F6pR#Bbxx~j5uZ>&=CPEr<6CH78#^+9bA z2^`L)f<loU&MmU8#n7dFOEyk&>(<5%lB(LUAlVGiqw6!jty=4yL9hcrB$XY{>mq4; z!j7s~nKaHUQ_?!RKCmwKp~C7`mw?S&^%hL94IYPn7Y6KLbrn^x{mv6_uSQ!xA^;F= zp+=^R@b4MuYV0pE95R>s^fKL}n;WlG#{c}hKO15}VgW`GJ`s5->I~)GD0))I+4f`< zMWRgL<-i(L?;|_M*h+1MA`A|s;fW_6b(uF*xc6F%V}afW(rD}T7ROeyqwmuL6|42; zi|=Y}c$OYY9&;rZbrvh$`*oXRD)GHDJl3F*b-zKMYa?T^4>9I&gZcp3hsdrWdlT;K zaPT>h#sqm(;d-{GuE3<;1!kwBe{7QyaystUcCQx$sT7o=z4Xe?S^0-o&Y#Qxn?e<V zPLG4Ud@6NY7vV53i$l3q*tl(pg?{^jR%<1Xt&8`z!BiJe0U^H07wg^Ya`+|2S-%a; RquY<|vR%i!-~!)!=RYf6{Y3x( literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/glibc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3ae91830fc25e9a3457d91fcddd3643d59130ea5 GIT binary patch literal 1504 zcmZ8hTW=gS6t+FHv(sskUI-Ne1eORWBXU8g4-}PhDUA?{R#k&kv=ogdws&{3bF1xX zNHlp0|9~Gr^2lHED^L6do;b&wh$LRw$NSm-e0;uh=DX$Pgg_hr`N^vvmk9YA|6Dc( zlW(A#A7GF~(vnnkOexM;$;QmvU>tZGjzby9@OLsE$bpQ&Msg@)utRxECSYU9_DFjB zA7CRXb$9Z8)0CZ6Sy8o(wj+TH*aGM=^rz6xa~Lc+qmrJ}6LOUF<ba*fm!w_|i4Eq7 zUZ(_qlJ1e8Vdp{E(`?YwQ*y#=)H6FgWoEZ$XK+0*upXTVjvu{Hw$ruY)3VqX{EgD4 zXlib(F6!w9Z!{k@wc^Eu*Nx?!0d%o-YvcyG5k-;Sa*?n{tuiir`u*;%Tb<TjHdQu5 z#_WR8t$b^Nb06OMOzTFwSY%?B>#TJ{tqh)bNdff6=Cx2R01sRwm1v|&19z|0jZns9 zbzUjc=0fQR0^)98&}XpyFQV@N_U{+lwraQAqTTdtWw|L1r}cq-{czjBV_VxarMWuw zPv2^f!1JpvBPTo;6T_^+K!yorG@&a&6vQ-Q2~C*32e?3?u!R@h3x?UU5UeNX>?G&| zvu4>@AX!fy5F4H|5G&XtcF+fBkqpo2DedW;H9Hr`z$0uv0HLDM@!I;=&mUL$L8G7i z^4aF2Uq4M>ZF#7u|A&shdiGnZgjMo}pofK>@z1$vAjfJ|Tf;roR)wcG__VQK@{i4q z8+aHD;_1*atq`+f=HkO#*ANiU8E0<gMOWLRQZE;<3yRvh!BjV0n}&J?p6^z)dfgRT z$!tNp475enRhg%EwDO8AhP!y+EiqGKo?X*n4HgX2k>L^zX#^64^gh)e03xtBv7rPQ zejj>Vu>>=}hvJ;a`aV{Lr9FfmDguI@ve8buP|x$EfqoAT>GyHKyKXx6_AGy+G7MjC zi~Uk9Tzm*S4VEYYw_<Qhe+YAd05%F89lY)o>7huyQ&563=*a{vIGBdVfBdA6xNW#p zR%r;5;&!I4OPM4b+GW}195T98yqR3otl{gB#2c5Dobtn2A!a~0$-B}bx2jrubh+D; z6*U*RS=?1N&Ae;*Bri&{<yS{3b3}7^2dIk$l2V`c@a<Z@Ce+QC#h2Bz3uhN$ihP)u z{s<8Ga3ona>EQdLvP@&3G)kzk*z^M&u)4fHKCb@Ml}oVNwNIP)an;DKR8Ince6B39 O7zBxf_}%z!{LX)<RfJst literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/glob.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7d9e4d27971405c092bfa68b8b0ef83607ecc6e2 GIT binary patch literal 3714 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/launch.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7c08480b321fb0aa551221427bd3f716b8710b6f GIT binary patch literal 818 zcmYjPO>fgc5Zy1wZrXA|i1xN8q#!jF5*MVZLU2V@1-CTF+IqLmw)WbrCxt}GDRAUB z&>s0qd*#%>z=>HKL}xYQH#_6;d-A;5-5nCN$&Y8#$DEK~G5Kc<!E5w(j6stL(NwdN zPH6XJ6Q;QqU&(|Up_6OopBug*lxX&Wj0VfI;X5^V#Z1D?$kPSPYA4&m+Xf_}cv;j{ zrJR<fbw;WSFn-t?m^V<@Wh-qf&+8gm@TzHymN!;OTQ#+Z@$eoAk&`0EXan>F{VjUy zF#ys4dc`!|Cu;(Hg`^_c?|e=Bd(FSG{l14sd_+J%q7xWw_?oTQifrg@dPmlL#cwk` z(CHmp3)or-oRwiu0>f3Zq8o;SISSrdo(?72`*|<!uT+bo7wuU2%bT+oAEiQF7t(^9 zDc!Z78{?#PH}y42bPDEPmE~gG)$S=u30a<3%DOy18S$80*wW;AL{3!^rFpLF0)eO- z<CbFTr*6rnE(r6*6r=61ljrAiTY_~hc5&nrL?jf1wgrUr(trZ+Ap>OL?9%u&epq;; zbV$8vN>!MU;_qtk+djkMXb`r0g&m8q6}hxc>`NkxJPi8sWZTug%KIdUqSodo@lSEY z?^lOVHHVFD4v-k2?1SR-rMrSpFAx8(!9!Sf`!sGAf&01J#To4$29gLmq^vs`+haSl yKYkx;9+#So5+7H@KZ+sldtZtx(@}X4;=qs{Rkfa%=2&3X#ur4A(TrzLGWrK}rQOE> literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/lib2to3_ex.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..44981eb4e6e25255bce43c1cf1e21db2b91c2cbc GIT binary patch literal 2397 zcmbVNUvDEd5V!YFve~9>u2*PPD6EcCrAXIQI(R?`P{kcR@jyUO>Cg&TrLmLSbpNEb zb4{c4seOfy0O=!N$r4XI@fGfg8E2EGRqsG}<*~gx_Kbh?o7pdxmwf^){C(%gKg)#t zg^O8pV6qQg{s4lJkTA-ugr-(#Q=Hq0le(d6=1x*d%V9b7LeH$-q!L!15msX5OTx;$ zd|`(^tUXqNb%ooowwU`psr#cd|H(kAJdH=31z*R*ID4$}4+A;q_j92>@%>;oXfY;d zZ-P!Pf_9$0<U+++H(+^NajB&5`-d-L8KgNIBs>tUSaKP(vf!%}5BgFF*q3L)w`b}F z438WB-*7Qfr@At?3JW{QyLC&ie#bklw#o&VILz}zZ*;keI`NPT8FfUSM*UX%xYgy& zHl8wT7EJb`%ZDI12`K<)A#j%@w3*Eu7#-%a5{xb@0|1`hd>TtNP;nw}*=*x!*f10} z^lzZcbr6d5=$Lls*!s=-l>p=fPNL1aB~VSf94}jUv?F=a(RM1k+G&Zd)YkFoA4F6^ z>D6a@D(&y}<Nj`(N!3b{-S%lW>#38E_9Rz>zJgoJ#c2{BVPqmcZ1m4`1#pUtoi+5z zxJpM4UU!$qTz!5kbQSwE-2WeL<-}PhuiL@{eNjPy<TaO>ie*^pB{Y<BDIqp*!Hbz^ z58vonvEhIF<}!XX=>Ds71~j9(x!~HHK{M*jdP#dxl(kYGMcR*|Da&DAjiQr5E17-~ zD~L!91x9578w|NXfJ6zzJ?IiA9`$U`Ht*W7oHvZiK6JSQV$S0VvzUEJfyuyO!(@}- zz+?|oSs)1x+PD`RvKDPTfi4AzG3fzs89lCu8ZvfF<tC2Gn%H>q#2M2ox<Rfe1>K2z z1<Z!AWJXIIsdCQ~nX14!{sld^$98XN4Cle)`~pQOtE%c`c?{=XSw&8`&BIao0E<dD zctrz9Z1+^eiigXyvJvH3a#ml_RR&oo;v-1JJPW;n<PoynB$QYM@3qs*<4kWy^J)=A zM}s(F)2d)%BlXteXFhBv1ICN8q5bQ;3fILTGX}tZH1oy8K`)sqQ=I3Cq7FgO=Z3X6 z+g*1|I%u~OCtQZ!>?BRaLhw!81GvLBbcxg>c9lBjS*O4On3bqc*R0Xn+(=_)qfK!G zGz_l`-30UqCKyoRV+gx2kI3*nMSIp$^3(b`#cvZ^K}atksFa*+K1Y4GS7HPR@bfU3 zu3n>k@O)m>$^zXM?}7;5o)w`fMnw&ly2OWyXH1}b0xuY@&LUW#548~sho=2oz=Zej zh+_j(CFT(UU=W-tU5CCxN88r`-LY?u6(#{DfWfK>69u<tv`a2*gAL$haM&5si491= z8c`ZP7*jxG>)aY!@YXpliAOk2+_Cw7@~FVYYKAK}=>-*{4F9N>Qeuk0#vFm0isA!s z$6%^Uf~WaQUev8{wNNZ5EkpmBinmd#Merk7r1!^gs>Cuw04RjYhiA042-nRG%{o1( zm&ASa2Ft&|axDTBTPWT^Vd~bkFib`sA{&Yd=HK(CrKi56%Mm6Ml*JWHXY*5SpfsgP yybqgnW&UOQv#b@AYRocCVBDrmLMtXI@A5-?pH8dr=SVDbb;rW1*DTMjE&T&5o=I5% literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/monkey.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..aabe15ef101a9b9911510e3770a09ccd02daa2ca GIT binary patch literal 4598 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 F`7ejW*%JT& literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/msvc.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b4dc8acc992d9f0b1de5f455079bd4f3c527453f GIT binary patch literal 34395 zcmdUYdvF{_df(3M6N?21f+R>m6g7hQf<!K#M@h6!2NED9Srnurc$97r_GXD$fQ!fO za%MpS<Au)=b$7Dsbaio@r=2qpSEX#19Vd=sJ5D8jR-8B~$8jp<WKwmNa{fpuRdJ<K zsiaDFIr;s*p6Q)k3_!|O9tLW9dwRNiy1)Kj{q@&9R|f|23H+6Q^!V&oe>9Q!kGu*0 za)?aea*r5^gq<iQY{NE}jgle1X33P_WGN}XsZvUQ)1?f4lgrtaTq$R;OlrArC11)T zp0+c~{VRo1!AMk-n*&=3JG*2$P2|ZT&tPc~>Bi!o(olW>s|mZ$&cC0q^AF9^V0G`q zL}{oxT+J-*TiicymJX~Bp;Z6!$jZUeK_l@_qP{<ss2*6#J3nV6`2WR3-F!D;7wm!e z6Qx78W$&?v-Zx55*n90^q>S48?EUzC(tgGsu@B<OVZ8B>{RH0l1m5@*?ndn=arY$d zj^OUF{S@w=!rjxjJ7PbLyQgty+2%}Qe5^8ICKCDASDH@ae$}?z)n>Edw5<7tW4&3M za~f`AzGdC6xvQ0BYx4Q$t+~cZv$kAy++sfeM!oT%9u`4i{p@o7^p1b|*lJ%Yp1qv6 z@E7}ZGI*&p>+SW{-A3IyUwpwjx%T3vQ&wfgzI1WCr}R6uy4`r-S~F8`SeJ_Df~;$o zE}pV#mEE(yP&~UmdwjFco!#E<=$l`Nd-D!eUEE$(1nyT?Ys<EEtI=3?t@CHkeJ0w% zinG$&{h;JbYt^nbSRe$JKmY{*HfLo!9J<T(ymZGpJ|gK&j~o8Ljp{;WZv8g!qt>V+ zp?|)%+^RbBm1Vd35y&yYObgXkd9~iGwC3(sZ9f|T3{Nr-YIUc&Fvse`KNgz6<sL>* zO@N9Mq+n7nDYuly1<D03n@$#4rpL2>u3WBHR;uN)pD&kJ8usck<Arkh9?&>^^4c5M zzF7Xk%(a^{{$7bse&OcLYty$R%^#Me8*fcsxlw-e%H(UWPhShO-MBI{b8V)4^R2gT z{Y1jqgLg{s@e5~KE6p>_TJv<R?zSq+%ctiaEYufU_b#4stF6^$i-Q-9uDJK-ip_Ot z_DOb;oGWLf<X=(&ljKbRgh1e58dpEANnGx?5ZK0s(FS{KC+5wO#D=*()Jkj`ZPQL} znHx#4m+wp^S|-@bqGB)WhmkuK=I+URD9CH8ymopcso0SU+ezmKTgk=LBCgGJJ85U| zjucZiGwsxt;rw7bHIry%Te*iuJMoZ1lC3;X_CmsbTMf50X4l--YOA*F7TN!oLZ(ri z2gR1}&)u&$E?_riwHnr{TeVtus}`VHw=2tydR3|li&%GrD9Eb<rf~B1<n@N5ZpMq& zbyQ^Csmv|0vW8PzsMW#7?o{tq?$;WQ)b-$Qwchg%&Bv^oYt<Vqt8%|mTdv$$u7c;W zD>til&8g0{q#V%ruGN^g#&pw*cPg#1AnT4SQYzY+N%A$ZtWYz`9dkSuvy|7rU2#Aq zAWyfaHFA4j5%Fbfez{R;NfO_AvwCk8y|?3=7ZlQfYOOl;Nad>HaEu8ki}1UQ5mv+D zot}Zfc~Ehxv&UQwfZ3_){i)jh*~sY59y?n+H}5C>d_Zg%60h)1<H4ni7tT*N?CR{a zH_$aC<9*IvP>kP4_H)0oyjt~hZ&cT>IZngz&4%lz*c3mt*r?V0Ow9%7syZY%f4?AV zxf?;p(|$JSZ7F+uvV8T*%r!r`R9*M;kfrwOTnjDo`*agJjKUd0rOqgV&*5^9AV`d) zjDlgBL&hM&g2CS*Gi3}THDyX(KM7$s2WpbP3_@x^Z{c#kfna^Km1r3cjg3?r<lQ#r z&9?b1vz`0~$dF`Bq6Hf`ueA*59j!D{rgRGQj`hJ-rcL5CH?v!bu96=ZiH)?8@P=Et zcA9T^m^2daL4$!lV{D|qH~ns?y9h6?{K#Vy{=L<zvmT{<5_G7DRM%QgMbIXsdTJg- z#F=W#s@Ct<oJM`6T5nkoYS0T-Tf#K{%+Vt|#6OMlR#c7HQGwaHNW2o$oj;;pbQGEH zEYViPD>KahNJjD}WFoA);><<(15<8Q9FVX)sI|a`SDg-Hj^j5GB)M$awK>Jhroj({ zx(_Jo?!iL8Ps=GkQzegZ{gJ6qbiKV?X#q=D6!Xa6CO1*>J=Z!Y`Fef6;pZL5ey3hW zEBxVdWp#nbTCT3mRhup9NEtr~HsYt)PlgMwpIHI}#BYis%TFS2FY~ZK@rxw=LkJR2 znMMw*Vi*i#(99%FFpvFU9FB!&T6G}jAjc5Zp^nIUL2(Qvsv|t&XctEqYJu88<K~Cv zW~PTH+yzfCz!QdAS*R7pLo?tANjte=e6OK7LK3P#s&Zl%j!@<xgcM#Z3yYp3%*I6L z|Fgmk&S@o{h}t3M2&MJt)bWaZZ0W~T=65UG^YR@PdSS4;Q*{$0P<ETuxsLGWn?D`m zTmXLJ@6-eo;Qal$@=C2<29->Y=M>HECAyru7{L?g8RU1y7(C117=z;sP9PXJOMSY* z&S@rVy<LgpGf4YuxZGg`i9;snXIN-y2(*+p96s0ck|b_;iS)gSh;6hIi^fvMxoAW6 zUN$$(R<dm_rXCutq>XSX;atRhdNH$@rR=0sZsl5iRFu`-c-s400n}w$6xEZviDRK! zFE7{blpDf7Tty)BwKXjyE3Mj{+H$S64o$c9pbGtVtiHO^TrX;lHfBMe-ti4%QqxIF z;c1q$UbfB^&z&otSCdR{Pfu+QXD8EMCd}j~-F4T`s(F`NN=tT!{KxMva~L@{ESF`( zN`0E@OM7~HriOY%4|P|!$CJ);sL^?z)tdEY?|5E7`Y+>h$@3DKyl}`N!(qC^F`nZ9 z@{g(%<CD1DpF+?EYqgCh5*ta(tCE|>R$?jRj@ijD?rhpAs#%NXe4>?nnD~Z)oav1; zSYQTbA*XG!%x22YZoxpblydH3uGIGe>T4(4X*)lXVEo=DQu`UJ7g4f+lHWwifX+9l z^3{j%bk9=SVg4cYbRK9^PS|_FR)@W18LlffY(>=;CMqr`JDfFX8Dp(fUAMA;xm3ft zTU~Bi3#&C7cgTYomQuVcQtZK9XylbS3MS}Nm^?XEx3PS`YSmgrd5w&<LzUIb-B(tj zIqz&Nqx+s<q%TuZ-{4%z38oH3@AQKQ4~i?HeW?h>e+Jf?Iwl(SnV=WNirZZKT+ROM zF+1P}V-uwmZ8snNFZ_AWS+7C~s42bA8tXKnTV**rcG;?3Eug)}!UFS7W5v4LYBevP zIa67xU>bVn{#;Y6O6Ok)-gR{1abIwbFL=jFBs9<RzB_yqRnlnF;>7?eU~617M}ZXc zV_0o=fRB4-dOR(-@28g=51=|^sEJfserCBb2Rn<O;zVUUquAV&7%FER0SHoIfuDkz zV!4!GaYK;z(hfQ1zrf{M2tYgLA!-(|N<hm<=8VBKsL8}H!=&)nIc5z1Qix38a_=CB zT5PH?8<0P4i6&9X+9^8?TV}4>XJ_o}`!E@l@^;SdLt4L`xBKy1u=m>o_Tc+QX}~@Z z*g^+k`J^?}DDAQLfdmfvg-{=(#^t>ym^!)YIGh%c(*;853RJ96V|1+=@)B;q^>9kD zyTp4;O_WlwG=e$c9N^t>$}ASXRdF7&LjLiWz!J_gf=JugOn`Ghm9ot(*mTOKjY-&e zavGDrOBemLvUDb$OUUbIohn4yTvbMQ-1Jj!b$MQHdd8FHuv)#=DwqEd<y?8Y;T?#= ztQh9d>LPi%ZX4&S<chr5I`B2~AWZ9DF`o$9XOtc0h7FFm=DftX;Y={zEol9GOVs!B zTyyo0@mMv-^bU44r<13vL2SAJi%eay=_OjR&1vUpq~MKwy2FbHf=X*{88d09su~od zaqm{yKH2O2{yBwp?A;E{7!0$h7hp=Q+wo*qJG%2-*YYZfE^0s&BY<#*+lDhtv%Y{P z35jyFjmw5r&V~}dm>A(`WmcE)PN5N^YDg!|U`k_Ar>o7^<}d}nGv8RYt4=WCX6_ye zVN%D4rR%&4@d6lMw(h{>sZ*I*O@^!!Cxk9(Ts!e=Up-;f=DVhI6c#A2L=KAq`**3# zj?|XrVnA$#LOhYK+?08lZk_6ezSW)YR&Uvu6McfgCr-hn$ex^Zt5qxLGR#?lO-(6F z%rCepl<&NP;qp?m=#H0!feR>djR>0*O7XKnCC+D&*h@DWwP04l`c%TD-jdjhX`kU8 zibWh`{Pd8fLdmb86EM{OXE-wp?1&xYPk=QXg$Uxz3Vy^^`srcLY(UhX4(<rEQ@G>2 zN|cGin~>iE8@L`CMVnZjORNzQfeOiLXd~f^+_MP4U~;xmhlOzwiwy{|)BrYfSTUVV z6T%B~e=IOyF=C6HIbCT)@n#YWimvr(q77vD+z!0v3s^lkA&3IyHUNA#o2lN%<OsY+ zKb&(yNevdHv7JOrRwc-#Q~%`rLy$~Kqwe;A?dhgOw1!jqoova85Q)mF3aJgv>u}2s z!}-{l1-m)smd8`VX+%CcuVW+~+MYwklMA8fXM^|ma-Tjf1-oS+$3=}qLxbj^;f-|j zo-o_=xOx4$T*meBA%`nlP9Fn`Za-Tt+l@J_$>rS2d{t~?N!WZuu~7}Z!fZKcQO&B; zT379!V)^R~USlBLc$2Y?iXkzvufL23{}q=^=ySOg?CH5=A(cz!lKGMRh{NY|xbz?O zmkC_%Pa^16TNl&S)M5r#7FTXQRqCS}3-vT#?N>@HRM!IHp&C1YxG1tnA4FV~S;Y4s zE=&7}4<SBi?-8|kFXBV?UWpGQK5Xxk_&&t<+Xp1RA4~ZM?L$y|57<xGqj>v>{Uk{2 zDZhXvLRco9by0se1zS4vp<vPxSdW}4<UCeyu*@n&KDinkQZIDM`Nm}{I{X?>$D*lY zcn4ST=3u5J0&Dg{HlsBeQR&pYmRgFz<z%y2gGR|gDGhYJHZtNe*u<7E5;28yLAi}W zBwo2iZpGI)?rQzmds%m2NANYk2Q=)k+S8%BQb9pl0a{wPg9=!PPV;7Uv(w%aUCoZ> z>e55mVqwYbI}J~pWW`tz7nW;!-|@(9%&g7q)QcpZfm?7o;v8f^6SH#*!4ADix@#_* zr(mD<hPpZtJVfyXyjvo3iXGbi;?8ZS`^oLe7j|qoo^5aV7x2y<8gAa7!>YJ$_nxkH z!y3)z^6zn){b-Qip4p}4GoQ5O?!BE`E~BAa&ejXEMDYA`y8{{0AY4$7M|E#_`-1Fl z2#<x>GAb=ABg<N(>7zYBk7VnDe_St4$Mk~kK0CB|utU?x<?h<vmC!U*cI~Av@7Uh1 zY+dbr6p6kP)Aqn{btdGU;=2^z8HdXMc4Yq|Q{$)I{STBw6g%|QNQVw}4L~H*C+bcd z<19{JyJcPHZ0JG5S=yyDr5tize;0%DiF(vmueRpb*q;w0{Tb=%kIvH7n>b{O>p^Hq ze52NKt()NdG+_o}vy1h6hof0%Usvuwkg`%}H%uE2A-;rnlpVg~ha$asx~n(a^LDHP zL^vXakUE`-sG`#j?GC~QFbt*LwBZp%M*vu+VTp#4ZfwCa02MutH)?!TYORI-L2O5s zu;>U#zYGn6$W;3AtOBTV`(!%opuA9gY2cBAw=6drOC8w?&3k*%>s0-zlv}&C?Gb8v z%eiccGl&L&%+yQ$5m%B@E_6!q`!o}Q5q1V(R{ChSv;-PY@DV-ML>Dh*>hMUpbWt!t z1r&dNpJpIG%t7ZECiaX#rw*Y)g|1@<*0XtP(*w9<uzw8^DghYW#3CHBs0wVP*M1Ve zsj0+wZEj@NN8l5Zf!7B7Lu{j+e3;tE!ZoZ!50F-7p6+4aP;0&@likb#X+Bs#6qd2g zhw!%xOWpf{NU8T#sRyH9Ox*i{cj39p82wkp4Xv-8ZNrSor4;cb3E%aL;rjBu(RUN~ zM&UuC)`#~+(eMVwUzUDlaA>X7i1+^yUecFvJ7S7EfW>EAaiKLnLMxvf9|4xct?BW+ zcm%>{32uuwuU(n)vu`!4^*5^P&UYh&pQgj&3=(IQBSQA|w<OZRQorzddfF&wg*7at zPN1A1sh?tFoigrAS<JZVAXVR7!BWCq#!`0>_Tny98yZWi&7UUXj-g;;PsZRs+?b3J z7^U*~J;YzE6qs;mf|+Vx7h0?GQ1h>kAMBYQI@4@fmI1vT9W37@93s3k$e_aD3WLux zpl<3=&vR}wc!$Be3@8qr5`!->m}Nj%IW-1xlg68P@J84pP8!ue*EtH=-v9it!~Ao& z^dCuh0+)LfwRBG+!?lkRCX$GQ32&JtOehggSF?!c><f0*&S8Srr+mn<8iMH}S3|0p zG-4HmD<lJm(<hwq!N4mV>mcG4K7?ln>=Ajk7jaG(nQs_znKB~25Ai4M!;-!q@u%z~ z5<h_W)3zn?5yYRd$0U9b@n`L$5<i6aG5fg0pFsSCeNy71h>zRPN&HE~pSMp*{4nCD z?V`k=!ph!R^yP?s(LQINM=zhYGY~(Y@$)n5ZmYT?lh^+&Y*;f{?FGeEocM_>)|ycm zJmHfq<~V^M4`#7Z%+!)#ESlOoi-k&y1<pT(W0RkO(lAwXMBZQt%V{h?S-K9dL)Y6I zy`z`=__SvJNuU>}xx)NOd34w-i@b+9E>VU_t~uIH&=`liq^uxeHl6ZKrzXt6e@eMB z(h%Ub%G$dXE_m#cpHaVoai}!V1uCb3H%4fOa!hFP_enNllLiyWgV;Nxx_tu9_EU&S zAGn&eUO<bn_N9e|0ikqO2@2>fhSFQ0u^8_e!4?U%^5lF5rM+X*jfkoeAPVP;!5TCq z$tu=F)BcD!arSoE_4BXSv1Fkb<};|#Az;OmBrrh04a;$Q`%O2h|HOXNc#!~`E66gb zcQV>{dE*YS)@ms^oObNKges}NL8fCs@yqEwq`HKu`Q(PV0Jni}8f!U8Nkhv2(MD?R zf3!`+{$L{wU(n2E7V_I@rz!DUnZ?{zY9j-gKMLvH*UF2`ZwAu)MFmil>2GJYjM?Ny zb|bgZxAu0c(1t5F>YUohuRqrsK#oD^5qTxk;cMF8?r$fTvd%BUHDXV@f6L&GmU~~v zJBBcPzpdr`*CFS>{!T(_%<39XN{xF}jh))Q2^(`)ecx8~A>Gn7ej7D@8}E7%SMi-h zYZ&^8_?>!_ntZQA@LKc$*TcOlj$jd()+zppm&5ozX9c68B!);95h@~HDtsXF>CZ7n z!Rg##Kw(f)a+drI(%DZtmHI-}Pm3FMsqY%xVMGM`nMxC))^?7fjGtvXvuCho3<KSG zL5b&iRtSoO1a?bVMVYR%z;}syd6&<#Sgm3PkS;wDUFRyRG-?hf0=-DvMA{z^Y0o2) zNaY}{VH_2CJqjtE6X#<SUQb-%A4ED_lI1yEk}1WXi6D18HEFCStJ3QSBy;GIz+`Mx zFj~f<xk-%XGz9)qh^4WO0O4Ym+ZmW^%WT4H3Nj+;UDRXKkqzDQ0H$g9f;OCpMb3L_ zr_AC!?xp1iijeTM5wx#k@$&aXSui-TLI%+shynq3bgGE^S-U!4SzT`RfZ8wIo(blH z;PVAAJ;fm5jWm?>4o2V@&8MM9{L;|-25txy10kn%&HakS1CnYxMuNU&0^b}VClJkS z_F*dsba1*JInzN-tk7(kb+b)hag;(Hmd$s{HkaF}jkM(MZ>P5m_XptclxY<f2T1>9 z!R<6Bj^4SQM}^EcZb%f&oqgy|$-F)3o!mA=T_t7RMKSL^PMfgqD=z@UT?i|GNJq=d zvhS$ZYAN(9R4XGagGWmC(=`{3>+u;J&kD);x$p(097JE4lTvsOihmH^3Z+a9HsXRV zesaZK*go=;osmDpk>8K^Cej&mD0v7JHIh6GH-9+&!}B4E2a!@552#a8z=*J<{z^Qs zjU~ew<hmPuZF{L{{cy{`79A6g8Yw!m1<&EmMiVjkX@=W$=9A#k?}j{8_8rQao%fs` z*BfvtYE?tkYf@%p+)bu4kQ3qW)C9I$+@7434QjJ*&fK09!3-bk7}`<;nO(*L1V=$L zPUjwK3MbFsgShj32ucNTz3Ljg(x{#E0NU9=jx&VsFd~Um-bk5T>Y)!by`a7Q5$I}k z(V#^^KqCMxy<B!;P(XJxvOEw6mO$0O@}`5$MV$F{0m|Dhe1atz;X>Hk0*gW%usk#? zP(mC5${r*rFo^Q?y}11xA;69h0^XBxeGW)OcO4R-qegxwZo08b?&v~tnC>HTm&V<5 z)Y;{ZJ78b5bHQC792BqHd0=BdKvnRjHG*{LJG7C}Myr8ETXW!X!aYSmoQ~Gk5y%0S zjZHulB(b%@OJYlem%3CuTL~T=oxlL$5mNCyOg%2CFQPySL6~|nNJZWki|4{rI2)T@ ziW?!kB$6>PmEqXIp1L>a&5XTtTY0oz=NKp|2NptZMlbJhWK6ad?HUwq#iKx?R@@<O zuJCLrH78CWMghEBaa$pj^;q~xI1WP#9xlW0v&<}9(UrZDJ*?9o=rnSw=Ij831D#Aa zP+0(o+Zq|+DCk+S9gk$!o#%u=cYX@^X+!^Ady&`%9kd9aYOOOY!jDk-7(lW?hk)iF zQjMD-ox<CRdxdxCt1vAkur~oR?5mN|Ic|Ym>=QZ3m~3FQ(~y(tcG?MZV%IlPSmR%g z)bk(KUJF|E3S_Kl!^X7<uf;8c&TtzUyRV&rev{H~>&Mneb0Ztn0GD9rTkY(IaqnBw z!vEH(`J0CO+}fp}?o%74oo5est?6T_>0{P}(i8ff1-oChTxjvU9{+e+1Pb(OPBJI; zlJ}3f{;(|GE@J`%M@i)m7AQ_ih;tSTik|k3qIab80xq%4h6qUmI=m3P(fH@Hcu%Q6 zT=w8Pz<~2Ukf8@Bl?EpE9FgQ-W)>~op=VPYb(Wd>9)iHY1%=vPqL`sB3<78bQo9iJ zt9+;8R!f;$y#=1+8+NaN`5KCSH!=DWB8fCb_6S5v3bWiHlcJoiu|p8%N_8&KNfvih zqZvZr!#^vQ20&LD_xn(H7MI9)9}(h#$oT!7{zAr^_2baOM1Qu^kp0K)3{3i2!GF+& zO$x|;2)z#&2ou0&l1>L(rfdsNVZJC1fN(Phey^P*&V#0oY``kq!mb3&788rPMc^*5 zHMwBG%{+b2#*FP0((}kU)|0c}9w44aa(@H4tv2VPhc=|P%|bhC4+0N!?VR&VpvhkX zo<d%X@9{qS2#l<*Rp(Y)+;JPHLk1lG_{2xg0#JggA8~Ml^pg{};CP~Zp<YF@M=k}V zIz3%&U0*w9i;8m0btv;bHckhnPEB|zpy3tg`;iR%6G<!v{@0Ko-ZK6ksiDL1WARf= zje@-zQ=tV-ppsHfmZN}X%1M@uE1C0aqGnRdbk%%~tL|`$1`L?kgOC29kmpXlaZQ8i zZDf3(NO}}yx!VEg2|Z{SNVq>qIaDx?04c|koXrt+y=P-kvbRQ!ov68^CKYiLrzS08 zeL=X6;-})m+&rah``+1@5fA2X*Po3WWN%QZMcC!J+MK=qtn(CJD`O2cJx)y$U0+PW zWDcRiL|FDhaOnEX-HOxf=;uF1$cgC+0t++TsQ%QOSHpzbmX=o6aT8E%+8H9n)?wd; z^g7w5{lrqfa^j|8z)>UckCR#1C@2GKAnjyx%I2&p<Hfl^e4$<g-e6<AHF@)vtfj_q zZH>zC1~<>0EtxN#lfHX-t}b$M5ok|689KIrP+%s!l(z9e^Y&AGlS0L>Be@rR!@4bK z3Wx!0?57AoQNV$EKs=yXK@=b$+EWok+g?(Glj^7j=dPO1L<}nFimgfO=4!oF!_o^# z-ip<NoUgF6;DhWOU)7oQJAajr;#bf|^-EO0BPz@<v;Rbh1T~&xJNGzJrmN>9Fk$_w z=fe8a;q(qlwXD;|B1X(AJBLqgYEafJ%Zea|m%dn}?wrJrjO^}uuJaesvftG7LC#`& zqmd5wuteP}LPHxbUct@UMG^>z;koE^HDDSv_)rNmso@G)<UkfVA&ZygpqixjQp~u= z^gf0zN+ZPo?RreePT0p@L=e&tUM}n;Ska}JaXw@aM;ZMgFhCN&OPJBBn@CeN2)OP@ z4CIhmLydSq$O$eSN2J@kOT<6V-T<@~Gc@cpkG44<NXGhn^+4ys`8(Jy6$2mdpw`P+ zWL7(Elm_QR{|ywoa2~9;hhCP@#)xI?Hf}?Md0<AFf6&W726g@D`i1k~CZvRTGO&t0 z5rI&5zW+Nwx^!_TAU&}IkS<;91``g|`2=8cewYyKp3?hW5W<GH$AZwMiyA^?rb%3a zMl>C98VS-;Q%7~s5_yB}krj(7+ZoA67Ak{d=7?HBvKy^3beeEaC-*Z<AVY6=hV?++ zR;=m5`Tx!?5!(~#E(x(c=cm^xHMB9EVw=(QA5}lRdt?tTUHrqx>;Z;F`iWX8-!xC8 zq#;MdX*~#`z+<AR47b=ioWS%JcMr)6%_b&=n<+KHZC;YSr!bRa5|DOov{N=5I5yJt z%cv!dW69FaS{s}cD{1gQ=9JXVFD0G2-4BCr$}ULWLCHG+1I}0NL75n&vBT7Ke#jo; z1Q`5eueYVStt_MLh$$U#>H?4F4FocCv2(KCIa!7n8BPK%tcKjFIy_iMWxQ~nyKOFA z?AV074s${yj@e!p)f}^Z<GwKXK=_@cf{*R_!R^tBX_6Hb@cS3NJRcM<oV{@FC1ko# z{7jH(OiV&dK$i2!@|m+Q=q;jF`0#A>A!xs&RgoR~Sva;=S}jNE8=`kzLOM2RPVjMx z{VQQJ-vY@98y^Fj0>c#@tW=l}c`%;$Ag17~2~u}QQCA|*ndyFLU;H1%?2{7#UR{ee z@wBVgmqW=-2I8JV@U_I(aGVVHB)*^HkrA8b2Z=4X5>3Ii0H$U7k|iIS&F2Cw<qtF> z1g>P_2!ny-eq&L{&^7w-aCQ@Hp~4=FdV``#E!0NbWgZWiSk-nv9Bu$Xo#H&yx{J*f z%%)q{bgI}jA783bUtU*5;kfR!YV`%zy0eZRuo5Y!tI_<4*p$U}fpFv6T3hKlSjOEn zMUE#wfT4yKJO|Xhnfd?>nX%hg)VZg2dSabE9TBl&;W&h<{JgZo<%VJ^_r<gD76~kO zkhh%W_!-qOg(0*If86&ncGOqbn$9aHi6Ue_DXite!R%~A%5Jv>7GG97iC-z|3Z{d3 zgO4Q<l6=)x&3wo=r|^<iXt$Rc*H0k1G=R;u*!o&upph}~w^eO*_*|X4KqdTe*t$dk zx>Bl3AZ%})Yz<J&v10v(-eTo%GZ5`$nK6&S6$V_hcbW{ud5CLDVlI-E1c%0SWqbO7 zv9B@sAqIbm0eQB=QzAqycK$kJKf>T|FxX`9HyKcpD01%zc8PIVoJ9n`0}<_BL?o9_ zr3#oW70i4(m(3k16bc7(L%D2WsE{ihFFal7E9^t8AL;%0hZ9n6RBD(*Vf_aHCMIyX zH&JiY?a2PD>`%c_c~zJ*gH6^M#KYYwS;WKLDLKT$-6?&Dhr3hqh=;pV`VkLzrxXwm zcc%;>&I2jMEeUZsk`nGld(?51*zJ;5M^PeeFXD0#rMM=gad5#iQf?p8$Lwb%z8~?U z_A!YcK>WCULgFKcpR~s%eh~5J?B^wZ2=P<)X^B69c+oy1@lnLj+UF$xB;x1o3lcw! z_(l6O5`W5m#eTtl5iUtb?3e7za8i2O{+#_C_RC07$7D{(c_NiBg2sjL1I`vXSqM&~ zPK_2TSJucPOB$goxn4x;EO1C&bZrVZw^*008?`&9tk>&v%d2+v6i>~&D_dn@xF`1t zIO8ocqWRUjI;nx%#&AL=&;5YKOb#9B$m@tR49<?@vJ?-g3F?`_hPP(RnschMDF`gC zf)n!AF;`lMD2LH*&cO&=TUd3(91Pz^c6hnAqz>i_&cORpu~_^rIR)>OH3kFDwfg<y z<cd9pyZdu;W}h5|800`^b)Z)dtMA!Y{0Vm7D=&#ZnQNByIz>^-!ikMIB6GC`zg?a& zrG=N~`{aU{Wh;FIZw!v8>3!>)*m=LQx)OnAWI(#=m=>>-IhhH8l&L6^tS3p<R}r)z zJa}GA8O~5p;8Z->5`W(|e01@I6GPa6aoWr)Hdgmr*~J`I_i;4idpI={YMnXl72zr6 zuGW-sH5N;PMg=ZYdD$qZoJen?6-v7y3-e7EXRk5o83tnvo<#r&Ho^Ef19?u1q2n;< zutVX5WXP|flWL+2O$Gi_rsyk&fHUFAZsG(Tdq4r0oq|se5%e8UK`#yOj2@-kde~7V zAwqwe&0}lh=P>f<^K2?u04FUYy$w`Ir?mlOm6<$$UFw0<pB7*k`~c0glhD(r5ToHf zMGj5FJ<pF3(>qV}%<5Q<%RuVxYl(S7Ttjm-D~iKY|8AWP7MR82twG}TPc~Lo8ub@u zU!S_>4TLw6DbRaQP22)VUPY_LjP9KaGoi$+ieFo6RqJAAn$<9#y#;?lWuEp9->Ozt z)OoeDZ{q-1dS_w>pi1$M?Dq6nX9E*~O|@koE;%T1fm+oFEJ&hN0fKOTp-%M|%zLnr z34V2HP*k4O*iz7=Q$NlG>L^{~Ol<r(|1v!i=D<l`sfHt+NqEoqj`ZyrfmK9H(&gY4 zBp5%#x4g!;1Y7&lWZtgdPcBx5w-z)a)!1Oh%m(<`pyqe^_Ccg1(m9X=eY0S<ho{I6 zEzw9vde9Thqqymqj}~!O?v_$R$vprznvWLf?~(LwXynji8I@MYBi!pc9Vr#_pM)~+ zhN7yoTiVYC(#spXa_h#M*C(+bMx@ye1M?o**)<r#Bm^M&+wg~xvhD(5BD^t;1+~#_ zkkA=5Fi3gfB}dT+<r$#7(SY)>hxbD)G1mw6eTw%uD+6<HET|y_#bUMtisj7uZP+J4 zc>y(=5o$CwHNN?$03}4f11+N3fn`9CMbM)mq=+AqrI$utET|R&2+N%&Uauebvo4(B zs{dzbNrr4UT5|q28o9wCQxxo-**;*pw~r*G*NGv)IR}3Sapz|k5KTh75p3zdJ*n$# z@ZE}pKtR~1J_JGn2|c+>J2d8yjEHKJxMXhwMGF>VvHf5HVpK1)r|5<NB2pIEE4z=p z3<vhG%wu;G7@<o=FMhPK6uDmy;B2P^EC#|{M$oLtl7&dFU5E%^nIS6Ntj@b%CRoT& zxljSKKnyr^UJZ^cvQxkcI1T|g1cx@_8;Y|m7_!C%fXLc(5^K{bS)1nCa&k+~rFCw# zLmv*7O1D!qc!_8uPr?KRMyL<us2X@I;~a_XhafhXq#~u@j~JAwe_hJtK$w4w82lKw zFbA{y@a8;LtD|M;S4s~@9Jt0B!x|*DU%~>6WPcP>hOOu-Qy+=uvJ1K{a?$~>b5uht zC+(KRCGfYmaXNKnq3Q<2dlZY;UixaSek@Gk8HhsjL5|{tH*lv`pM9<2w%&d55|}{e z_R>W;Q-;TY_(@cPb!@?o9*iNfMC8<)yrr;Gd)Y{Box>tv&zfKY>+#bq9%1gh!2}^h z3er;UE}FtQevf(wc{V8>{(x9_99iN22<Hen)YupWK@J;-NS46FoN*YA5;@~YawJa9 zsd_X<k~oRQf{`smFoq;h!#R%_l`8%xp;UEy$3j(5qc2`-Dqor`zsrY~UO&Xg9F1F8 zmID64%O}Y*mBZ5XdmHbI^?wb0Uby_YBZ*^}yA&+N&I2AV>yuvQn7g`i%;hn)LiM6j z$k_CZri}2{00f+_2v?Uty9muOGE85=(^6)+b_cqB?;!QRHKUvP;~Xf>HH|~bK@1Vr zaJR9ENEtmSDBE#ip|;hle8}pRVh}j-Fn9{r7LX8#2LQ*WC=l}mVi~x*fI-0JOY}Ty z#>(AG-^1;SgQ4$5OGZuDN@(|CaPqNwaddD3%|df+KU-6}h9*VdTv!fnPECl#$;%yc zT{sU^Z7;>~@v_HYldC%|e03mVx9ez~92Yfy{{XR2i2Xyv#V;vlJo0bBXI$w#zrf*; zW%cwhsU^vC_vou1rvY_}b&Uw6q>#xkAre4Ksee!hHw-uiDb`E2{al;z44i*d8fPi5 zf!&2;07te6v*!B4&!a>*lB!k^kIs+HY+Kxv%JV5WZ;9T~WiEWCO3KM7!~*DE25nDU z*#*@WveqH5<8$0$t<mw+SS&`9jt*7IL-GYeHyF*ai6C-(!h2H9XC|X|joInyDvllR z41Q?<i~o)Ko3P|V`K@>-f)^J%>TprJ2V7~^P#en6wY=;(*jngPdMu_yr?Ad{D$ItZ zWNw>>A*P6jb(kP(_i?0a@tp^idYHR3pl4y=Hm*0M0aFxJ$PFCzO8a8^SjyH_Cm)Hq z#GG&*lY~0r!*g4VQN66BPuK!yI=@BC<*I)oJq(Wl%wKTr$7RZ1l8pSO%<aD_g*!$~ zBahYKUUf~sK_fYpHL@N-axS>TP9i%bWO{6Pai>H?(WYA@^BhIa=J4SV@=}p^p^`~b zQe75xGY8)nDf~a#S?alow71P}5oXfu<@}7YYYvw?8fa6ZT%HB;W8n{kc*s`zQ^c=d zIZAM;fF#P(`CXea=t<C<Aj8BH71~nh>rWQ}e57N`49Z|ZaLIJnf_Io8UDiXL=>xkD z>~=`k27|Ep5%!D!X>5J<8&VG@Q`nUiYFhF}vU8>Pby|kJsl~kZWKG%y>`fETMBTd7 zVn1pck(~W(u{{8yAAF>zpbUVl>$nydJ7AX#KJ3BO#DL0+9ddVm9$@#f(2aP6TsW)h z*0_!;Uf(6453qzBQ(?h+s;n4Ly&wcAq6<4K<{|(@c3;Pvm6|oh*ar-_v=G?K{4BIO z(W10w<@_V&=|(%}*OB(e#JH1)(A|Gn2n&a?;+IEN)8iDIy2K-usZ_DHPnbLCtud1* z%xe;t94yZ<mOY4uvtKPwL%1r7!6hv=HP6v|b*cG;Mnq-m(3!pDF?Uw2-2^5#f&q}8 zz>l9@opb1g+uLP|&co38g86?gMj?r4KDs|UP2*C#PU9ZMFT^2HcSsAAQd%DDHb)~W z?7~Z={84t3>_H}IW-LFEjJlWPC)9_55($_1#8DGf%lLlAv2Y8Hauz;`5W<_utwbTw zIK|~h#&GyF9Eh0Od_|=(7Zfq<{Ak`pEW_AF5^4e{)@ij<V)TG&_I?g#ku1#~P#55w zfWxcRvrO<Tr=QVzEgS0r+T(T7&58riLRFSyGj)fFqJ)sx1P>!3Ho^T-n_#a+aNBWK zT(k>~futi0i>T2;Yvk@?!1x>oLtbZWw*p>Yljg=5FFw_#a%u6=O}*M_DkcoVZ=^#F z_GOBJu%By;k-j^Nm7%$wWlDX43Vh+bj^fmkUtj@(CIpknzibErzWNBBa(0&ivq^#Z z!0#BEDnDu?yW9|Nw_XP2yP!pE7XI@xBE)1$Mt2x7%+}lynqLqX>!mW@Y43G0rFZ6c z*qs>XM_Ytm)pID3)*E|?npSXSb@Ou2cxE{r3pa}jaAo~hU>!3r3z(XkCwKF3f3I>B zoO(mQ`#OP`6ChGy!numi^r}AF%4ooKF}mk=1e~7a%EXttJP0!xt5?T>DV&sShmwa+ zFv)}k5DNKU2R_}i)gAcXP}sTfEuSYm6dxo!JZmRtgazV(u^+(bo%BezO)u^QuI?Sh zvPPjCC9ElE{oE*`dyn0YGq+}@uHw^F&E>}W4z_JhgLmk1`nG#(>du$gPqG;3jt6@C zC^>Y;Ld8+YgMJDjc_?uvcP4C<R3kCMA_7P#a5txVSjPzqNKezg4P}ugv4m2>pfY0X z@FpzVR2N~$<B}p3(X`{WQ=Mn{o`KpLf^Q!Hb8_BE4ULWxpuRA2t&UHvb$}JH@{^$+ zrtI0Tq7Q0Tz3<H#DW^W_H48-u8-g-78}9OYJ+yxaMtLkE6!#iq1aHr@JJhE7I9jrI zw_~aD)3W&7qh9#g;O%!f7M!{(<0wBFfipve8eu&);|x<lNj*kglsJZ(1d@-k9CsEX zJ8*pM)|)r1*Z8r9cQ6ff?>3qm*a0*#cOBlID<r^fvQyHH(AxnUhgcI|7rt%1LxAAu zF$CCKK*In9JI1*i+h8DAXo`8R*YL)Ta=nH(OktviH*AlH+dQP_-aY>Rn!ok}ufyAw zwGDP1DxYBRk7aJ7BM`nP$s#-1+nj%bJiVwk@CEE0(2aUX7<0<1l)b>%_Eaw$=qjVZ zOs1iw<t5zgj%poyJq~}v%rCTLj;CT>$9Do~z;3sL)1ggEjFx~2ObViS#33O;=ll+W zP(ZR^FPsYObI97iNiZqdNL0iIox^b;3bS`Xh)@!SNxCM4c9_px)jjHv;7%}j?70m+ z#ll|3V1q#6huJxj4Ay#MIu=DS-7#_*-7yO{dgu>H%)~cm4h5<bB!NizV=*1n8?f{< z%~~|ahT%tsQrIt@;C5gj8MRUB$JiYuxA&86Y;%)P*>qQk!R)<^5k2+P7|~gRc6r>v zjt`-B95Dzp2rjHD)p7O(?|5>SE!O&AA0+dd&TDo~PAKPDcwio^qm5H@#5SS?U2qNp zEclODv~z;JL@@aBwB*{IRkbN`x${+nP)GcTI-Yl0<-{yk;}L9e$LzC3AoMIwj8GLa z!CqeWGU~ttFFSiv-ryDSjng?<w|%S%f?>iMQK0mTBH9_S_s}NUyBIGeMKqTBRhxr@ zE_565eU|0rm?IbbJ+~)=JyxpGKg}^$W@;W6qxQU}lKZ*y_32(p?J0XpJI5!{RL&~| z6Mh~MWyh19h7=0wtQeSw7wGVTJA8;l%++`%`%Ur7lT7jp+=r;13#UUG&q?AsUm;SK zO3nZ-I>Yb5Mf=xYT+GY)#y(v87qFLh3m<p-5SWMi16ZL<J3reRSv<H&QhNdpyg$od zt`NNpbxPEtzoN-0#!ZmlAN<7b&DAwvAH3zaeNN-`mUYWng`c1}EIaZ=3w-wpx#__t zJ|`XJLRhqjJLgvbU*!dpic9^7Ye1!aO@5U#z}T`vlJQYL#V$bji7q8b<2rwj_5EW8 zzsuma82lUq+K!!n%HUry_-73MK7(In@QV!oE`xv0;5QijCWGH*@GlwsYX*YQ9bxhW z)BX*D&?=o#0Kyqv_4_@d#5s<9zd{V1LL|{=Vm*r!Q*MG)*Y>;aC+a!#;zLNl@9nlU z1$Uleuf6y3co$x(uz3xUU={-BZ`eU`1S=LqumH1(Gcgx&CIC*`;YN@YSGTctopi49 z>u`9M2i|5Lnh$Y&YdeE|)mirrw}xyMws?wCt~IbYh?BQ)`T)-4No)?aSr^M?H}|&t zWWP_c!X<l+lCNSPX&qjkU7t=3eOJ|)m2^n$_^%2Qb(XaQ9IGhgsy0u%)h0f9!XxF$ zAc1x8^p`U5Nv-31WObzJx3AV~_|E1jpeW9Rhl3>+jpgV8_`F#1SuT9S6;AuAJlnxU zU0ObB*6|C}F1JPNW~GK=>=nP%X{qf5Qj0FEj;@ujnc+B2T8H_k<{#EEHy$4FtgWsz zTkGS)ejmOJ;k3B^?WgDNqF??18&_sBg@W@IMp@j>{j}S}=l6u=`dMj3wdwpC9^+G8 z@;P+ny+QAOKfQ`Wz<N(2!pTMoQf1|AU#-h2>^K5+f-k8eDDB}83Hjk`fZz_!zhi1% zr@Ey+AY?$FKf`AQ1@$25&r4G98fj!N<@{UZ_%Ea!;q83|gC7+g1=Y}~13K8Ig+*C{ z-cFK5E#&QUxLo>;wh|9vcWfu2iNU4_`%ccejFaIYlfmQh4N+_n9fr>bXyKuO)sD1m zj~K(*b*I*zlik!~^a$ZoPzt?W;h})snMm#loGGjJy8WIW=^Fr&rMhcXm#h2=t9#1A zo(X&b@4n!zBcD1Fv_NnZS!4?mPml`>SR4=d23O(tt84BZtCJ_L;P2|ytCN#c@_S+& zA4z(}x?)|$^kiz+f+#e1WeT5%0WlTj^KRW`!`AUU$D~_r`N@iHJA^MkZy!*cTP_D~ z8-7ls=V9i-H^Qp*QjTF61^sN$G2d9~9sS=&ego>6OTL@v<I%4C$ZU=~6%g`&yH%za z6#Oz5wbgM0YSQ%hGqL+Mt{{Wjj3Inp<benjksu;1L{Nw<5h3%dEb$u*ew_i=2bA0p zNh3l=M36|8jw}%oBm#=_4<%YCMnpz9M0bb1jzD4$Z>g1t|NmLQ*}aUr+`d#g--pc@ zd$2WQ2wOBP#P$_VV{^t4q~r^SuvH_E=LZoEAkMUX`O~@mQV&$<r%?-jNLhf&G~Xcd z?JQ#W><La=p~tNA?|D0<zuQ?9_U5WDXFiMJUu_CUDuS}BPQBO^XCfeTF_@#sS2s&f zZqMn~)`}~Q`#36)xKql&9~cJ+sxNM4Tscxz9XFf>6QLuvVsF34_VmBL(!?2s*T`y} zF{FswcWFdEQ~DC-!%b3^TUL!N9qcq;zO+mSTWlL}<ZJBmX>-S7C1)61U~qx~4Zw1~ zuIzSE-*c7W=mZ=XKlifw(C90KrK~xpV6+MU3#R;oVdb)enM}$|<?(%FeqKG3%srn! WlRKUp$R8d2(%_d98C+jZ-1*;@_e(1P literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/namespaces.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9c2886bb26e87e96dd6b9f3a11d076e2926c6f9 GIT binary patch literal 3576 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 M?b|KKcQy|H13*)rS^xk5 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/package_index.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1553312297ed6cf16f7ccad4b428ccc7b241ddb5 GIT binary patch literal 32430 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/pep425tags.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8482a0ab0a4cce0e77c4127dac2a8d965c09a330 GIT binary patch literal 7167 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 O?VNO`oevCFsQeF;r1Yr( literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/py27compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e24404ca32f8e23c09d5e2ac82f041aebd43a0c9 GIT binary patch literal 775 zcma)4O^?$s5Veyw$%d{LI3aQI2`LhrN)^&xphE0{9$-~zdm%!Kys@|SuJeKILbK|T z|H1B&zmzK{{sJdv(jr!z7-?o~XZ+^9ao!vr#sn<;_Uz*mkB}d@`D3srufgpCf*=_Y zRCt<Z6tb_q($9QK#6S$cl58OTtD#9nu;0<!;Ess!+N-DdB@1O}W-_V*5s3q+KM>wI zN#dJHd|H<ccj`iE<yv;WZkpOSc3B%XZ{4b{*d#q+yb?@uqm?xAPhdmN659DzZ3-lb zhS>){1-GbaOK!=Q-ce{nZ)PzAd#gUn3b5F0v6#P?*7Bu%&Wv<x1IJpkmE=Mi%S!Hw zm8zDEvt@thTDEBq0d2#jbU9QfUKf@-kj{sK@5BVq_t&ejE1PknnqyU22ZhJQmt}S3 zKD`)QXw|s7*7p9gX(uN|KZUeuyQ4jPz9)lPY_D=)B3S>QVw_J5NPCdPGXuD5h8U3L zE`+#3(8u7rCbS#AQ`LG?P&h)vjNT6xLAC@(de$RA7rOZeu!~-5US0@3eG1hUoR|@W zB<{jI7j=>6UDRmq;El`d(chV*a^s|_42tbpb^iRrqzi0ooh-8>jl6Q0R?cmq6uiGP t*#lELBV}&+rMyR^*NF0fO<9YzmQ(yYED9ZXkvH<AFrd+JL<9dJ{SD@{xLp7M literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/py31compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..335f0be085fd79f585f921b05dcd1d223c1d6d39 GIT binary patch literal 1161 zcmZ`&%}*3D6mL7-*<leSgo6nl=0w~?AR<RK#E%#~EG7`qiAhtZWgX~z&~}9(+~ofd zZu&3H)sz2%C*PahMO1u~dGED-eZTkBCv$T>0+f7Ne!meA@*Njbia^<f-@OJlBni<p zVfDNsikcwj38!S26ziPm&Oy(<q69xUWhP9*Rt8D%f~Y|8Gotusmhg9^U~j=<oAf(B zz$@v~W?@I?RcWQIpJi63zO?lq#j`0fP&VOrcY$e=P(>1^Xc8!<f-{nE#Z?DnM}?{j zGE@=xpRsuF<ZCaU&>L;**kyTTbnK^)v6^DWX<2xE?BiS(a;WX<<;C61nApQ*U&cxs z?R6~oytYTus(bN=k&lniLK;`b*{~?Bj<>dBStvxyjI@`Yw6&#maaoN0WM%OiC8ZE9 z5=spHDg15`m?Eb{5Kqt9MXM<S>Cr(yXm}xW-9(tpUS@RD%?}hVpsL(yv-geIE;#u4 zXwB!<T9s8RS>e1iW+gou7W@8iW6fzls(e`*cU7(G2lvx5ucTkC>LwB*D>5$xM&mdz zLPL78^l#%<r<Q+YgBi8igrJ;~{Ym`P2C(i^i`#9WV}^6r%m|^OA6AIluyj}uLQn2o z3pp`N+sMEUB|2#_*FmWlJUOR;3}bV_+Ob{a#0N08%j2<~3?|l>we@9#ojz|u_i^Mi z(}XtnR_iw4rn|NM92?o^ZRAZ?AE&;qbP|E`Nt)4E^H!$%@3f$l`WQ>O1Yx=M?NLS- z=*|BZbZkH9cd-xHa3PwW5P7La2K5_49FC-!oOFdyWh#W70RW2t_7*angDVWn(>{<n zP#mtJ4rdXMf_4|cz!3}z_~&hIbAYJ5OpSC7ykm)5%Vzc^zFyx}#LnXOHBe3Ta2)Sr ToCS9i7-u|SY#uU?XvBU2=PDL? literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/py33compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ceb34e5b46209cbcc7858f5be95be48a2fbd74b3 GIT binary patch literal 1384 zcmZux-EZ7P5Z@1fo#RWJHli&cWECmlBzk#hC0<I^l%8578W5yk7Lw(7H&<VLwzIo| zT;zM<`p7fljpPLh!C$nmJmp{D1!jDTsGw`j?Cf}EcIG!@Kj`;E0xS7t<J;dILjJ_V z#R@>U52SwrCWxRVNtQcJXm@4_n?;?(6aJi3*Bv6AgHYY21Rp^Y{*qMe1$wd4oqCA} zS|WJqPlF_&MD~(UveOme2=|O7(IX-};lC!rU$CSvS0xdF>@Rq731lvMGB~|_MkZ^Z zSrhadG6>HhH?lLJmh0jewv|_ATBc2=v{cspve{PSldx{`TF5w4;~dQ|76aivkbWPS zBv@3!1QqNxNx0y`fgKWqYdm}D!OTdElIHca$xM#UxNt}M3`irGEp15(Re~GE#2oY* zFzaYp?kf*0ej^I8{p-^$Gi|n-qPbO6+GJ&UEB}66P0Zn)EiKJaW9qupZ;H+A_U+~M z!)9iKG%c#ar0G?>y32>2T>np=!waLFf)y^j8d^;d3jGH#Lr$SpEt${>J7aTd_)=cb zITLKoft=$XTHdk)qJD+)_zg05Th}-f_rO&@qDJs*<OY@wsG%g>b#jfgAkRI}d7qFu z?>xK%rhYd5BoIDC@msI;MX;djWbPbpRFUX)_8jd^uXS5*!Jfe=9d0})qK6GXx%aY= zrHD5_s+*6Yql3-3$qE(k*D97-{wl5;sWMa4Ra{hY*Y|pFB6AaO;$hR$J%v!5cMMTG zhxp{2qx3hdg1~ua5L!1=Dw}m3vwmJf<At=ml$GV8(6;}0``IYn{`%3=C!?KR8;xG< zj&>f79->NNT-z@yBgayuX4Xip5cENye0=5Z!8mElWxa2CW0Z~Lv5}RKB88ePs~gKf zNP1;mjXVEtWR|Rl5wQCPVyExGNyoqlzf2?MP=|#q0E#Ja8q$b5+yVKmv(bgv8Mqj) z%BC_+ZJ4IhS{#)qM`?O^l$Faj3ddW0fDDJ|4Tc#h7uXdbjfDm@;GM<>7ZYiNqe|*L zYvkaHT1SsHV0I<1%M$tn9n;pq&)2SeK5c4cMoQHxS^M`}7$Qij>d;Nz`=5RYzkuPi z{tmFlZdwO%Px?@fG+AC|T4Qxsi-51IlwC)bN%~_jF-EDI=omiUee%Uu-9JQqh>5<X hTpQe7qI3@jNxusWY6h4Y0KQ5?7GX13#8+=d{2vM%TweeH literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/py36compat.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/py36compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d14207dac0cda0c030038369baa2957a9b6a7698 GIT binary patch literal 2156 zcmZuy&2QX96rZuZ{)%^#rfCWY39AyQE0Gl13My1kX;UhJ2o)bqSru7c&+KLrukFmt zrn@UI2hsx<P>&ptNRCJxIiUU{NOR@Xf1xMd%yyeZt*sfqdGqGIpWoNqY&Js#Pv?(! z9(=KY(0_U{e{3Lbz!3LfB8cD|b@bQD@xba>SkrcH51fu;XeVzB+>VRU9Yh+$eT0a6 zV0Ao-c6{RPBK|e-{bN4C-=KEz6m+A_HdZSeOvs^Rx%jG*tSoMGUUJ|ELULJl%QA;W zW8?PC@9t#!%=~$Q@(tin)WHOGEP^{WV6chv2zMM}fhAYHr7dvQ1tVpVR4ErU$;zU~ z`bm%FR80O2V|cz~qcv8<6)*Q0VMRagmHc7K$y!zps#LNr%b6T&ZrmFdnO2q>jx6IY zH7Zz<<wHVA+#Sb+_R?W4<FbhFj^#FduB?B!9vZogGA>FPQ^I5{w`rV}gvMZ7ZZi>Q zc`8IqM;WbPw~U7sNhLjP(`ZRW%m!6X2ego26V8*lE7y&{W@bJ2RtvsO7`I@Ee=vj< zLpad@Pa&Mr+Oc6cyEeb3U8jRcJP27pLb5<2(j+ai*l$kl!s(-_EgQ9cfTwm1F5mU} zw>3I+kI)oLk9UFg$<h(VsJ0+Y&isO>&gi!qZ=fF@Pa7cdvyoV?8>`4jIfp^r(A20` zJBQ&B0?E$Q1$v=&kMPt3`N&ZI=tk|q?zL%92jncEeNqRtz3ai(Ic(N$9UNKHunrDe zWQCjq8Z_5o&#L`8xQ_OoY@xm1w-CrK9wChO_!c6oHQHI)bsuB?_vld5Wc77)c*dak z^#N#ru>d;J&N5gC08cdjtd2nbo;+KlI+81Ocz`2xU}IEV1YGBhHg0x<*{<1(W*m?P z$t_g8>mYe<Hv~<8VKi-GG>PPD-8{fQVZa6NwE1K6KKdRN)_wFC?_JPbNaxo!IfM^E zO+>d$4&T-J%qI~mgiP~%t(yuuS(>k^Je7vCFz4i~J6W7B^!91SkkeC)ZJH9w#qkl5 zaaKujY!I?DRc^&;kBue^bVReY*+Mzn<$x+@2>6u4%Ti7*oGiulmrL<t`y=?XCWD0L zRSDpr$R<%7b3ma>@@=8~Bq`DXO_FDLP2ohj{k-g^dD~LnKIPp~P~{OmPWZ5BpI6bW z(2XU|UGSW;#aM7pQw!QN$#bwlkCzi#2rAW?9xKSH7Qr1Y@25pkLg~XlX+X*s)U*Mi zywdb8p%(j8CbLCCSSFPX4CQeOo`!P(o)t_ciCToNGDyM9{A7bkIuI%<XdixipXv?e z0i0Ay&ULp_;k`5;Qqv&0uIzS8IfCXr73e;uy&`76*kb*n<VFQJP(XA{k|=*JrxhFM zTz609gRSRqwN-mR&B0APQw`{FsZjPn^#4TsJ&=9&@g+H^E>*08W;x5a>|wvyk$YD! z0oY+Bp<|1aWHr9>!K{U@S7WvOa?lq+t@s=!gd;n$T<l^WN0wvxmXCeQ!J!r65IeX9 zvmScAgd=!YoTw4uH-WO?)C%k^TT6HuPcENKv{&@}SL9wBZ?+pe0vIYxl0iv^Ib@lN zl4Ng~=ChnrUXqY9OA>w=<cvd3Oz&%6116naLZ^)HIoNR8_^A$I2IIw}>-Yu?p=}=D zU{K_iIkVZe4IF+2_W4yk=?I*dUKrHg6FMb)+z$9zAk@<FWkB_nDoo0#)-hXOy0gSu wJZ2Kw9rjJS8w@Ifq7wSvWCh%OuduKD>oZ?{qW?$en+Bq%U%T~bXtkXG0W9Wd1^@s6 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/sandbox.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0a0defcf2391114c51584b8dd7ad075dd786bc67 GIT binary patch literal 15500 zcmcIrS#TW3d7f(zEDnMsNP;3I4JC@?(j;_{zGRvv&BK-=K@3TW@>=qGu`>V`*o!^0 z1hHD!DS@`=s#ub9l~YM<Ah(msU5=Bolh{>`Q{_07%7gPTc}!KR?3cXzCHcO;XJ-$9 z3N2T5YkGQmdV2o;`@j32kB*P$4EzdTJ@U$T-)|WI$&2nUi^@41LC!J^&+yEuQP5|z zV9K>su;gqPY&kmxN6x82O3vv*TF#k5M$XwnR?Z`Z5uB}Rt~Od2H94kT9jlEO#%mLW z3Ar|_I|`G&xwLa*m*;GnYD1peU7NBD)2Qu{a<7#83e%=hA4A_gzOl4_zfqW8&H4`% z4%{&6(~jXET+XQ<n0N}~nuP<OFzVLJhW}vUA&i)+K3sDPuDmf_ova-y96~+gWxWwE zx8M{W@lJZ9-q;<p@Ti|zI_%AO<KDy_bKNXFCf7T>$vXzFj>y$cZ<kyhm8;#}lw2MA znBnd5_TDkPy?%b(E*!`8K5rV=)9Y5@J<@l-_ki?0;T`Y}-Z2U%rS(DYA!(hFtA{;T zt{(Red5@sa6W*iVVVs}z9`kZIKZS9Rco~eF!MLaV)4t&yUANvg)%Spx_b!-)_tl*R zqwqfTJLYB4FYBKIJn#3NjSu+t(g(e~cO0$n*?4->xQJP8T7?gx?+I@Nts}mRzGpo1 znvs9}N2HM1ycyX+<#yhRvU9CUHLTQw$gY)|k+W2~Rl?ngi<Ka3g_UY>NvVcH%jil& zEm!Ib#lR1v9p~qQP?gHzwNl-iYut_|FIJRa4jXDUX^AT@RT|Y&SZUOw5!I^m=~lCB z6AJt?I7V<>z!5x)!ZX+G(C8Q)d)<0#V$JC|8|J35mbw9w`+4K4@v_meJZm|tW;*7Y z6<VEC2L!loucbq~lkS)uYuyGJSeUBQp2@lRU0Dqm8+G@TTd6gxe$B6k0*>35cm3Ob zdA?Hhb;rn3bF-1d#=H|bjiz6Z9Oak1C{u3Kn&_v-0b)KAW%*FORP&?ELbWkhss>TI z+9>nv)Eb^2rGXv4RKvNfD$Ou*%4q$Xp{DWtPo91}tTi8RR+=Y)_OMi~o-D5{)R)4W zrym#WgpEcu7^rF_&ooz~kzyC-M~Sit6o%uNW9BY1Yx1lfKug(VJAPn(gF>Q=Be;kn zG?vKz#^<d4#+nJ-8OtN;aHp^RjM2_@%$LA&z`4;edrzDJ_B{ibHD^IMcCd=smej&6 zTmVhYYLp5}w|q|~sf+!1V>H6nB0D}oD8^72)&#(vFfB7@sfTe*_~b{x6M$!M(R)1r zCTK<iTHn0^(9{7u7dg#RxR^K9L%7%;BzE`^?gkW=1WCX-g!%yfcvtXu8Wn=GWC3rc zXMNE!jnH0lh{w<_I_;ci$H3XZ8(M%bTPX24p~UAK^<{tcB;H$IbVI+^6xw6Ot0;G+ z5-z&LW2r1udcyVVK}&(<+)4;i1w#fh%yn>MR<4VU<=K2H8gDKy6qO$|TB_^^QLedq z>Pb>;DU7nU(z1`ygDBg5VU&sAh;<w7d*8O08gJb4m8y7tkq?oA^a7?Ptu+3EvHUQ` z$kBo^y@0~OprZ}oZPPRd=u28nw)SYtj;sb4YQYc7D_)c;F9LqRnhrrjez+}|sb(u! z^j;)*q7$vGnbXTj5EAM_-LP?-!x0=r;TzP3(1d2e_8rgiY?0F`&%v^#qCGFxo0al% z)i2Fe{Y$sYev^W%eMOexd>xAtH*wvt0FW(Qu2Q`bF8az%o^Zp(Qs|Z&t*YnZo;&Be zdR$LSo-+BAKLR%(4_BvvA<)+*@n?2`sd>mY#|SN`#*1Cm2z6}NoHfv6$J$7Btd12z z7OvyJiQWknenH@-Ogvv*DXj*8I&7)BTXMZtt?7I2u^6hn8?H8e%){dpXWVBfD$8!U zR6p7e{E1||6;*1IN-K4DTa>x;Ai+>imhV^Ob1>)QIL$(!ruB=X6afjMkpy$muAWGo z3A7xPry_@4MewM+9XSLzvH@jem#e`L!z;3`heK0G+A^oi32V%3Kd>#dGaPz0pN_J{ zBBgw>80CsZ2=-Q$^|4~{W~)?<?_`QauTf?*WO-OA*L<iOPu|!E1qHvNI27QE1jRv- zwH-@Z21u0DaE@J$q39=3O`tH;94`g4A?2mL49;mU3vwNaCK9w=gUD6wPiZ=JFEr|* ze>-%aFV#y6pi7~~l}fehQZ!?kdxU(#4SZE8RV!`ZJ0S!BvW8msvAQxEbh)o$s_kkS zo_Sm#%$!z7YYCY@gq0Kc)%iYTXthu*f?a%7EZ*j0!U1M`dT<IeNvAT$<&S3`@-i2d zjupT%y#~=t2I*Lv5Hm%qW23ai=CNk4=N-YatV)zFik^z>VmOBzAHf*veJo%^8<7>x z4TB0YfVd5d#n;e5lMr;RV^5fAyS;BK#L_p>AvPXL;ShlN9uK_SfswYHQIoV(LNm0M z0Pd2rZoOiy(XL5th%JM*%x2e~vD=Sy*Mf|x{FACw3AlW#z4cS)@q*cWHgay2RG^3` zMYS8Hs*REt$ZbVjM;YbI^Xj9x%G*O|7)C)FuWr@+&!ewam-d+HSi8*jo}uaMe&A{K zLG)Emv!IeyXIPwLagoKxSqNA33gM5lyn#brlXV;`YiCClTgy1)NBAivAH@;8go0Xm z!`d{y06n~JyfwCF-0hkPrnVZThjUl-&l|=(v^PY3maR0G*UT_Qc?tPxY@|2E-4MOK zAvE9RA4s>A#R_ycEXjrnAuzQ}2;34FM2Ko8Cr?~grFuYC33^KtKstin>!qq2Ho${E z6oTeUwCe`{W~*|m1k;lGK2|L<UZWKTP{RFBX&#(S$c#wga-Skn4x{K8uO5VHV%{}C zXjaGEfCSt$1Jr1w+=R}<6s>m7ufsTn+6rdq7UUqsR2a}0fzGvNo`4C_@I(v_7*kxU zpNyPY@az8VraJpozBP@)F)TA{wI3!nVv!lloYBVd*_ot2=tHcuOpHNV$jwz*<|y52 zdO%$?Q7l9As_rO4GJr|!Ne>)ZE{uA9HMvbX>VhZ|W~?8Ew+Wz_%h?=k&q-^{o=Rmc zbrtOcI3&9YtI}}1J*`>wqVeh&h=it}`C;Q`j;1lN2SXUDrwYqVW}}|RBY<!$Ru$9` zf%-W#_EEYJ`4zN%4Tnfe1D3F2OG4ljril^7wWMr=8#G}5qAfP4`b;N9o}h+;r9^!c z>nkYH_^OMcL9UCY1y=)hWKo{@Q;ZiI$XRVs-9XC##)wsd9{d^#&5AUTHzCS|9dE-- zcEFbNIH%S@dtn+^vp8pPK7(_X%=gwY)J7;6-<m=#=UHS(ugl1WW@KXir>n_I*>LP= z!GgZ&fQpNiA63Tzv2szs@oiM<igOc^h;}T}=<Rh@hj@#=ipsN~T}i7zi-KZN2$Mq> zVXbOoo3){ZkH%%hV$Av9z#zdC3VI(|{L@nA;1*>~MJr(d(PVESO)efu0!XIpB6CB3 zYyyd7>C(qRKO#2Ho;~Xp>%Q*=MN9`ge(Y#(Mo06psA~E5>O4RX_tC#Mc(GY+EmZ39 zGne5R-}5EChoJ2%b?Vvsc$L?UPuxe}MsPoHT#z`y@Nn%XkM#iT3?QVFz|hgp=8wHH z(>a_+@W6s{ox~zV&K#WiC{?4&m$yU~L>V|{R0LaSV_>PihsU*e*qJkxhpPecV56ar z7PJkqZmogU$U<NoO$(28Y2m70gD(fOVcu5|`Or*II=!hKO?273YSdgf_cLAPhJFZA zG*+m6gi<Q?TL^a072+7014K2|8bRomnoZSc!iWr^6BA~eaj!2{@J_$HSg+h{!JgF4 zY~2SaK}oH0sM4)Q#lxMT1@M9vG;JwxA3gQtd!cs$b>DDqtGS>`Bxx9?G%p3P74fj< zOBGSE^A(s$C3n76FAJ=mU#>z?;{|{l>KB%J35uo^Yf|`oX*lFq8Nqf>qKj;X+@y3L zS~K-YwEYJTy;2#(U)YlPbJU2VIAo=MjEWYIQVPd{e=V#SMBQ88HI3D~9b+N3MfO2V zE@cpBFh6IVVcp!wdhqNv8Fd)h$k9p(N0vr6#ys0|?uca*jw2E=v2Lkq2Vqs%GCRWb z#^fgMA*!}h-f|F6?dsSbe1|VuYfiWuu{PM9677j?B?Mnj!^50{hZ&iOy}@JO+et0$ zQQv3jA#$X?|2m^XfNd@HnbgaM4$QJei)Nv{O#1^@TjE@HSyiu}t7BsDG_*UX7X+*5 zLSE_^;;i_GiR_~~q<M1<hv*{A%-D<-Fk&HyL&9tdeYzUt$)QDxvS+HL+MHK9``;V@ zhtWQe#3K8Qleib%zFMhL7om<iqcp{$*t7Y)eJUeUnhO|1iZTG4x?Uu<B9xkV7-5Lg z2=e(VR19@;WG&&M5kw2CbEWb!A|2ouzwSl3N+1D2FejpGp^DOCn)%TlD02b<ri2db z+G~my0w-J!CFmFBuF3sNa6cq47v$50G2y_XM!8xcXs@Dx<<zQs0GPu@7NWoAts$%_ z((QlY2xtfy)|5n4rr|fkdP+^06Lt>a#%XgB|1x`Yf7DXva0D}0w?Xd}o~zI*JXg@4 zc&-T8<D6m89_Ort><w%&Fj#LCa<>nAJ79brER6bN{<uF1+P>`Pa5nvkb;BP$W8Az9 zx;yMKfNvId_><~0{tj=qKZ!v4Bx+OsPSkc{oIOM1yy@>480Srlv)9{)x9&pk>7m}= z@^=mN{uX*m=)bTVy$=la{;|J%p!bi_`=IwA#-8#X@*c){kLP-aaNg@Z;ysG<K5r7b z`!U66WBcL_##4?$Z^cqsJn^H9NFU1|b>on|JKs?5t%?c}jHt9J3T3fl{t7M+@Q;mg zc}UnxJRtZ$^ngNG4fKKT!fB38rQ|^}9bMPme2{kNLgH1#-h>n4L0E5=aysUhtecFR znUM)|NIir8QD(6eK-(dHr=I1tLq35l6{lNlP;n%3XJ|w-W_dOXsu5|Lh9}WJF|^T; zm<auB+kF(qxJ~QJE;4>t<a>kucXjJxg4Y2~n(yKy4XZtUuQw&aoaiGLU%(L@L2=uK zgO2@{SNB4Q(+sn)3BfH0*@U>6#iGYT%2B_7{!s=CM5siFVDCU*#m+Z23nYN6I_NsY zj8O_EV{>(^iyH&1*WR-QV)jWE4}E3D1zbjwC^dBiHZ;{<fDVw05_iBk<sr&g#Fif| zNCZqW>JA}JiG)y`dgO?(NEJzjibj8wDT?SFT+n1y)j9N;B*+qzh5T^DylwB_0(dtR zRHpFYk7vGAfG6b%cpz3aNlX{*&>_%t*TW3M$1&iS^I3Hl-PPw<a0K;v7H_a1%rY(Y zS=8dt4@2qYqJ$4eScCuF@}m*%ZuykYLn|TCi+#OGr7@{A{@c-y4jLu&Lqem>mO1T3 zrDMDWY6tfK>3xdRYClB9d6b6BQCH-&+kic!)g}0RR$u~4k&Cb_=r;sqWJA9_lu(NW z_;wE?9X%3SA!tMv50Ma*3wMom>kH-^#v6z^bHC$Gmf-}@hdo<nNB$@sxK<D22%bVg zj!-U%i*li3&D$OOD^|yO)6}7@yAq?DM|@7VQeI#?Nfs>{#V!VRA&botBK|2oJv&f{ z>3YzI)LxObyn^0jkto|x75EsXs-C>~{0<}0M>uhsUIrHC0keH-c<RO4a?yj-#EZhk zA|GiYsF_45*npS3jsY~K=ohMAW&_DPhCuxi8|1xvwjJ`(9w0euBGrEEz5sz3L%5BC zlCg#QGQ`Gejg{Gil)7sr>*WH9yJmCj9%}}%q}NOY9r|{8OV*4Yu&mhw-8IA7SXdkT zO}Lg^t$D1Xz8+Ysv3RX2^=2#VhEWNMwlcni+5nn*Vu5Hp-NQ^8!T9!jx5Es~p#_*; z_qj;67M!vs@32z)xKi7U{A3TJ39i-A`-Di#7mAkrZbZ5v-=hqb8J+(VM2AR9>|(*4 z;$~K3r4D~^nR*JVOrHz^uez*rO4Zn$!oEA!K3&zF)8$3gXoQI1a`3_kN+srCl&&q$ zSLPcWu8zU8L=++m^ROt(^s3%Hd-szH8A(Xxqo@d}JhdIEKonbdL5KYW!`-LB7EMC7 zmeF6vfYEqNM+kAg8$x=9%SNM#ygmhcw0-&=7LH*}ypOwHKNGv}?IWVTF)#OM2>hOI zAGtqJ5If2;&p<Of!&G4YcfWW5LVo1)L^iv)(6SeNO{H(BgIF?3X`9Q`;YM{LiPayW zdzY!jYal<9U_<D~ci`)nd&`l-g1}1ImX8nsP^&-F3XE_CWSAF+kiONr==KEM?~!RB z|AH9qQaR5=+65e9dWx1a+aJCF9}Vs)A`_yQT-w{PwHck3Z5J}!3C1R5yH_M3`)E?` zY6>c8<+2bFn8-oIx4VOhi1RoP0SN}c7Qz|mI-q{3175%(R+iX!)+V*I+1?w&Pd|a6 zBJcqgqe=W1=-*YaBe3U`L~}Hh$#M_DtH`d4eLx=E0;Ja7@|Fa|uBsB`(hwW~ao;eA z8g~hd@xIhw;<@c`D0EuwgXzJ0z@&#w%uC8NvWDR82?1&e=89+T!*(JRpaX@MdJ`70 zv|4Djd#&7o&)e;f41-RqC2*^iWk%VkzE9wyzO1)VV-@Zu$PU`6lMJ=B?UP{xOG51C z)7mkT>Ar;q^)`!puE?9X+vMyy7sK9bwh!E6{$f#qy{EU`mJ^G)&R5-GagN1B7GGrX zD=fq*d5yKtve?by*I9_6E#~zf^YYJFki29<vObDn_7PLU0pje!b~l1E=z;tt3%h;k ztdq^)pUUPC2RC<FxtxPD{wZE%M|Ep*cF^BJ2*$rvZ&j;h43zwKpmq*NK-~66B9Jzh z;tnA9(Yc4NlLi@kVBBG0eAC39`VOSsW&AAm3Majth%JnGyS&}-)DeA9FMCHNG0;RH z<(Q-dnuW1A9xxs!0#1061X$SNJ<RmK!epHMw-d>FhrP!z;x6w9DCxKaa@uFEVxwIl znA1lh5)*Z`v4VK$9IOK!AahT;&A@MYjg#6q(5}sIVw&o=SbT-WS6OVZ*ktkBEPjW@ z@3Q!P7JtCvPf)a{W{y`Yb5DhhQ!~e3nbGMOhX<ILroJ%oWmE>@nAnBbr1$7ZE1a?= zhuc5mPfAKn$6|y5*O@T8fi0fIVRL4q!7UE@*Vk|aE((b@Ok;xs-o%C#2TkQ=I?|ve ztkV~g%hnsJRxSm;DAX#29)$k07;9VUv4$IOcclk>q>~rB2#%8%-#Ofn>%Ccho$vT- z6o~P4^Hd7F%oLFsG+((5=O)?H4TSO)IWBho3z_(#DA(6ZIHkuf?Ei}dmtxc~_ktbL z*eYu8zbDv<itGAmBJd94X*zUOqh_u-@IVo}LDCS?C|^f56os1(z(OkVO~BwOoOE4# zWlAJePcE@rABT%elq=rqrhfh^ffgA>i{QXkaFd>qsS=_afSHK|Nd08e#4*tzpo0K4 zq%&gstKZK=fLpip`<OQJ<kYt?2DWBG#T-ObUX08a#e8Sr2)T6Xo16v(TC5v2(Qt$A z-ZGfoe}nU*PBD;&2`RjH>kJt?`Tw1n`a8nOsj0tb@eeE}P=Lg~&AQBvlKQ8Z9lLM* z-?L*#C^1;ky%)P709-F_RVGmy_2-1b6o_yV3u%bf+2i;4VzG$K_P#AB9WvrbUi1S* zM9rc?<-KOLpYBGEmaGk%JNO%*b_y(7!AO>~H_hfbW(zH)mo3&dGN@;1LV+iYVmC3- zn!TJK(SFNujIK$e$Muq!TWcaIM16y|8U0j$gQ9CiyQtGK!&Zeaf?|kYWR3oiGoD0G zdNUS18jI>~%x+I@nLh}23wzsmQj}>g!b>zrj*BI2Hsd&GGo{TAffTYnHtQYiLpid8 z?A#-(giD01l1an`u%g6boJm5N0pr4yS;qo5Vl+)BOd=vI8PgQUde#&W>NynO=q|Cd zt@K5*v*5JnDkK>s3AvF#QaC810%ku0#9dSxOb0{8k2MISr9O>5Y7RwLHI!L5)pyz6 zlePr!n?3NrG=GbhXm?MH(`@HPE)o_iI7?CiU3}~vMK;p1x_rig3*+LqV`B+B!G2KK z5kK2)h;n7b_r$f(*^6C(1XbU`2wx{GWN(8sVdIbt#;tVGMcRP4A%;ZwpGE}&6I8LB zR!@KhAUq*TQDbro^O>1J$~@C<h>lsMT;O~96X|GVMF9hd3<rIprpG4Ki(O>&O!=Pr z7~=geqx*L_TM?<)c{*seAKW_6es4pR3m)SWtjkoNLPc~1rlY2$25t|Ill-;DLv%7W z^*Koz`7+U;)wBm;eH-uA^6g#N^#9a9dFYda_nJJ-`XBuddJlLu$y%Qy0$@0uGZZGR z^M_^nP^2*e!1LPIf!f5{52FR>fH&Ib=^zi_WYxdrR}qq)q1Zo`Z)f5vcF;#}Tz%&H zrQ+r1&VTG$4+q+35M2~w<MV(lO3hbG3xS#<s_sb)eCl6%_}Ik|&z>##AS4t(RPnvj zKl5t$wk}T#w;+|^fFUJ6P~XR;`bV~n7B9Vg;nJ1s&%7{uO)RvYRiJkfsG0QCzQY=c zReLyuv`?t_BngB5pWzf-RK(3e#@DV?+8G;Rf+HN86p|drvtw|6(gSjh<SYt}gNZo| z;mbHLd{txJ?rym0bn3x~^|N>)GE02`i6o)P`$NJ)v6(g$uiK|zDBigG!t8UOa9=21 zy?Em)PUo*&xiotbl?zudoxhIr^{X$=Uf}uC^H*NDdj9GsC^eHG70)>wvM;vP)!H<f zR*7w1z5Sc@QXs6fSd{Hc=LhyJUCLAu`t*JfG_A}dHw5V#y&Z4{Sdw(e*lsR4n2;oa zxcJ59d-Cnk)9!2Knz!~Ez90w=sWtbt<rP-fbhaj+xQ;h8vE73N=|OO?fw?V60*;Fm zm{siBF<%ByC-0XGYbJ#<+n)i#IOXJ0DOi0*fAk}}xX4dI;7>;g_@X)AN5;gQB$vji zq#8J+&UB%Jo`}C82ukyQbrn$^s1^xS&8@n9Z_vZmN~?q-0WD}XnY@aW9;z-zvf}4; zLJu=FnJt6F)mwn2GSB(B*ehb5jmAuGDEYX_#akDlyJqmI74kKakzA=G;#8AGi-A50 z9JY`buVf>etJw!<G9HsILL5HAC|G;R-@#H72&C~;ZZo#Vuh2@Wfn71=2_az!xjy_j zqxWe+!ar04B+CmVOS(MNd9T>aua*EPOu>1{7k(3_9?cg=gb?xs@tqh_fiQ(qD1naH zgu|BwHBa|RYx)^tF8F##nnXtXkH}!6lIZVD4^tz&O6fKWgYts_Y$!{b*@L%3ZbC(A z&-aiGjJ*KH2Ab;M*!zbpM7s0};q4r5AY&&^on|;Cm$Sq$o6Ub%`>F@{>=E|M>PS>W zMI(|S#gER^_jvo$yq$|v6cH4V1akH7Xf5pQOXvcOOk$%PDID0+K7-E-kwJC~39wuQ z$wV(q59H6`d$#U(N;+*di*KJo;$7^>!r_KmKp%d+*Ud$nX*M|S6_(G-_ZaweM0!Ye zR+N(ah0(qaTK9Aa1C@@rchSf!!gKOvqmG==&50(He7+gvfHjalPw}f0cd)WxF=PSJ zz>Fqh<ka*B6*?{S5Ig5t%&?&Gp+7n}%i2{IS6JL&QDot<_#_MF+US_TYpnehi+^Q7 z)xog4*J4soLlyCnU9(yV)em@=3%(sCAmd3V@0|rT7{RAdFuQc<5A$)-%A#~}AZr^+ ziCgqz=9n|)<i=6UO^i(JoXAb?o_J_te>R1y9oaqE(d>bVl`)u~jy?GjV{;SE{{mdW Bk&6HT literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/site-patch.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc49a1fbfc4d28b47e9cbb788a4b5b0357451d89 GIT binary patch literal 1466 zcmY*Z&2QsG6rVSC9LI6eHciVGamWEt<<J%_NV|tp0lSFhQYvkw?uJ&z>v2;zj_u4$ z>4(M_vT!aEchVdD189%@5uE0P#Az@50X-nzIO=MdXx_|w^FDs>BmTVA@(8ZMFCQHK z>k{&}VeS^i%cr=-dq@~z@RAHj42+H_zZa7!0rCxD)>G2ABh;wY3epDdN4SNL9vCo^ zl5&1R2?|c>%wqHgN~$O$BUjv4<kV&sdVQ#<csL{_&3r{?HPm&Co~$dv?1W6M(n4KV zHWZzr-yi52DQ(npXP#`LX6@pYvLBP9UrR?hsy3oRDo6Y{k;<A`%J{0QI>v19SE@eq zSq&wwax2O2%AK{01jrtl$je@Zyj?a_!)PjJ2siZ5D!sB<`UfOiwTWC9dHf&1IsiGB z&q+p~5#^bj`0Yeqb<q+%Do-_)e`5nVz$z+lws?d3&#EW~=z}>^_#WgEt26f{G5I|v zQ<y^8s`73yz`WZG6bU*PtBPWN?b4CU3hjVg!({&et!#4IQSAqWqL%C`o531-Ii%%6 zxyVSlgjMZaq;u~_FVMbg?D2iM?5eI>9MNmwf2bvc-rTUp9mKGNZ>^DY4dTx?Z-1%I zY{gU)NY=&ss#-#h0znP$0med1KO?4&iH387ecDEfbJE;>ZKgzfd(Zcue7(E(+5Qt< zJ5REY?(5|ulqW$lE^;no9z<bu5^Gx|GQN8MQGS-PY+d$_lZ^G`N!;UcnD*Aq>w0gT zv$Hggz<9=Grq;&&6n8bbL#)nGw**NPR+W)8#Bxl3q7xet!E0mJ2knl-QEV{usivDB zY8!oze<R%dJ#IhQlH+2lNQ#Xl6EaNGjp%%soyy6_TOyWch0OC*{O^j^8|W=M*(@$^ zz3ns+GRnurPT!z15FK*$ZV<f4bGf;l=24i69lYGB>1Ghb!y!hCx#W(4_>Q*3rO-4N zx*liWB|OixHH@Wpi!_wSIUnnqDAGjgx=BOCg|6dsC?(gnk!UN8GhJs1&%$x6-5@wl z(l`io)08!smr*y<Jbc4g*bm+Os%pv?oabEEqBIxS7?wnmw-A^1LdHxZ&@ZnWffE)* zoH6ap(f3z)8^wIV5R>`9Dw1eW7m^uNgWCAgn3|7<cJKPH9Rnlg+<bbpBP2F_%vTLl zW3h<1ZjQ42JPWE+wUei;z`_6<(2NZl^T<Jn#mVCHN=ZYZX;xJIoRenddfo#w1masH z1YG?2unG?KsSh3SsfRoT59PR#vnj><J!n_D6e#VY)S)h(KAs-5X`3#Bjha5%cg+j< rmXC72fiZXu$!>qnm`0d}1i@R_%+&D;pu0V9%uWT-OoIER3l97Tq6>fP literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/ssl_support.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bb175262e819cb1c12d2c7e796256ceacd5b1a6f GIT binary patch literal 6755 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 T=0mSOH#>K=;(6ujl2`d3Pyd*I literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/unicode_utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb92f2eafa07eb6aeb139595be69367b69ddf8d7 GIT binary patch literal 1133 zcmZ9L&u`N(6vu5RP1CHaU>gW=Ksii9o!ENeumeI9tQ-T<1nVMD6~%6wEp;;6p+D4~ z;QwGf@-O8I7yboKJUiVF;mGgV&WoM*d0)TT-1HE%@W<Zg-xfl@^yH=y7#u^FM_?$T zI7MOQafo3~QZlwe3nOY#`#TD4TB8p58m&_oyhHIRYB&DC*C=S?(vrzE#(D-#dl&j! z=<*X7g%(KR3-XPKC(63EDPEuzIYqPG1-h<LvcgMrx4wkvYo}U0Lwv_Zs($H-4;VJa z=p1p<g9td@3PLM*cQUUPYH)DWc1tgj370D3F%vq&vZ2^i_0=qA<wn7iIHQb4Dk>X1 z6XPgN=B#um)61p9xbe-8Ra{qyOh9IK9;wk!BsO5bzsDUl&O3RMADDB}^dO!L`GvZA z*^x{YxyrIs-XE?H?H4LZ<zYT68~V6$o=K(&$t^GlH{l`J1KWbf!D16uZ*kf%X+SqP zdoZ|%^MMAT(XCMal;R~`V2TH1Nv4Mja)Q3>Ev=cSAup^IR18o$fHJ61PWI2y)qW59 z8B|;You7L?v@Vy0V7?kf3Jmjy$ydgG4Z=^PUjd^pOla^v==zfpyyltDra6lhqrPF8 z@S#7+#HBQW>na89x&SdEQy-yI1MSRY`Dn=0AW0dF6&v4tFX}pAYh98PQ>m&jw$S1Z zoq_B_aOuSnrwP=S$<l%aQ?AN1^%kx5-u>$5cVMkz?=-PZn%E_tsXz;hZFm=J_2{Pk zt(13RVrZfTUem-t^I1hx--sUEB;ZKq9aRYKud9EDBjGCZBY#lvSS1;cQeR{s4bFl# z5&E3lT)Re%Rj#CTq!NHrXu15Kny17}GXN1khu2bXgNT+BB=Z=?K)eP{w7`T9?{s<y qcY_IDRYEJyq;5XBcZSxzFbv&S<BS$5d#&%c)c9TC*0kNGyZsLx;SpK@ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e15991363dbee69b6d6066088775dd6786a0cb4a GIT binary patch literal 292 zcmZ?b<>g`kf~fgwF%y9FV-N=hIDiZXATBlo5-AKRj5!QZ43z?@3=0@jm=-c-F-0+l zGvrCIFr>0%a}^mdGJs$Ta};wVLmpEEP<=3iCd*5pUIxEgT*av+r3EGV`8mb6*h}-W z^YY8{G+A%)7G$T#7o`^Gmlh?b7T*#`Pc4a0$t*4@%1kOP$;{8Y#a@<LR19Kp$HzmN z@$t7fT`Q7P3qT51G8AzFEdUe0tn^EA3-k*z3v@H{ic1o6a&(i+)AO=Q3QhD8)*~~a hCh8Sb-r}&y%}*)KNws4H8dnVRItLRIqW~ixBLLTaQ!)Sm literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/wheel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b0f745d92c8c31f619bf304ba84b805278bcd219 GIT binary patch literal 6980 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 J&$j%P{{x)K7$pDz literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/__pycache__/windows_support.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..49fa5d378466a3891ab35310e66a280f7c28e5e8 GIT binary patch literal 975 zcmZWo&2G~`5Z<*N$8}qNDnOi&Ply~Et1UtTRTT|M)k;x{nxIG)lAC%rjT77J?rsRF z(hKd4hoC+3Dm=noIrSAdG3zK$!ALvvc{TgZ?6>3E>Z*&tf^W}1{xA^wsXrEG0(c8c zyZ}cK!3hfH5eJwU#Joa*K@DP&(iOVIfk|*1RqR{HMy&|z0Hz}_qj#{xQ*aVp;~QWb znf%e5rHy6?PFgKh?#3Bm6A?jPVfv(I2w@2e9MPG$^&M3VW%c-}Q1)n|BiHQ~?pMv1 zY3}E7z8+^n_L5{hnw(}sdG^v5RE~4WSR(Gi$-HVP#(B=TtmaeYY$v_+g!FdGx-u+u z{%n!PvSeD_PFU1S#14RYA~fXWNl*3}Pn9jELejK?mDL|-(ck8{4OD97E>%fa(Ax;F zU<dPMK!4=Zch)y6<ZA+uAl)U#NaCR}G>6s&22>i_g)jGw84jHSF9C9iaRECsG&3%Z z3v*_QeTlD^Z_pP^OfC8OSJwk;Q|ZY8^#(B^H1m2=^7v#dsmI{M>&FQo?va?&NHRXH zy2YtI&Qfn6W&XzZLFZ`1K2hFJ*rXb<)IS?jA!C*af8+J5&CQLiEq{LOIPb~9v6qg8 z^iHTJ>1SCj_|ES~a+*_71$7E=tDnDBSy65n#;JaqFjV$DN!eP%BvH<Y@{A^1o531f zV-I@WU9>N{fwSNW?B@G!yK@wj>fOVmx^iG>iXwqkJ3MTvGKY4ddf;^9tid_s6-!yV z)!^ZOyz24ZL9-F=b~;A~wGW*}xPMTuH(JW%RQ~(cOCTx@wTAj(#RG6?$-ypO!>(Z& sF19d#0(%vUI}rFi?R09fdxxzU@M3(N?Ua#mLU;79QH+j*9n-OY1GD=2D*ylh literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_deprecation_warning.py b/env/lib/python3.7/site-packages/setuptools/_deprecation_warning.py new file mode 100644 index 0000000..086b64d --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_deprecation_warning.py @@ -0,0 +1,7 @@ +class SetuptoolsDeprecationWarning(Warning): + """ + Base class for warning deprecations in ``setuptools`` + + This class is not derived from ``DeprecationWarning``, and as such is + visible by default. + """ diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/__init__.py b/env/lib/python3.7/site-packages/setuptools/_vendor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..97c8945914d4e64c76ecc3e3611687e427521345 GIT binary patch literal 154 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd<h9ZzKg81dEUy@s(Uyxa# zo0(T!l9-dDn_QlrmsL_|qF<a^Qd&@wpPy5V%#1Hf%}dEI(vOeN%*!l^kJl@xyv1RY Qo1apelWGStycmcX06Rt|Z~y=R literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/pyparsing.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2160210b88e0aa890b5f2d72cd14e401e1c5692f GIT binary patch literal 202997 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�yt|u>yHoX~2 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 Y$ad_>WxBd^S$;EJ*&MUGlTrBp0B(W(`Tzg` literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/__pycache__/six.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..933326ab8ed4618e154cc3fd4605b38fc3c8768c GIT binary patch literal 24355 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py new file mode 100644 index 0000000..95d330e --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__about__.py @@ -0,0 +1,21 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] + +__title__ = "packaging" +__summary__ = "Core utilities for Python packages" +__uri__ = "https://github.com/pypa/packaging" + +__version__ = "16.8" + +__author__ = "Donald Stufft and individual contributors" +__email__ = "donald@stufft.io" + +__license__ = "BSD or Apache License, Version 2.0" +__copyright__ = "Copyright 2014-2016 %s" % __author__ diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py new file mode 100644 index 0000000..5ee6220 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__init__.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +from .__about__ import ( + __author__, __copyright__, __email__, __license__, __summary__, __title__, + __uri__, __version__ +) + +__all__ = [ + "__title__", "__summary__", "__uri__", "__version__", "__author__", + "__email__", "__license__", "__copyright__", +] diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__about__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5abb62b242e5b5e9757dced07c3aeed885f94127 GIT binary patch literal 690 zcmYk4O=}x55QcZX{#dW=#BD>)YM=!}<4r;crIeB;IhGJG^dJgiy(8O7cO_LHF5W-W zbN@}xzV_6=&{Ib-A(hyN8S(0sX0%tMQ5NB#KVE<N)rz9uA$c4r2ABBRI|M`!S5Y0) zxNgx_ozNtXpaluEp#xp$K??n4O52dp4h(1)hO`GGn!+CK!#>SmOb76c_YWgFgy*wp z^5PG=Mw4W_U(BtlyyHyNS{b)ZL9B%pN^bYG5z?`Rm!%7NpD`y~#TnZU7_+{v3$wwb z$Cx)_x4Pyg?8PKwtnhB7492*V*M+Edno5*h+F&zctW<hq#B$|=Oc&+XVkzXZIl5Mc z6YoSNoZyx$lp%K;w3B2f;<kCYa!%WKdA<~G<>%8<)w$m2B7d@JpI%JgHj^7Aiwelh z`NhJKLIM#olnK75NU5YVV(y(Xwi&~N^wK^^r$RMHSF;;}r+-A(6(^r|mw!V(?<yr{ z)05`#`mqXfc5-@tjJP1L?CoR}+OY7>8!Xr06GtWqXd^=3iVAyTI$^0B&<hAJZ~6h@ z?=XXaA>wCb#vu;)dz-sj=UV7vA+1B7<MR7b-n(z-x#iAlr&MMC580YaQ0A#QIUYY( h9veT^n{E2OR^TiCAzaNKAP$l&&XRVFvxPG-{s-}(&V2v? literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c4ed9d214e33a381900e1a836ce79026c7e6cbfa GIT binary patch literal 528 zcmYk2xo+Gr5QZsfSLe!sfjmQyEgUr|1H*8iG)_er7|5b5)8-W(YwXjc&MT=+<yT0R z87~re0DhPu=lD6-ecv)P{`13amNWL7f`3+{bA=~-M+hb|#dO9qo%385yvUfyMWHr& z%eT7ZrLK6TYhLSyH@fAm?s%tne1~}(u@$ALL@gT8if*ZSFLpO<-@jmIwlCIq<6W>S z#Tle_*2lFL@*sn>W<7IWnh5vFOcCRkj4JB21sGF&upVIT0VeB?UM>$2!v<j1qg3d2 z07_1?3G*okN$b%cPf1ZmMfVjz^752$m_1De@Ey+av>d-9^n{W?Yw-=CLVVkwk(T=u zlgDNrm&klU*dR#DcxMyJIu%pNn+~u2Unl(^LUKlh;(sxJPT7P%Ux%pO;H0~dCPaL{ zn4TB&7=L^o!W@%})~fK<g~M!w^@AIyr*V;H833e_DCCnnuJspfMN;!6i463u_xZ=N G&He&X7L8T_ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..32408c93cc06eb1bda49bafbcd4d3f87fc479051 GIT binary patch literal 980 zcmah{OKTf35Y}UDZ(PSdGz9uMxR<~lVnf?w2&FCbQbM6n=n@dhN=`P}S0rtMLwZUe z`4?@E{Y$#`l)unZXXM09>7fHNni)yoe45eg)zv-$NxyFF?s7tYVsIx6oL8Xs6BtDl zEl5dITC$XtJmnN~tccP`M~59n9udWlSlV4i5kx)RGjDY~qv=Z3)qPx5M|Cer`arRd zB<bA%Hc7Z2$vs;at<xeeo7y-ZtNbLld0qKoWAe(0SzBce;+-2Lb^~llM)5WX23^n| zsNDebj$Dx|I%A3|b{Q*nO)vNt=EygC&J<TsPQFJ_zH>J1k3rrTEu9|A@t(ALoE6gA z@oDZ3AX925Lt+w6W&pkvEQ?|vgV7|Vilpp*;gl;5WumiZh$jAEZ54GU3%fm8rm`qN z5rQk~Lr^;ab4}0bH96-O2t{{(0G{VrVSQA|Qv1F;$gM!))>D-*-&yz(LL2PJulG|| zHq$0=HuK6lSrnVu>3((Sj$cl#c5UP8y0G_MaiS|#n`tAnBe|bf`%{tCWh33Bnfsm) zl|B{XDH6n45PFvU_kEMwTRXr$1|O&k;rl|AwQ39W2SOaTvRLex5#R>)2{YIQvwD{> zL-72{vU5)$3_N0LuxWneH2xuJ<|0h)7RE<z-sk|F@C94|#ykI33Ppy0KWhyug*o-s zxmkxO8Q>FUt!oWD!C*HG{tAPqJhyY}2PfL#KNfj4t3Chl`8k>wu<48+fPwZ3WM+Lo iOfF;sdSG?W1WxhRqGQ`w!eVNT#e7JIQAA_b<-Y-)CHEEp literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/_structures.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0348d7cda710f1001d70e7f5e89d8bc1b4ec0507 GIT binary patch literal 2832 zcmcImOK;Oa5Z<*D$4S#ReL!0fNL)acXd@wzkU&*=2*f2qq9+S!WxU(e#j)M>rl?hK z>4AU2nZM*KC;kE_W;S(6DjSDKH`<xCXLrBZ*_qFIK0n_g(A+O~-+!(X@(myIR)fI~ z^z<bNPB;z8fVy;GxW>SAO-f!9ZgBIAa8uMqrdt>F5pnDAw#Mu5wyxh=!h*LJx84z_ z@f~&|j+rfbAJRA+D#3z55=)iYJU9x{Ada$yL<W&!d&9_A@a*G?ycsaqfu8Py5X7aN zxCW=(I3upfO<n^H*xUkL=M8Ryws@1bKsWdtZ-ch^JYN9a<cqumy2Y3HGUz$J0v@hr z_M2!ghyr!&Qvkt+8v6_ADF%g8m}&GR1dMzo4$W$*2=}A~k6QeA+f{?4n*_;b5T(is z!%hEFKRQr{54)*Q!$ie#m`)Dak%)LKyNTz2^!h>6@3K_Mp|6Hgq+7{xW-}&5A{lF< z6Bq|VPnL35w{q*0&n8ULKDS|@h@z)tL`Ud5?KwtP+xOD_tcKe<R5oDFuM<cc9uXAh zFoqixfsU=db_b@QE(+8uy|H6xkgOi7eIYMnS&W5>vBe3b#fjsg?ay%JJZx2jA{bjP zLjl_q%B2vVLI@A&$jC$3f|SJzj(m|dVQJ{4DP!jcEptE|GIp)R0kjo6umCF*$sK5u za~EU>Pq_r50yTo8t(TypZ3?yM5_cyrvFvPpxTc#WC}{gnDB$nyG88-u`i~9u)LGPd z+-TP6iN2?TBatUrNewg@i$tHXJFrz=0-byf)SWi=oHiCq<P88lYcV#6`7p$Bo3X>8 z7mh6wi&tVXNxV*p$u2P$<qC>b6qp%u4aEhWj7M0JnsKmFQ(R>mwmJRNb{|X^4NGzd z`V}&!ybk-9hy0u@Pnw%~)W(TaNI5z}4*IJ(g`R9&zNWvSI*H#nIR~QnlJ%9`uRxuV z>nh7cUwwB1Y^~skGtpf&6eie%Dkv-%9c`G1`uChS6XEEjepCT`HC(4l>2U@0OoTV} z)hZ%9U9e9opk`vdYAB?I?JB6*s85qbNg*KdJez=7FUZZD@g#mu<OYfxDE^t;kVo!8 zFC#a!_nZdu>)sIm8Nt6EOjwB-EAfw6X2l;4gs=1wH7^yhXl6eh^Yb>YNs(Ar&CV?g F`cJYS^xFUc literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/markers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..734e69fc180bde56fe8303d317d912c27ed7b077 GIT binary patch literal 8837 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 URZRW`(>jnftP$&oWm(hz2lW-k!vFvP literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/requirements.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5496a5e2d002dfffd4c161cfad34d30212fb5147 GIT binary patch literal 3839 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 VB~VLdiDghqGvH&DHEtHI{{lz1+<gE5 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/specifiers.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..42bd9c967a3b8a465f4a3532a2a1e263ea117128 GIT binary patch literal 19758 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/utils.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..89bbd06c26679b9702101d9d9ac6a997179b0cd3 GIT binary patch literal 459 zcmY*VyH3L}6t$f+jSA%<_y(j1rI8RLLI^g7E^Gm0rLl<&j%{qGg^H2?pdA?aC9h2U zLMQA>NaafB_&#;+_2qCl0N%=vqq|QCz;_7#Eb`8UhdJ>?0D&B|u!JotQ5%&J3^~N( zGN$pON1`Px6B3i&J1F}E-GD6l@pB-H+-@~7l6RJ3)+(v3O9`7Y!=!LKN;6^cLnmtM z<MBMX&GG2|xc1AeExfVEm515$WWfRw_y(3}ftJ9_pz#XkUgZGSm5_qf6=!pbHErmN zi%d6hJuYWdXVAr>YUvly;pWwKVOv!wrgA2XtvJu?StB0p^J!tI?Ua?0n@tx_sUT7p zs;Zx=hKZ)=EaPURUfupb>7cS5_C=lm(!tMCH^BZ*+i8li4iz0fScl^r($w{9*(%1V ePC`1&toPiYt<ajDwUTt4o`*pbdJj<=4WeI}#CP}r literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/__pycache__/version.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..25e3dcc4585fe80e6996a03e179b0bd1dbe18687 GIT binary patch literal 10525 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py new file mode 100644 index 0000000..210bb80 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/_compat.py @@ -0,0 +1,30 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import sys + + +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +# flake8: noqa + +if PY3: + string_types = str, +else: + string_types = basestring, + + +def with_metaclass(meta, *bases): + """ + Create a base class with a metaclass. + """ + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py new file mode 100644 index 0000000..ccc2786 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/_structures.py @@ -0,0 +1,68 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + + +class Infinity(object): + + def __repr__(self): + return "Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return False + + def __le__(self, other): + return False + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return True + + def __ge__(self, other): + return True + + def __neg__(self): + return NegativeInfinity + +Infinity = Infinity() + + +class NegativeInfinity(object): + + def __repr__(self): + return "-Infinity" + + def __hash__(self): + return hash(repr(self)) + + def __lt__(self, other): + return True + + def __le__(self, other): + return True + + def __eq__(self, other): + return isinstance(other, self.__class__) + + def __ne__(self, other): + return not isinstance(other, self.__class__) + + def __gt__(self, other): + return False + + def __ge__(self, other): + return False + + def __neg__(self): + return Infinity + +NegativeInfinity = NegativeInfinity() diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py new file mode 100644 index 0000000..031332a --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/markers.py @@ -0,0 +1,301 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import operator +import os +import platform +import sys + +from setuptools.extern.pyparsing import ParseException, ParseResults, stringStart, stringEnd +from setuptools.extern.pyparsing import ZeroOrMore, Group, Forward, QuotedString +from setuptools.extern.pyparsing import Literal as L # noqa + +from ._compat import string_types +from .specifiers import Specifier, InvalidSpecifier + + +__all__ = [ + "InvalidMarker", "UndefinedComparison", "UndefinedEnvironmentName", + "Marker", "default_environment", +] + + +class InvalidMarker(ValueError): + """ + An invalid marker was found, users should refer to PEP 508. + """ + + +class UndefinedComparison(ValueError): + """ + An invalid operation was attempted on a value that doesn't support it. + """ + + +class UndefinedEnvironmentName(ValueError): + """ + A name was attempted to be used that does not exist inside of the + environment. + """ + + +class Node(object): + + def __init__(self, value): + self.value = value + + def __str__(self): + return str(self.value) + + def __repr__(self): + return "<{0}({1!r})>".format(self.__class__.__name__, str(self)) + + def serialize(self): + raise NotImplementedError + + +class Variable(Node): + + def serialize(self): + return str(self) + + +class Value(Node): + + def serialize(self): + return '"{0}"'.format(self) + + +class Op(Node): + + def serialize(self): + return str(self) + + +VARIABLE = ( + L("implementation_version") | + L("platform_python_implementation") | + L("implementation_name") | + L("python_full_version") | + L("platform_release") | + L("platform_version") | + L("platform_machine") | + L("platform_system") | + L("python_version") | + L("sys_platform") | + L("os_name") | + L("os.name") | # PEP-345 + L("sys.platform") | # PEP-345 + L("platform.version") | # PEP-345 + L("platform.machine") | # PEP-345 + L("platform.python_implementation") | # PEP-345 + L("python_implementation") | # undocumented setuptools legacy + L("extra") +) +ALIASES = { + 'os.name': 'os_name', + 'sys.platform': 'sys_platform', + 'platform.version': 'platform_version', + 'platform.machine': 'platform_machine', + 'platform.python_implementation': 'platform_python_implementation', + 'python_implementation': 'platform_python_implementation' +} +VARIABLE.setParseAction(lambda s, l, t: Variable(ALIASES.get(t[0], t[0]))) + +VERSION_CMP = ( + L("===") | + L("==") | + L(">=") | + L("<=") | + L("!=") | + L("~=") | + L(">") | + L("<") +) + +MARKER_OP = VERSION_CMP | L("not in") | L("in") +MARKER_OP.setParseAction(lambda s, l, t: Op(t[0])) + +MARKER_VALUE = QuotedString("'") | QuotedString('"') +MARKER_VALUE.setParseAction(lambda s, l, t: Value(t[0])) + +BOOLOP = L("and") | L("or") + +MARKER_VAR = VARIABLE | MARKER_VALUE + +MARKER_ITEM = Group(MARKER_VAR + MARKER_OP + MARKER_VAR) +MARKER_ITEM.setParseAction(lambda s, l, t: tuple(t[0])) + +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() + +MARKER_EXPR = Forward() +MARKER_ATOM = MARKER_ITEM | Group(LPAREN + MARKER_EXPR + RPAREN) +MARKER_EXPR << MARKER_ATOM + ZeroOrMore(BOOLOP + MARKER_EXPR) + +MARKER = stringStart + MARKER_EXPR + stringEnd + + +def _coerce_parse_result(results): + if isinstance(results, ParseResults): + return [_coerce_parse_result(i) for i in results] + else: + return results + + +def _format_marker(marker, first=True): + assert isinstance(marker, (list, tuple, string_types)) + + # Sometimes we have a structure like [[...]] which is a single item list + # where the single item is itself it's own list. In that case we want skip + # the rest of this function so that we don't get extraneous () on the + # outside. + if (isinstance(marker, list) and len(marker) == 1 and + isinstance(marker[0], (list, tuple))): + return _format_marker(marker[0]) + + if isinstance(marker, list): + inner = (_format_marker(m, first=False) for m in marker) + if first: + return " ".join(inner) + else: + return "(" + " ".join(inner) + ")" + elif isinstance(marker, tuple): + return " ".join([m.serialize() for m in marker]) + else: + return marker + + +_operators = { + "in": lambda lhs, rhs: lhs in rhs, + "not in": lambda lhs, rhs: lhs not in rhs, + "<": operator.lt, + "<=": operator.le, + "==": operator.eq, + "!=": operator.ne, + ">=": operator.ge, + ">": operator.gt, +} + + +def _eval_op(lhs, op, rhs): + try: + spec = Specifier("".join([op.serialize(), rhs])) + except InvalidSpecifier: + pass + else: + return spec.contains(lhs) + + oper = _operators.get(op.serialize()) + if oper is None: + raise UndefinedComparison( + "Undefined {0!r} on {1!r} and {2!r}.".format(op, lhs, rhs) + ) + + return oper(lhs, rhs) + + +_undefined = object() + + +def _get_env(environment, name): + value = environment.get(name, _undefined) + + if value is _undefined: + raise UndefinedEnvironmentName( + "{0!r} does not exist in evaluation environment.".format(name) + ) + + return value + + +def _evaluate_markers(markers, environment): + groups = [[]] + + for marker in markers: + assert isinstance(marker, (list, tuple, string_types)) + + if isinstance(marker, list): + groups[-1].append(_evaluate_markers(marker, environment)) + elif isinstance(marker, tuple): + lhs, op, rhs = marker + + if isinstance(lhs, Variable): + lhs_value = _get_env(environment, lhs.value) + rhs_value = rhs.value + else: + lhs_value = lhs.value + rhs_value = _get_env(environment, rhs.value) + + groups[-1].append(_eval_op(lhs_value, op, rhs_value)) + else: + assert marker in ["and", "or"] + if marker == "or": + groups.append([]) + + return any(all(item) for item in groups) + + +def format_full_version(info): + version = '{0.major}.{0.minor}.{0.micro}'.format(info) + kind = info.releaselevel + if kind != 'final': + version += kind[0] + str(info.serial) + return version + + +def default_environment(): + if hasattr(sys, 'implementation'): + iver = format_full_version(sys.implementation.version) + implementation_name = sys.implementation.name + else: + iver = '0' + implementation_name = '' + + return { + "implementation_name": implementation_name, + "implementation_version": iver, + "os_name": os.name, + "platform_machine": platform.machine(), + "platform_release": platform.release(), + "platform_system": platform.system(), + "platform_version": platform.version(), + "python_full_version": platform.python_version(), + "platform_python_implementation": platform.python_implementation(), + "python_version": platform.python_version()[:3], + "sys_platform": sys.platform, + } + + +class Marker(object): + + def __init__(self, marker): + try: + self._markers = _coerce_parse_result(MARKER.parseString(marker)) + except ParseException as e: + err_str = "Invalid marker: {0!r}, parse error at {1!r}".format( + marker, marker[e.loc:e.loc + 8]) + raise InvalidMarker(err_str) + + def __str__(self): + return _format_marker(self._markers) + + def __repr__(self): + return "<Marker({0!r})>".format(str(self)) + + def evaluate(self, environment=None): + """Evaluate a marker. + + Return the boolean from evaluating the given marker against the + environment. environment is an optional argument to override all or + part of the determined environment. + + The environment is determined from the current Python process. + """ + current_environment = default_environment() + if environment is not None: + current_environment.update(environment) + + return _evaluate_markers(self._markers, current_environment) diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py new file mode 100644 index 0000000..5b49341 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/requirements.py @@ -0,0 +1,127 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import string +import re + +from setuptools.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException +from setuptools.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine +from setuptools.extern.pyparsing import Literal as L # noqa +from setuptools.extern.six.moves.urllib import parse as urlparse + +from .markers import MARKER_EXPR, Marker +from .specifiers import LegacySpecifier, Specifier, SpecifierSet + + +class InvalidRequirement(ValueError): + """ + An invalid requirement was found, users should refer to PEP 508. + """ + + +ALPHANUM = Word(string.ascii_letters + string.digits) + +LBRACKET = L("[").suppress() +RBRACKET = L("]").suppress() +LPAREN = L("(").suppress() +RPAREN = L(")").suppress() +COMMA = L(",").suppress() +SEMICOLON = L(";").suppress() +AT = L("@").suppress() + +PUNCTUATION = Word("-_.") +IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) +IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) + +NAME = IDENTIFIER("name") +EXTRA = IDENTIFIER + +URI = Regex(r'[^ ]+')("url") +URL = (AT + URI) + +EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) +EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") + +VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) +VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) + +VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY +VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), + joinString=",", adjacent=False)("_raw_spec") +_VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) +_VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') + +VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") +VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) + +MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") +MARKER_EXPR.setParseAction( + lambda s, l, t: Marker(s[t._original_start:t._original_end]) +) +MARKER_SEPERATOR = SEMICOLON +MARKER = MARKER_SEPERATOR + MARKER_EXPR + +VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) +URL_AND_MARKER = URL + Optional(MARKER) + +NAMED_REQUIREMENT = \ + NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) + +REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd + + +class Requirement(object): + """Parse a requirement. + + Parse a given requirement string into its parts, such as name, specifier, + URL, and extras. Raises InvalidRequirement on a badly-formed requirement + string. + """ + + # TODO: Can we test whether something is contained within a requirement? + # If so how do we do that? Do we need to test against the _name_ of + # the thing as well as the version? What about the markers? + # TODO: Can we normalize the name and extra name? + + def __init__(self, requirement_string): + try: + req = REQUIREMENT.parseString(requirement_string) + except ParseException as e: + raise InvalidRequirement( + "Invalid requirement, parse error at \"{0!r}\"".format( + requirement_string[e.loc:e.loc + 8])) + + self.name = req.name + if req.url: + parsed_url = urlparse.urlparse(req.url) + if not (parsed_url.scheme and parsed_url.netloc) or ( + not parsed_url.scheme and not parsed_url.netloc): + raise InvalidRequirement("Invalid URL given") + self.url = req.url + else: + self.url = None + self.extras = set(req.extras.asList() if req.extras else []) + self.specifier = SpecifierSet(req.specifier) + self.marker = req.marker if req.marker else None + + def __str__(self): + parts = [self.name] + + if self.extras: + parts.append("[{0}]".format(",".join(sorted(self.extras)))) + + if self.specifier: + parts.append(str(self.specifier)) + + if self.url: + parts.append("@ {0}".format(self.url)) + + if self.marker: + parts.append("; {0}".format(self.marker)) + + return "".join(parts) + + def __repr__(self): + return "<Requirement({0!r})>".format(str(self)) diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py new file mode 100644 index 0000000..7f5a76c --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/specifiers.py @@ -0,0 +1,774 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import abc +import functools +import itertools +import re + +from ._compat import string_types, with_metaclass +from .version import Version, LegacyVersion, parse + + +class InvalidSpecifier(ValueError): + """ + An invalid specifier was found, users should refer to PEP 440. + """ + + +class BaseSpecifier(with_metaclass(abc.ABCMeta, object)): + + @abc.abstractmethod + def __str__(self): + """ + Returns the str representation of this Specifier like object. This + should be representative of the Specifier itself. + """ + + @abc.abstractmethod + def __hash__(self): + """ + Returns a hash value for this Specifier like object. + """ + + @abc.abstractmethod + def __eq__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are equal. + """ + + @abc.abstractmethod + def __ne__(self, other): + """ + Returns a boolean representing whether or not the two Specifier like + objects are not equal. + """ + + @abc.abstractproperty + def prereleases(self): + """ + Returns whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @prereleases.setter + def prereleases(self, value): + """ + Sets whether or not pre-releases as a whole are allowed by this + specifier. + """ + + @abc.abstractmethod + def contains(self, item, prereleases=None): + """ + Determines if the given item is contained within this specifier. + """ + + @abc.abstractmethod + def filter(self, iterable, prereleases=None): + """ + Takes an iterable of items and filters them so that only items which + are contained within this specifier are allowed in it. + """ + + +class _IndividualSpecifier(BaseSpecifier): + + _operators = {} + + def __init__(self, spec="", prereleases=None): + match = self._regex.search(spec) + if not match: + raise InvalidSpecifier("Invalid specifier: '{0}'".format(spec)) + + self._spec = ( + match.group("operator").strip(), + match.group("version").strip(), + ) + + # Store whether or not this Specifier should accept prereleases + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<{0}({1!r}{2})>".format( + self.__class__.__name__, + str(self), + pre, + ) + + def __str__(self): + return "{0}{1}".format(*self._spec) + + def __hash__(self): + return hash(self._spec) + + def __eq__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec == other._spec + + def __ne__(self, other): + if isinstance(other, string_types): + try: + other = self.__class__(other) + except InvalidSpecifier: + return NotImplemented + elif not isinstance(other, self.__class__): + return NotImplemented + + return self._spec != other._spec + + def _get_operator(self, op): + return getattr(self, "_compare_{0}".format(self._operators[op])) + + def _coerce_version(self, version): + if not isinstance(version, (LegacyVersion, Version)): + version = parse(version) + return version + + @property + def operator(self): + return self._spec[0] + + @property + def version(self): + return self._spec[1] + + @property + def prereleases(self): + return self._prereleases + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Determine if prereleases are to be allowed or not. + if prereleases is None: + prereleases = self.prereleases + + # Normalize item to a Version or LegacyVersion, this allows us to have + # a shortcut for ``"2.0" in Specifier(">=2") + item = self._coerce_version(item) + + # Determine if we should be supporting prereleases in this specifier + # or not, if we do not support prereleases than we can short circuit + # logic if this version is a prereleases. + if item.is_prerelease and not prereleases: + return False + + # Actually do the comparison to determine if this item is contained + # within this Specifier or not. + return self._get_operator(self.operator)(item, self.version) + + def filter(self, iterable, prereleases=None): + yielded = False + found_prereleases = [] + + kw = {"prereleases": prereleases if prereleases is not None else True} + + # Attempt to iterate over all the values in the iterable and if any of + # them match, yield them. + for version in iterable: + parsed_version = self._coerce_version(version) + + if self.contains(parsed_version, **kw): + # If our version is a prerelease, and we were not set to allow + # prereleases, then we'll store it for later incase nothing + # else matches this specifier. + if (parsed_version.is_prerelease and not + (prereleases or self.prereleases)): + found_prereleases.append(version) + # Either this is not a prerelease, or we should have been + # accepting prereleases from the begining. + else: + yielded = True + yield version + + # Now that we've iterated over everything, determine if we've yielded + # any values, and if we have not and we have any prereleases stored up + # then we will go ahead and yield the prereleases. + if not yielded and found_prereleases: + for version in found_prereleases: + yield version + + +class LegacySpecifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(==|!=|<=|>=|<|>)) + \s* + (?P<version> + [^,;\s)]* # Since this is a "legacy" specifier, and the version + # string can be just about anything, we match everything + # except for whitespace, a semi-colon for marker support, + # a closing paren since versions can be enclosed in + # them, and a comma since it's a version separator. + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + } + + def _coerce_version(self, version): + if not isinstance(version, LegacyVersion): + version = LegacyVersion(str(version)) + return version + + def _compare_equal(self, prospective, spec): + return prospective == self._coerce_version(spec) + + def _compare_not_equal(self, prospective, spec): + return prospective != self._coerce_version(spec) + + def _compare_less_than_equal(self, prospective, spec): + return prospective <= self._coerce_version(spec) + + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= self._coerce_version(spec) + + def _compare_less_than(self, prospective, spec): + return prospective < self._coerce_version(spec) + + def _compare_greater_than(self, prospective, spec): + return prospective > self._coerce_version(spec) + + +def _require_version_compare(fn): + @functools.wraps(fn) + def wrapped(self, prospective, spec): + if not isinstance(prospective, Version): + return False + return fn(self, prospective, spec) + return wrapped + + +class Specifier(_IndividualSpecifier): + + _regex_str = ( + r""" + (?P<operator>(~=|==|!=|<=|>=|<|>|===)) + (?P<version> + (?: + # The identity operators allow for an escape hatch that will + # do an exact string match of the version you wish to install. + # This will not be parsed by PEP 440 and we cannot determine + # any semantic meaning from it. This operator is discouraged + # but included entirely as an escape hatch. + (?<====) # Only match for the identity operator + \s* + [^\s]* # We just match everything, except for whitespace + # since we are only testing for strict identity. + ) + | + (?: + # The (non)equality operators allow for wild card and local + # versions to be specified so we have to define these two + # operators separately to enable that. + (?<===|!=) # Only match for equals and not equals + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + + # You cannot use a wild card and a dev or local version + # together so group them with a | and make them optional. + (?: + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + (?:\+[a-z0-9]+(?:[-_\.][a-z0-9]+)*)? # local + | + \.\* # Wild card syntax of .* + )? + ) + | + (?: + # The compatible operator requires at least two digits in the + # release segment. + (?<=~=) # Only match for the compatible operator + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)+ # release (We have a + instead of a *) + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + | + (?: + # All other operators only allow a sub set of what the + # (non)equality operators do. Specifically they do not allow + # local versions to be specified nor do they allow the prefix + # matching wild cards. + (?<!==|!=|~=) # We have special cases for these + # operators so we want to make sure they + # don't match here. + + \s* + v? + (?:[0-9]+!)? # epoch + [0-9]+(?:\.[0-9]+)* # release + (?: # pre release + [-_\.]? + (a|b|c|rc|alpha|beta|pre|preview) + [-_\.]? + [0-9]* + )? + (?: # post release + (?:-[0-9]+)|(?:[-_\.]?(post|rev|r)[-_\.]?[0-9]*) + )? + (?:[-_\.]?dev[-_\.]?[0-9]*)? # dev release + ) + ) + """ + ) + + _regex = re.compile( + r"^\s*" + _regex_str + r"\s*$", re.VERBOSE | re.IGNORECASE) + + _operators = { + "~=": "compatible", + "==": "equal", + "!=": "not_equal", + "<=": "less_than_equal", + ">=": "greater_than_equal", + "<": "less_than", + ">": "greater_than", + "===": "arbitrary", + } + + @_require_version_compare + def _compare_compatible(self, prospective, spec): + # Compatible releases have an equivalent combination of >= and ==. That + # is that ~=2.2 is equivalent to >=2.2,==2.*. This allows us to + # implement this in terms of the other specifiers instead of + # implementing it ourselves. The only thing we need to do is construct + # the other specifiers. + + # We want everything but the last item in the version, but we want to + # ignore post and dev releases and we want to treat the pre-release as + # it's own separate segment. + prefix = ".".join( + list( + itertools.takewhile( + lambda x: (not x.startswith("post") and not + x.startswith("dev")), + _version_split(spec), + ) + )[:-1] + ) + + # Add the prefix notation to the end of our string + prefix += ".*" + + return (self._get_operator(">=")(prospective, spec) and + self._get_operator("==")(prospective, prefix)) + + @_require_version_compare + def _compare_equal(self, prospective, spec): + # We need special logic to handle prefix matching + if spec.endswith(".*"): + # In the case of prefix matching we want to ignore local segment. + prospective = Version(prospective.public) + # Split the spec out by dots, and pretend that there is an implicit + # dot in between a release segment and a pre-release segment. + spec = _version_split(spec[:-2]) # Remove the trailing .* + + # Split the prospective version out by dots, and pretend that there + # is an implicit dot in between a release segment and a pre-release + # segment. + prospective = _version_split(str(prospective)) + + # Shorten the prospective version to be the same length as the spec + # so that we can determine if the specifier is a prefix of the + # prospective version or not. + prospective = prospective[:len(spec)] + + # Pad out our two sides with zeros so that they both equal the same + # length. + spec, prospective = _pad_version(spec, prospective) + else: + # Convert our spec string into a Version + spec = Version(spec) + + # If the specifier does not have a local segment, then we want to + # act as if the prospective version also does not have a local + # segment. + if not spec.local: + prospective = Version(prospective.public) + + return prospective == spec + + @_require_version_compare + def _compare_not_equal(self, prospective, spec): + return not self._compare_equal(prospective, spec) + + @_require_version_compare + def _compare_less_than_equal(self, prospective, spec): + return prospective <= Version(spec) + + @_require_version_compare + def _compare_greater_than_equal(self, prospective, spec): + return prospective >= Version(spec) + + @_require_version_compare + def _compare_less_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is less than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective < spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a pre-release version, that we do not accept pre-release + # versions for the version mentioned in the specifier (e.g. <3.1 should + # not match 3.1.dev0, but should match 3.0.dev0). + if not spec.is_prerelease and prospective.is_prerelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # less than the spec version *and* it's not a pre-release of the same + # version in the spec. + return True + + @_require_version_compare + def _compare_greater_than(self, prospective, spec): + # Convert our spec to a Version instance, since we'll want to work with + # it as a version. + spec = Version(spec) + + # Check to see if the prospective version is greater than the spec + # version. If it's not we can short circuit and just return False now + # instead of doing extra unneeded work. + if not prospective > spec: + return False + + # This special case is here so that, unless the specifier itself + # includes is a post-release version, that we do not accept + # post-release versions for the version mentioned in the specifier + # (e.g. >3.1 should not match 3.0.post0, but should match 3.2.post0). + if not spec.is_postrelease and prospective.is_postrelease: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # Ensure that we do not allow a local version of the version mentioned + # in the specifier, which is techincally greater than, to match. + if prospective.local is not None: + if Version(prospective.base_version) == Version(spec.base_version): + return False + + # If we've gotten to here, it means that prospective version is both + # greater than the spec version *and* it's not a pre-release of the + # same version in the spec. + return True + + def _compare_arbitrary(self, prospective, spec): + return str(prospective).lower() == str(spec).lower() + + @property + def prereleases(self): + # If there is an explicit prereleases set for this, then we'll just + # blindly use that. + if self._prereleases is not None: + return self._prereleases + + # Look at all of our specifiers and determine if they are inclusive + # operators, and if they are if they are including an explicit + # prerelease. + operator, version = self._spec + if operator in ["==", ">=", "<=", "~=", "==="]: + # The == specifier can include a trailing .*, if it does we + # want to remove before parsing. + if operator == "==" and version.endswith(".*"): + version = version[:-2] + + # Parse the version, and if it is a pre-release than this + # specifier allows pre-releases. + if parse(version).is_prerelease: + return True + + return False + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + +_prefix_regex = re.compile(r"^([0-9]+)((?:a|b|c|rc)[0-9]+)$") + + +def _version_split(version): + result = [] + for item in version.split("."): + match = _prefix_regex.search(item) + if match: + result.extend(match.groups()) + else: + result.append(item) + return result + + +def _pad_version(left, right): + left_split, right_split = [], [] + + # Get the release segment of our versions + left_split.append(list(itertools.takewhile(lambda x: x.isdigit(), left))) + right_split.append(list(itertools.takewhile(lambda x: x.isdigit(), right))) + + # Get the rest of our versions + left_split.append(left[len(left_split[0]):]) + right_split.append(right[len(right_split[0]):]) + + # Insert our padding + left_split.insert( + 1, + ["0"] * max(0, len(right_split[0]) - len(left_split[0])), + ) + right_split.insert( + 1, + ["0"] * max(0, len(left_split[0]) - len(right_split[0])), + ) + + return ( + list(itertools.chain(*left_split)), + list(itertools.chain(*right_split)), + ) + + +class SpecifierSet(BaseSpecifier): + + def __init__(self, specifiers="", prereleases=None): + # Split on , to break each indidivual specifier into it's own item, and + # strip each item to remove leading/trailing whitespace. + specifiers = [s.strip() for s in specifiers.split(",") if s.strip()] + + # Parsed each individual specifier, attempting first to make it a + # Specifier and falling back to a LegacySpecifier. + parsed = set() + for specifier in specifiers: + try: + parsed.add(Specifier(specifier)) + except InvalidSpecifier: + parsed.add(LegacySpecifier(specifier)) + + # Turn our parsed specifiers into a frozen set and save them for later. + self._specs = frozenset(parsed) + + # Store our prereleases value so we can use it later to determine if + # we accept prereleases or not. + self._prereleases = prereleases + + def __repr__(self): + pre = ( + ", prereleases={0!r}".format(self.prereleases) + if self._prereleases is not None + else "" + ) + + return "<SpecifierSet({0!r}{1})>".format(str(self), pre) + + def __str__(self): + return ",".join(sorted(str(s) for s in self._specs)) + + def __hash__(self): + return hash(self._specs) + + def __and__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + specifier = SpecifierSet() + specifier._specs = frozenset(self._specs | other._specs) + + if self._prereleases is None and other._prereleases is not None: + specifier._prereleases = other._prereleases + elif self._prereleases is not None and other._prereleases is None: + specifier._prereleases = self._prereleases + elif self._prereleases == other._prereleases: + specifier._prereleases = self._prereleases + else: + raise ValueError( + "Cannot combine SpecifierSets with True and False prerelease " + "overrides." + ) + + return specifier + + def __eq__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs == other._specs + + def __ne__(self, other): + if isinstance(other, string_types): + other = SpecifierSet(other) + elif isinstance(other, _IndividualSpecifier): + other = SpecifierSet(str(other)) + elif not isinstance(other, SpecifierSet): + return NotImplemented + + return self._specs != other._specs + + def __len__(self): + return len(self._specs) + + def __iter__(self): + return iter(self._specs) + + @property + def prereleases(self): + # If we have been given an explicit prerelease modifier, then we'll + # pass that through here. + if self._prereleases is not None: + return self._prereleases + + # If we don't have any specifiers, and we don't have a forced value, + # then we'll just return None since we don't know if this should have + # pre-releases or not. + if not self._specs: + return None + + # Otherwise we'll see if any of the given specifiers accept + # prereleases, if any of them do we'll return True, otherwise False. + return any(s.prereleases for s in self._specs) + + @prereleases.setter + def prereleases(self, value): + self._prereleases = value + + def __contains__(self, item): + return self.contains(item) + + def contains(self, item, prereleases=None): + # Ensure that our item is a Version or LegacyVersion instance. + if not isinstance(item, (LegacyVersion, Version)): + item = parse(item) + + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # We can determine if we're going to allow pre-releases by looking to + # see if any of the underlying items supports them. If none of them do + # and this item is a pre-release then we do not allow it and we can + # short circuit that here. + # Note: This means that 1.0.dev1 would not be contained in something + # like >=1.0.devabc however it would be in >=1.0.debabc,>0.0.dev0 + if not prereleases and item.is_prerelease: + return False + + # We simply dispatch to the underlying specs here to make sure that the + # given version is contained within all of them. + # Note: This use of all() here means that an empty set of specifiers + # will always return True, this is an explicit design decision. + return all( + s.contains(item, prereleases=prereleases) + for s in self._specs + ) + + def filter(self, iterable, prereleases=None): + # Determine if we're forcing a prerelease or not, if we're not forcing + # one for this particular filter call, then we'll use whatever the + # SpecifierSet thinks for whether or not we should support prereleases. + if prereleases is None: + prereleases = self.prereleases + + # If we have any specifiers, then we want to wrap our iterable in the + # filter method for each one, this will act as a logical AND amongst + # each specifier. + if self._specs: + for spec in self._specs: + iterable = spec.filter(iterable, prereleases=bool(prereleases)) + return iterable + # If we do not have any specifiers, then we need to have a rough filter + # which will filter out any pre-releases, unless there are no final + # releases, and which will filter out LegacyVersion in general. + else: + filtered = [] + found_prereleases = [] + + for item in iterable: + # Ensure that we some kind of Version class for this item. + if not isinstance(item, (LegacyVersion, Version)): + parsed_version = parse(item) + else: + parsed_version = item + + # Filter out any item which is parsed as a LegacyVersion + if isinstance(parsed_version, LegacyVersion): + continue + + # Store any item which is a pre-release for later unless we've + # already found a final version or we are accepting prereleases + if parsed_version.is_prerelease and not prereleases: + if not filtered: + found_prereleases.append(item) + else: + filtered.append(item) + + # If we've found no items except for pre-releases, then we'll go + # ahead and use the pre-releases + if not filtered and found_prereleases and prereleases is None: + return found_prereleases + + return filtered diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py new file mode 100644 index 0000000..942387c --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/utils.py @@ -0,0 +1,14 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import re + + +_canonicalize_regex = re.compile(r"[-_.]+") + + +def canonicalize_name(name): + # This is taken from PEP 503. + return _canonicalize_regex.sub("-", name).lower() diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py new file mode 100644 index 0000000..83b5ee8 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/packaging/version.py @@ -0,0 +1,393 @@ +# This file is dual licensed under the terms of the Apache License, Version +# 2.0, and the BSD License. See the LICENSE file in the root of this repository +# for complete details. +from __future__ import absolute_import, division, print_function + +import collections +import itertools +import re + +from ._structures import Infinity + + +__all__ = [ + "parse", "Version", "LegacyVersion", "InvalidVersion", "VERSION_PATTERN" +] + + +_Version = collections.namedtuple( + "_Version", + ["epoch", "release", "dev", "pre", "post", "local"], +) + + +def parse(version): + """ + Parse the given version string and return either a :class:`Version` object + or a :class:`LegacyVersion` object depending on if the given version is + a valid PEP 440 version or a legacy version. + """ + try: + return Version(version) + except InvalidVersion: + return LegacyVersion(version) + + +class InvalidVersion(ValueError): + """ + An invalid version was found, users should refer to PEP 440. + """ + + +class _BaseVersion(object): + + def __hash__(self): + return hash(self._key) + + def __lt__(self, other): + return self._compare(other, lambda s, o: s < o) + + def __le__(self, other): + return self._compare(other, lambda s, o: s <= o) + + def __eq__(self, other): + return self._compare(other, lambda s, o: s == o) + + def __ge__(self, other): + return self._compare(other, lambda s, o: s >= o) + + def __gt__(self, other): + return self._compare(other, lambda s, o: s > o) + + def __ne__(self, other): + return self._compare(other, lambda s, o: s != o) + + def _compare(self, other, method): + if not isinstance(other, _BaseVersion): + return NotImplemented + + return method(self._key, other._key) + + +class LegacyVersion(_BaseVersion): + + def __init__(self, version): + self._version = str(version) + self._key = _legacy_cmpkey(self._version) + + def __str__(self): + return self._version + + def __repr__(self): + return "<LegacyVersion({0})>".format(repr(str(self))) + + @property + def public(self): + return self._version + + @property + def base_version(self): + return self._version + + @property + def local(self): + return None + + @property + def is_prerelease(self): + return False + + @property + def is_postrelease(self): + return False + + +_legacy_version_component_re = re.compile( + r"(\d+ | [a-z]+ | \.| -)", re.VERBOSE, +) + +_legacy_version_replacement_map = { + "pre": "c", "preview": "c", "-": "final-", "rc": "c", "dev": "@", +} + + +def _parse_version_parts(s): + for part in _legacy_version_component_re.split(s): + part = _legacy_version_replacement_map.get(part, part) + + if not part or part == ".": + continue + + if part[:1] in "0123456789": + # pad for numeric comparison + yield part.zfill(8) + else: + yield "*" + part + + # ensure that alpha/beta/candidate are before final + yield "*final" + + +def _legacy_cmpkey(version): + # We hardcode an epoch of -1 here. A PEP 440 version can only have a epoch + # greater than or equal to 0. This will effectively put the LegacyVersion, + # which uses the defacto standard originally implemented by setuptools, + # as before all PEP 440 versions. + epoch = -1 + + # This scheme is taken from pkg_resources.parse_version setuptools prior to + # it's adoption of the packaging library. + parts = [] + for part in _parse_version_parts(version.lower()): + if part.startswith("*"): + # remove "-" before a prerelease tag + if part < "*final": + while parts and parts[-1] == "*final-": + parts.pop() + + # remove trailing zeros from each series of numeric parts + while parts and parts[-1] == "00000000": + parts.pop() + + parts.append(part) + parts = tuple(parts) + + return epoch, parts + +# Deliberately not anchored to the start and end of the string, to make it +# easier for 3rd party code to reuse +VERSION_PATTERN = r""" + v? + (?: + (?:(?P<epoch>[0-9]+)!)? # epoch + (?P<release>[0-9]+(?:\.[0-9]+)*) # release segment + (?P<pre> # pre-release + [-_\.]? + (?P<pre_l>(a|b|c|rc|alpha|beta|pre|preview)) + [-_\.]? + (?P<pre_n>[0-9]+)? + )? + (?P<post> # post release + (?:-(?P<post_n1>[0-9]+)) + | + (?: + [-_\.]? + (?P<post_l>post|rev|r) + [-_\.]? + (?P<post_n2>[0-9]+)? + ) + )? + (?P<dev> # dev release + [-_\.]? + (?P<dev_l>dev) + [-_\.]? + (?P<dev_n>[0-9]+)? + )? + ) + (?:\+(?P<local>[a-z0-9]+(?:[-_\.][a-z0-9]+)*))? # local version +""" + + +class Version(_BaseVersion): + + _regex = re.compile( + r"^\s*" + VERSION_PATTERN + r"\s*$", + re.VERBOSE | re.IGNORECASE, + ) + + def __init__(self, version): + # Validate the version and parse it into pieces + match = self._regex.search(version) + if not match: + raise InvalidVersion("Invalid version: '{0}'".format(version)) + + # Store the parsed out pieces of the version + self._version = _Version( + epoch=int(match.group("epoch")) if match.group("epoch") else 0, + release=tuple(int(i) for i in match.group("release").split(".")), + pre=_parse_letter_version( + match.group("pre_l"), + match.group("pre_n"), + ), + post=_parse_letter_version( + match.group("post_l"), + match.group("post_n1") or match.group("post_n2"), + ), + dev=_parse_letter_version( + match.group("dev_l"), + match.group("dev_n"), + ), + local=_parse_local_version(match.group("local")), + ) + + # Generate a key which will be used for sorting + self._key = _cmpkey( + self._version.epoch, + self._version.release, + self._version.pre, + self._version.post, + self._version.dev, + self._version.local, + ) + + def __repr__(self): + return "<Version({0})>".format(repr(str(self))) + + def __str__(self): + parts = [] + + # Epoch + if self._version.epoch != 0: + parts.append("{0}!".format(self._version.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self._version.release)) + + # Pre-release + if self._version.pre is not None: + parts.append("".join(str(x) for x in self._version.pre)) + + # Post-release + if self._version.post is not None: + parts.append(".post{0}".format(self._version.post[1])) + + # Development release + if self._version.dev is not None: + parts.append(".dev{0}".format(self._version.dev[1])) + + # Local version segment + if self._version.local is not None: + parts.append( + "+{0}".format(".".join(str(x) for x in self._version.local)) + ) + + return "".join(parts) + + @property + def public(self): + return str(self).split("+", 1)[0] + + @property + def base_version(self): + parts = [] + + # Epoch + if self._version.epoch != 0: + parts.append("{0}!".format(self._version.epoch)) + + # Release segment + parts.append(".".join(str(x) for x in self._version.release)) + + return "".join(parts) + + @property + def local(self): + version_string = str(self) + if "+" in version_string: + return version_string.split("+", 1)[1] + + @property + def is_prerelease(self): + return bool(self._version.dev or self._version.pre) + + @property + def is_postrelease(self): + return bool(self._version.post) + + +def _parse_letter_version(letter, number): + if letter: + # We consider there to be an implicit 0 in a pre-release if there is + # not a numeral associated with it. + if number is None: + number = 0 + + # We normalize any letters to their lower case form + letter = letter.lower() + + # We consider some words to be alternate spellings of other words and + # in those cases we want to normalize the spellings to our preferred + # spelling. + if letter == "alpha": + letter = "a" + elif letter == "beta": + letter = "b" + elif letter in ["c", "pre", "preview"]: + letter = "rc" + elif letter in ["rev", "r"]: + letter = "post" + + return letter, int(number) + if not letter and number: + # We assume if we are given a number, but we are not given a letter + # then this is using the implicit post release syntax (e.g. 1.0-1) + letter = "post" + + return letter, int(number) + + +_local_version_seperators = re.compile(r"[\._-]") + + +def _parse_local_version(local): + """ + Takes a string like abc.1.twelve and turns it into ("abc", 1, "twelve"). + """ + if local is not None: + return tuple( + part.lower() if not part.isdigit() else int(part) + for part in _local_version_seperators.split(local) + ) + + +def _cmpkey(epoch, release, pre, post, dev, local): + # When we compare a release version, we want to compare it with all of the + # trailing zeros removed. So we'll use a reverse the list, drop all the now + # leading zeros until we come to something non zero, then take the rest + # re-reverse it back into the correct order and make it a tuple and use + # that for our sorting key. + release = tuple( + reversed(list( + itertools.dropwhile( + lambda x: x == 0, + reversed(release), + ) + )) + ) + + # We need to "trick" the sorting algorithm to put 1.0.dev0 before 1.0a0. + # We'll do this by abusing the pre segment, but we _only_ want to do this + # if there is not a pre or a post segment. If we have one of those then + # the normal sorting rules will handle this case correctly. + if pre is None and post is None and dev is not None: + pre = -Infinity + # Versions without a pre-release (except as noted above) should sort after + # those with one. + elif pre is None: + pre = Infinity + + # Versions without a post segment should sort before those with one. + if post is None: + post = -Infinity + + # Versions without a development segment should sort after those with one. + if dev is None: + dev = Infinity + + if local is None: + # Versions without a local segment should sort before those with one. + local = -Infinity + else: + # Versions with a local segment need that segment parsed to implement + # the sorting rules in PEP440. + # - Alpha numeric segments sort before numeric segments + # - Alpha numeric segments sort lexicographically + # - Numeric segments sort numerically + # - Shorter versions sort before longer versions when the prefixes + # match exactly + local = tuple( + (i, "") if isinstance(i, int) else (-Infinity, i) + for i in local + ) + + return epoch, release, pre, post, dev, local diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py b/env/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py new file mode 100644 index 0000000..cf75e1e --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/pyparsing.py @@ -0,0 +1,5742 @@ +# module pyparsing.py +# +# Copyright (c) 2003-2018 Paul T. McGuire +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# + +__doc__ = \ +""" +pyparsing module - Classes and methods to define and execute parsing grammars +============================================================================= + +The pyparsing module is an alternative approach to creating and executing simple grammars, +vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you +don't need to learn a new syntax for defining grammars or matching expressions - the parsing module +provides a library of classes that you use to construct the grammar directly in Python. + +Here is a program to parse "Hello, World!" (or any greeting of the form +C{"<salutation>, <addressee>!"}), built up using L{Word}, L{Literal}, and L{And} elements +(L{'+'<ParserElement.__add__>} operator gives L{And} expressions, strings are auto-converted to +L{Literal} expressions):: + + from pyparsing import Word, alphas + + # define grammar of a greeting + greet = Word(alphas) + "," + Word(alphas) + "!" + + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + +The program outputs the following:: + + Hello, World! -> ['Hello', ',', 'World', '!'] + +The Python representation of the grammar is quite readable, owing to the self-explanatory +class names, and the use of '+', '|' and '^' operators. + +The L{ParseResults} object returned from L{ParserElement.parseString<ParserElement.parseString>} can be accessed as a nested list, a dictionary, or an +object with named attributes. + +The pyparsing module handles some of the problems that are typically vexing when writing text parsers: + - extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.) + - quoted strings + - embedded comments + + +Getting Started - +----------------- +Visit the classes L{ParserElement} and L{ParseResults} to see the base classes that most other pyparsing +classes inherit from. Use the docstrings for examples of how to: + - construct literal match expressions from L{Literal} and L{CaselessLiteral} classes + - construct character word-group expressions using the L{Word} class + - see how to create repetitive expressions using L{ZeroOrMore} and L{OneOrMore} classes + - use L{'+'<And>}, L{'|'<MatchFirst>}, L{'^'<Or>}, and L{'&'<Each>} operators to combine simple expressions into more complex ones + - associate names with your parsed results using L{ParserElement.setResultsName} + - find some helpful expression short-cuts like L{delimitedList} and L{oneOf} + - find more useful common expressions in the L{pyparsing_common} namespace class +""" + +__version__ = "2.2.1" +__versionTime__ = "18 Sep 2018 00:49 UTC" +__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>" + +import string +from weakref import ref as wkref +import copy +import sys +import warnings +import re +import sre_constants +import collections +import pprint +import traceback +import types +from datetime import datetime + +try: + from _thread import RLock +except ImportError: + from threading import RLock + +try: + # Python 3 + from collections.abc import Iterable + from collections.abc import MutableMapping +except ImportError: + # Python 2.7 + from collections import Iterable + from collections import MutableMapping + +try: + from collections import OrderedDict as _OrderedDict +except ImportError: + try: + from ordereddict import OrderedDict as _OrderedDict + except ImportError: + _OrderedDict = None + +#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) ) + +__all__ = [ +'And', 'CaselessKeyword', 'CaselessLiteral', 'CharsNotIn', 'Combine', 'Dict', 'Each', 'Empty', +'FollowedBy', 'Forward', 'GoToColumn', 'Group', 'Keyword', 'LineEnd', 'LineStart', 'Literal', +'MatchFirst', 'NoMatch', 'NotAny', 'OneOrMore', 'OnlyOnce', 'Optional', 'Or', +'ParseBaseException', 'ParseElementEnhance', 'ParseException', 'ParseExpression', 'ParseFatalException', +'ParseResults', 'ParseSyntaxException', 'ParserElement', 'QuotedString', 'RecursiveGrammarException', +'Regex', 'SkipTo', 'StringEnd', 'StringStart', 'Suppress', 'Token', 'TokenConverter', +'White', 'Word', 'WordEnd', 'WordStart', 'ZeroOrMore', +'alphanums', 'alphas', 'alphas8bit', 'anyCloseTag', 'anyOpenTag', 'cStyleComment', 'col', +'commaSeparatedList', 'commonHTMLEntity', 'countedArray', 'cppStyleComment', 'dblQuotedString', +'dblSlashComment', 'delimitedList', 'dictOf', 'downcaseTokens', 'empty', 'hexnums', +'htmlComment', 'javaStyleComment', 'line', 'lineEnd', 'lineStart', 'lineno', +'makeHTMLTags', 'makeXMLTags', 'matchOnlyAtCol', 'matchPreviousExpr', 'matchPreviousLiteral', +'nestedExpr', 'nullDebugAction', 'nums', 'oneOf', 'opAssoc', 'operatorPrecedence', 'printables', +'punc8bit', 'pythonStyleComment', 'quotedString', 'removeQuotes', 'replaceHTMLEntity', +'replaceWith', 'restOfLine', 'sglQuotedString', 'srange', 'stringEnd', +'stringStart', 'traceParseAction', 'unicodeString', 'upcaseTokens', 'withAttribute', +'indentedBlock', 'originalTextFor', 'ungroup', 'infixNotation','locatedExpr', 'withClass', +'CloseMatch', 'tokenMap', 'pyparsing_common', +] + +system_version = tuple(sys.version_info)[:3] +PY_3 = system_version[0] == 3 +if PY_3: + _MAX_INT = sys.maxsize + basestring = str + unichr = chr + _ustr = str + + # build list of single arg builtins, that can be used as parse actions + singleArgBuiltins = [sum, len, sorted, reversed, list, tuple, set, any, all, min, max] + +else: + _MAX_INT = sys.maxint + range = xrange + + def _ustr(obj): + """Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries + str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It + then < returns the unicode object | encodes it with the default encoding | ... >. + """ + if isinstance(obj,unicode): + return obj + + try: + # If this works, then _ustr(obj) has the same behaviour as str(obj), so + # it won't break any existing code. + return str(obj) + + except UnicodeEncodeError: + # Else encode it + ret = unicode(obj).encode(sys.getdefaultencoding(), 'xmlcharrefreplace') + xmlcharref = Regex(r'&#\d+;') + xmlcharref.setParseAction(lambda t: '\\u' + hex(int(t[0][2:-1]))[2:]) + return xmlcharref.transformString(ret) + + # build list of single arg builtins, tolerant of Python version, that can be used as parse actions + singleArgBuiltins = [] + import __builtin__ + for fname in "sum len sorted reversed list tuple set any all min max".split(): + try: + singleArgBuiltins.append(getattr(__builtin__,fname)) + except AttributeError: + continue + +_generatorType = type((y for y in range(1))) + +def _xml_escape(data): + """Escape &, <, >, ", ', etc. in a string of data.""" + + # ampersand must be replaced first + from_symbols = '&><"\'' + to_symbols = ('&'+s+';' for s in "amp gt lt quot apos".split()) + for from_,to_ in zip(from_symbols, to_symbols): + data = data.replace(from_, to_) + return data + +class _Constants(object): + pass + +alphas = string.ascii_uppercase + string.ascii_lowercase +nums = "0123456789" +hexnums = nums + "ABCDEFabcdef" +alphanums = alphas + nums +_bslash = chr(92) +printables = "".join(c for c in string.printable if c not in string.whitespace) + +class ParseBaseException(Exception): + """base exception class for all parsing runtime exceptions""" + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, pstr, loc=0, msg=None, elem=None ): + self.loc = loc + if msg is None: + self.msg = pstr + self.pstr = "" + else: + self.msg = msg + self.pstr = pstr + self.parserElement = elem + self.args = (pstr, loc, msg) + + @classmethod + def _from_exception(cls, pe): + """ + internal factory method to simplify creating one type of ParseException + from another - avoids having __init__ signature conflicts among subclasses + """ + return cls(pe.pstr, pe.loc, pe.msg, pe.parserElement) + + def __getattr__( self, aname ): + """supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + """ + if( aname == "lineno" ): + return lineno( self.loc, self.pstr ) + elif( aname in ("col", "column") ): + return col( self.loc, self.pstr ) + elif( aname == "line" ): + return line( self.loc, self.pstr ) + else: + raise AttributeError(aname) + + def __str__( self ): + return "%s (at char %d), (line:%d, col:%d)" % \ + ( self.msg, self.loc, self.lineno, self.column ) + def __repr__( self ): + return _ustr(self) + def markInputline( self, markerString = ">!<" ): + """Extracts the exception line from the input string, and marks + the location of the exception with a special symbol. + """ + line_str = self.line + line_column = self.column - 1 + if markerString: + line_str = "".join((line_str[:line_column], + markerString, line_str[line_column:])) + return line_str.strip() + def __dir__(self): + return "lineno col line".split() + dir(type(self)) + +class ParseException(ParseBaseException): + """ + Exception thrown when parse expressions don't match class; + supported attributes by name are: + - lineno - returns the line number of the exception text + - col - returns the column number of the exception text + - line - returns the line containing the exception text + + Example:: + try: + Word(nums).setName("integer").parseString("ABC") + except ParseException as pe: + print(pe) + print("column: {}".format(pe.col)) + + prints:: + Expected integer (at char 0), (line:1, col:1) + column: 1 + """ + pass + +class ParseFatalException(ParseBaseException): + """user-throwable exception thrown when inconsistent parse content + is found; stops all parsing immediately""" + pass + +class ParseSyntaxException(ParseFatalException): + """just like L{ParseFatalException}, but thrown internally when an + L{ErrorStop<And._ErrorStop>} ('-' operator) indicates that parsing is to stop + immediately because an unbacktrackable syntax error has been found""" + pass + +#~ class ReparseException(ParseBaseException): + #~ """Experimental class - parse actions can raise this exception to cause + #~ pyparsing to reparse the input string: + #~ - with a modified input string, and/or + #~ - with a modified start location + #~ Set the values of the ReparseException in the constructor, and raise the + #~ exception in a parse action to cause pyparsing to use the new string/location. + #~ Setting the values as None causes no change to be made. + #~ """ + #~ def __init_( self, newstring, restartLoc ): + #~ self.newParseText = newstring + #~ self.reparseLoc = restartLoc + +class RecursiveGrammarException(Exception): + """exception thrown by L{ParserElement.validate} if the grammar could be improperly recursive""" + def __init__( self, parseElementList ): + self.parseElementTrace = parseElementList + + def __str__( self ): + return "RecursiveGrammarException: %s" % self.parseElementTrace + +class _ParseResultsWithOffset(object): + def __init__(self,p1,p2): + self.tup = (p1,p2) + def __getitem__(self,i): + return self.tup[i] + def __repr__(self): + return repr(self.tup[0]) + def setOffset(self,i): + self.tup = (self.tup[0],i) + +class ParseResults(object): + """ + Structured parse results, to provide multiple means of access to the parsed data: + - as a list (C{len(results)}) + - by list index (C{results[0], results[1]}, etc.) + - by attribute (C{results.<resultsName>} - see L{ParserElement.setResultsName}) + + Example:: + integer = Word(nums) + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + # equivalent form: + # date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + # parseString returns a ParseResults object + result = date_str.parseString("1999/12/31") + + def test(s, fn=repr): + print("%s -> %s" % (s, fn(eval(s)))) + test("list(result)") + test("result[0]") + test("result['month']") + test("result.day") + test("'month' in result") + test("'minutes' in result") + test("result.dump()", str) + prints:: + list(result) -> ['1999', '/', '12', '/', '31'] + result[0] -> '1999' + result['month'] -> '12' + result.day -> '31' + 'month' in result -> True + 'minutes' in result -> False + result.dump() -> ['1999', '/', '12', '/', '31'] + - day: 31 + - month: 12 + - year: 1999 + """ + def __new__(cls, toklist=None, name=None, asList=True, modal=True ): + if isinstance(toklist, cls): + return toklist + retobj = object.__new__(cls) + retobj.__doinit = True + return retobj + + # Performance tuning: we construct a *lot* of these, so keep this + # constructor as small and fast as possible + def __init__( self, toklist=None, name=None, asList=True, modal=True, isinstance=isinstance ): + if self.__doinit: + self.__doinit = False + self.__name = None + self.__parent = None + self.__accumNames = {} + self.__asList = asList + self.__modal = modal + if toklist is None: + toklist = [] + if isinstance(toklist, list): + self.__toklist = toklist[:] + elif isinstance(toklist, _generatorType): + self.__toklist = list(toklist) + else: + self.__toklist = [toklist] + self.__tokdict = dict() + + if name is not None and name: + if not modal: + self.__accumNames[name] = 0 + if isinstance(name,int): + name = _ustr(name) # will always return a str, but use _ustr for consistency + self.__name = name + if not (isinstance(toklist, (type(None), basestring, list)) and toklist in (None,'',[])): + if isinstance(toklist,basestring): + toklist = [ toklist ] + if asList: + if isinstance(toklist,ParseResults): + self[name] = _ParseResultsWithOffset(toklist.copy(),0) + else: + self[name] = _ParseResultsWithOffset(ParseResults(toklist[0]),0) + self[name].__name = name + else: + try: + self[name] = toklist[0] + except (KeyError,TypeError,IndexError): + self[name] = toklist + + def __getitem__( self, i ): + if isinstance( i, (int,slice) ): + return self.__toklist[i] + else: + if i not in self.__accumNames: + return self.__tokdict[i][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[i] ]) + + def __setitem__( self, k, v, isinstance=isinstance ): + if isinstance(v,_ParseResultsWithOffset): + self.__tokdict[k] = self.__tokdict.get(k,list()) + [v] + sub = v[0] + elif isinstance(k,(int,slice)): + self.__toklist[k] = v + sub = v + else: + self.__tokdict[k] = self.__tokdict.get(k,list()) + [_ParseResultsWithOffset(v,0)] + sub = v + if isinstance(sub,ParseResults): + sub.__parent = wkref(self) + + def __delitem__( self, i ): + if isinstance(i,(int,slice)): + mylen = len( self.__toklist ) + del self.__toklist[i] + + # convert int to slice + if isinstance(i, int): + if i < 0: + i += mylen + i = slice(i, i+1) + # get removed indices + removed = list(range(*i.indices(mylen))) + removed.reverse() + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for j in removed: + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position - (position > j)) + else: + del self.__tokdict[i] + + def __contains__( self, k ): + return k in self.__tokdict + + def __len__( self ): return len( self.__toklist ) + def __bool__(self): return ( not not self.__toklist ) + __nonzero__ = __bool__ + def __iter__( self ): return iter( self.__toklist ) + def __reversed__( self ): return iter( self.__toklist[::-1] ) + def _iterkeys( self ): + if hasattr(self.__tokdict, "iterkeys"): + return self.__tokdict.iterkeys() + else: + return iter(self.__tokdict) + + def _itervalues( self ): + return (self[k] for k in self._iterkeys()) + + def _iteritems( self ): + return ((k, self[k]) for k in self._iterkeys()) + + if PY_3: + keys = _iterkeys + """Returns an iterator of all named result keys (Python 3.x only).""" + + values = _itervalues + """Returns an iterator of all named result values (Python 3.x only).""" + + items = _iteritems + """Returns an iterator of all named result key-value tuples (Python 3.x only).""" + + else: + iterkeys = _iterkeys + """Returns an iterator of all named result keys (Python 2.x only).""" + + itervalues = _itervalues + """Returns an iterator of all named result values (Python 2.x only).""" + + iteritems = _iteritems + """Returns an iterator of all named result key-value tuples (Python 2.x only).""" + + def keys( self ): + """Returns all named result keys (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iterkeys()) + + def values( self ): + """Returns all named result values (as a list in Python 2.x, as an iterator in Python 3.x).""" + return list(self.itervalues()) + + def items( self ): + """Returns all named result key-values (as a list of tuples in Python 2.x, as an iterator in Python 3.x).""" + return list(self.iteritems()) + + def haskeys( self ): + """Since keys() returns an iterator, this method is helpful in bypassing + code that looks for the existence of any defined results names.""" + return bool(self.__tokdict) + + def pop( self, *args, **kwargs): + """ + Removes and returns item at specified index (default=C{last}). + Supports both C{list} and C{dict} semantics for C{pop()}. If passed no + argument or an integer argument, it will use C{list} semantics + and pop tokens from the list of parsed tokens. If passed a + non-integer argument (most likely a string), it will use C{dict} + semantics and pop the corresponding value from any defined + results names. A second default return value argument is + supported, just as in C{dict.pop()}. + + Example:: + def remove_first(tokens): + tokens.pop(0) + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + print(OneOrMore(Word(nums)).addParseAction(remove_first).parseString("0 123 321")) # -> ['123', '321'] + + label = Word(alphas) + patt = label("LABEL") + OneOrMore(Word(nums)) + print(patt.parseString("AAB 123 321").dump()) + + # Use pop() in a parse action to remove named result (note that corresponding value is not + # removed from list form of results) + def remove_LABEL(tokens): + tokens.pop("LABEL") + return tokens + patt.addParseAction(remove_LABEL) + print(patt.parseString("AAB 123 321").dump()) + prints:: + ['AAB', '123', '321'] + - LABEL: AAB + + ['AAB', '123', '321'] + """ + if not args: + args = [-1] + for k,v in kwargs.items(): + if k == 'default': + args = (args[0], v) + else: + raise TypeError("pop() got an unexpected keyword argument '%s'" % k) + if (isinstance(args[0], int) or + len(args) == 1 or + args[0] in self): + index = args[0] + ret = self[index] + del self[index] + return ret + else: + defaultvalue = args[1] + return defaultvalue + + def get(self, key, defaultValue=None): + """ + Returns named result matching the given key, or if there is no + such name, then returns the given C{defaultValue} or C{None} if no + C{defaultValue} is specified. + + Similar to C{dict.get()}. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString("1999/12/31") + print(result.get("year")) # -> '1999' + print(result.get("hour", "not specified")) # -> 'not specified' + print(result.get("hour")) # -> None + """ + if key in self: + return self[key] + else: + return defaultValue + + def insert( self, index, insStr ): + """ + Inserts new element at location index in the list of parsed tokens. + + Similar to C{list.insert()}. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to insert the parse location in the front of the parsed results + def insert_locn(locn, tokens): + tokens.insert(0, locn) + print(OneOrMore(Word(nums)).addParseAction(insert_locn).parseString("0 123 321")) # -> [0, '0', '123', '321'] + """ + self.__toklist.insert(index, insStr) + # fixup indices in token dictionary + for name,occurrences in self.__tokdict.items(): + for k, (value, position) in enumerate(occurrences): + occurrences[k] = _ParseResultsWithOffset(value, position + (position > index)) + + def append( self, item ): + """ + Add single element to end of ParseResults list of elements. + + Example:: + print(OneOrMore(Word(nums)).parseString("0 123 321")) # -> ['0', '123', '321'] + + # use a parse action to compute the sum of the parsed integers, and add it to the end + def append_sum(tokens): + tokens.append(sum(map(int, tokens))) + print(OneOrMore(Word(nums)).addParseAction(append_sum).parseString("0 123 321")) # -> ['0', '123', '321', 444] + """ + self.__toklist.append(item) + + def extend( self, itemseq ): + """ + Add sequence of elements to end of ParseResults list of elements. + + Example:: + patt = OneOrMore(Word(alphas)) + + # use a parse action to append the reverse of the matched strings, to make a palindrome + def make_palindrome(tokens): + tokens.extend(reversed([t[::-1] for t in tokens])) + return ''.join(tokens) + print(patt.addParseAction(make_palindrome).parseString("lskdj sdlkjf lksd")) # -> 'lskdjsdlkjflksddsklfjkldsjdksl' + """ + if isinstance(itemseq, ParseResults): + self += itemseq + else: + self.__toklist.extend(itemseq) + + def clear( self ): + """ + Clear all elements and results names. + """ + del self.__toklist[:] + self.__tokdict.clear() + + def __getattr__( self, name ): + try: + return self[name] + except KeyError: + return "" + + if name in self.__tokdict: + if name not in self.__accumNames: + return self.__tokdict[name][-1][0] + else: + return ParseResults([ v[0] for v in self.__tokdict[name] ]) + else: + return "" + + def __add__( self, other ): + ret = self.copy() + ret += other + return ret + + def __iadd__( self, other ): + if other.__tokdict: + offset = len(self.__toklist) + addoffset = lambda a: offset if a<0 else a+offset + otheritems = other.__tokdict.items() + otherdictitems = [(k, _ParseResultsWithOffset(v[0],addoffset(v[1])) ) + for (k,vlist) in otheritems for v in vlist] + for k,v in otherdictitems: + self[k] = v + if isinstance(v[0],ParseResults): + v[0].__parent = wkref(self) + + self.__toklist += other.__toklist + self.__accumNames.update( other.__accumNames ) + return self + + def __radd__(self, other): + if isinstance(other,int) and other == 0: + # useful for merging many ParseResults using sum() builtin + return self.copy() + else: + # this may raise a TypeError - so be it + return other + self + + def __repr__( self ): + return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) ) + + def __str__( self ): + return '[' + ', '.join(_ustr(i) if isinstance(i, ParseResults) else repr(i) for i in self.__toklist) + ']' + + def _asStringList( self, sep='' ): + out = [] + for item in self.__toklist: + if out and sep: + out.append(sep) + if isinstance( item, ParseResults ): + out += item._asStringList() + else: + out.append( _ustr(item) ) + return out + + def asList( self ): + """ + Returns the parse results as a nested list of matching tokens, all converted to strings. + + Example:: + patt = OneOrMore(Word(alphas)) + result = patt.parseString("sldkj lsdkj sldkj") + # even though the result prints in string-like form, it is actually a pyparsing ParseResults + print(type(result), result) # -> <class 'pyparsing.ParseResults'> ['sldkj', 'lsdkj', 'sldkj'] + + # Use asList() to create an actual list + result_list = result.asList() + print(type(result_list), result_list) # -> <class 'list'> ['sldkj', 'lsdkj', 'sldkj'] + """ + return [res.asList() if isinstance(res,ParseResults) else res for res in self.__toklist] + + def asDict( self ): + """ + Returns the named parse results as a nested dictionary. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(type(result), repr(result)) # -> <class 'pyparsing.ParseResults'> (['12', '/', '31', '/', '1999'], {'day': [('1999', 4)], 'year': [('12', 0)], 'month': [('31', 2)]}) + + result_dict = result.asDict() + print(type(result_dict), repr(result_dict)) # -> <class 'dict'> {'day': '1999', 'year': '12', 'month': '31'} + + # even though a ParseResults supports dict-like access, sometime you just need to have a dict + import json + print(json.dumps(result)) # -> Exception: TypeError: ... is not JSON serializable + print(json.dumps(result.asDict())) # -> {"month": "31", "day": "1999", "year": "12"} + """ + if PY_3: + item_fn = self.items + else: + item_fn = self.iteritems + + def toItem(obj): + if isinstance(obj, ParseResults): + if obj.haskeys(): + return obj.asDict() + else: + return [toItem(v) for v in obj] + else: + return obj + + return dict((k,toItem(v)) for k,v in item_fn()) + + def copy( self ): + """ + Returns a new copy of a C{ParseResults} object. + """ + ret = ParseResults( self.__toklist ) + ret.__tokdict = self.__tokdict.copy() + ret.__parent = self.__parent + ret.__accumNames.update( self.__accumNames ) + ret.__name = self.__name + return ret + + def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ): + """ + (Deprecated) Returns the parse results as XML. Tags are created for tokens and lists that have defined results names. + """ + nl = "\n" + out = [] + namedItems = dict((v[1],k) for (k,vlist) in self.__tokdict.items() + for v in vlist) + nextLevelIndent = indent + " " + + # collapse out indents if formatting is not desired + if not formatted: + indent = "" + nextLevelIndent = "" + nl = "" + + selfTag = None + if doctag is not None: + selfTag = doctag + else: + if self.__name: + selfTag = self.__name + + if not selfTag: + if namedItemsOnly: + return "" + else: + selfTag = "ITEM" + + out += [ nl, indent, "<", selfTag, ">" ] + + for i,res in enumerate(self.__toklist): + if isinstance(res,ParseResults): + if i in namedItems: + out += [ res.asXML(namedItems[i], + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + out += [ res.asXML(None, + namedItemsOnly and doctag is None, + nextLevelIndent, + formatted)] + else: + # individual token, see if there is a name for it + resTag = None + if i in namedItems: + resTag = namedItems[i] + if not resTag: + if namedItemsOnly: + continue + else: + resTag = "ITEM" + xmlBodyText = _xml_escape(_ustr(res)) + out += [ nl, nextLevelIndent, "<", resTag, ">", + xmlBodyText, + "</", resTag, ">" ] + + out += [ nl, indent, "</", selfTag, ">" ] + return "".join(out) + + def __lookup(self,sub): + for k,vlist in self.__tokdict.items(): + for v,loc in vlist: + if sub is v: + return k + return None + + def getName(self): + r""" + Returns the results name for this token expression. Useful when several + different expressions might match at a particular location. + + Example:: + integer = Word(nums) + ssn_expr = Regex(r"\d\d\d-\d\d-\d\d\d\d") + house_number_expr = Suppress('#') + Word(nums, alphanums) + user_data = (Group(house_number_expr)("house_number") + | Group(ssn_expr)("ssn") + | Group(integer)("age")) + user_info = OneOrMore(user_data) + + result = user_info.parseString("22 111-22-3333 #221B") + for item in result: + print(item.getName(), ':', item[0]) + prints:: + age : 22 + ssn : 111-22-3333 + house_number : 221B + """ + if self.__name: + return self.__name + elif self.__parent: + par = self.__parent() + if par: + return par.__lookup(self) + else: + return None + elif (len(self) == 1 and + len(self.__tokdict) == 1 and + next(iter(self.__tokdict.values()))[0][1] in (0,-1)): + return next(iter(self.__tokdict.keys())) + else: + return None + + def dump(self, indent='', depth=0, full=True): + """ + Diagnostic method for listing out the contents of a C{ParseResults}. + Accepts an optional C{indent} argument so that this string can be embedded + in a nested display of other data. + + Example:: + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + result = date_str.parseString('12/31/1999') + print(result.dump()) + prints:: + ['12', '/', '31', '/', '1999'] + - day: 1999 + - month: 31 + - year: 12 + """ + out = [] + NL = '\n' + out.append( indent+_ustr(self.asList()) ) + if full: + if self.haskeys(): + items = sorted((str(k), v) for k,v in self.items()) + for k,v in items: + if out: + out.append(NL) + out.append( "%s%s- %s: " % (indent,(' '*depth), k) ) + if isinstance(v,ParseResults): + if v: + out.append( v.dump(indent,depth+1) ) + else: + out.append(_ustr(v)) + else: + out.append(repr(v)) + elif any(isinstance(vv,ParseResults) for vv in self): + v = self + for i,vv in enumerate(v): + if isinstance(vv,ParseResults): + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),vv.dump(indent,depth+1) )) + else: + out.append("\n%s%s[%d]:\n%s%s%s" % (indent,(' '*(depth)),i,indent,(' '*(depth+1)),_ustr(vv))) + + return "".join(out) + + def pprint(self, *args, **kwargs): + """ + Pretty-printer for parsed results as a list, using the C{pprint} module. + Accepts additional positional or keyword args as defined for the + C{pprint.pprint} method. (U{http://docs.python.org/3/library/pprint.html#pprint.pprint}) + + Example:: + ident = Word(alphas, alphanums) + num = Word(nums) + func = Forward() + term = ident | num | Group('(' + func + ')') + func <<= ident + Group(Optional(delimitedList(term))) + result = func.parseString("fna a,b,(fnb c,d,200),100") + result.pprint(width=40) + prints:: + ['fna', + ['a', + 'b', + ['(', 'fnb', ['c', 'd', '200'], ')'], + '100']] + """ + pprint.pprint(self.asList(), *args, **kwargs) + + # add support for pickle protocol + def __getstate__(self): + return ( self.__toklist, + ( self.__tokdict.copy(), + self.__parent is not None and self.__parent() or None, + self.__accumNames, + self.__name ) ) + + def __setstate__(self,state): + self.__toklist = state[0] + (self.__tokdict, + par, + inAccumNames, + self.__name) = state[1] + self.__accumNames = {} + self.__accumNames.update(inAccumNames) + if par is not None: + self.__parent = wkref(par) + else: + self.__parent = None + + def __getnewargs__(self): + return self.__toklist, self.__name, self.__asList, self.__modal + + def __dir__(self): + return (dir(type(self)) + list(self.keys())) + +MutableMapping.register(ParseResults) + +def col (loc,strg): + """Returns current column within a string, counting newlines as line separators. + The first column is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + s = strg + return 1 if 0<loc<len(s) and s[loc-1] == '\n' else loc - s.rfind("\n", 0, loc) + +def lineno(loc,strg): + """Returns current line number within a string, counting newlines as line separators. + The first line is number 1. + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{ParserElement.parseString}<ParserElement.parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + """ + return strg.count("\n",0,loc) + 1 + +def line( loc, strg ): + """Returns the line of text containing loc within a string, counting newlines as line separators. + """ + lastCR = strg.rfind("\n", 0, loc) + nextCR = strg.find("\n", loc) + if nextCR >= 0: + return strg[lastCR+1:nextCR] + else: + return strg[lastCR+1:] + +def _defaultStartDebugAction( instring, loc, expr ): + print (("Match " + _ustr(expr) + " at loc " + _ustr(loc) + "(%d,%d)" % ( lineno(loc,instring), col(loc,instring) ))) + +def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ): + print ("Matched " + _ustr(expr) + " -> " + str(toks.asList())) + +def _defaultExceptionDebugAction( instring, loc, expr, exc ): + print ("Exception raised:" + _ustr(exc)) + +def nullDebugAction(*args): + """'Do-nothing' debug action, to suppress debugging output during parsing.""" + pass + +# Only works on Python 3.x - nonlocal is toxic to Python 2 installs +#~ 'decorator to trim function calls to match the arity of the target' +#~ def _trim_arity(func, maxargs=3): + #~ if func in singleArgBuiltins: + #~ return lambda s,l,t: func(t) + #~ limit = 0 + #~ foundArity = False + #~ def wrapper(*args): + #~ nonlocal limit,foundArity + #~ while 1: + #~ try: + #~ ret = func(*args[limit:]) + #~ foundArity = True + #~ return ret + #~ except TypeError: + #~ if limit == maxargs or foundArity: + #~ raise + #~ limit += 1 + #~ continue + #~ return wrapper + +# this version is Python 2.x-3.x cross-compatible +'decorator to trim function calls to match the arity of the target' +def _trim_arity(func, maxargs=2): + if func in singleArgBuiltins: + return lambda s,l,t: func(t) + limit = [0] + foundArity = [False] + + # traceback return data structure changed in Py3.5 - normalize back to plain tuples + if system_version[:2] >= (3,5): + def extract_stack(limit=0): + # special handling for Python 3.5.0 - extra deep call stack by 1 + offset = -3 if system_version == (3,5,0) else -2 + frame_summary = traceback.extract_stack(limit=-offset+limit-1)[offset] + return [frame_summary[:2]] + def extract_tb(tb, limit=0): + frames = traceback.extract_tb(tb, limit=limit) + frame_summary = frames[-1] + return [frame_summary[:2]] + else: + extract_stack = traceback.extract_stack + extract_tb = traceback.extract_tb + + # synthesize what would be returned by traceback.extract_stack at the call to + # user's parse action 'func', so that we don't incur call penalty at parse time + + LINE_DIFF = 6 + # IF ANY CODE CHANGES, EVEN JUST COMMENTS OR BLANK LINES, BETWEEN THE NEXT LINE AND + # THE CALL TO FUNC INSIDE WRAPPER, LINE_DIFF MUST BE MODIFIED!!!! + this_line = extract_stack(limit=2)[-1] + pa_call_line_synth = (this_line[0], this_line[1]+LINE_DIFF) + + def wrapper(*args): + while 1: + try: + ret = func(*args[limit[0]:]) + foundArity[0] = True + return ret + except TypeError: + # re-raise TypeErrors if they did not come from our arity testing + if foundArity[0]: + raise + else: + try: + tb = sys.exc_info()[-1] + if not extract_tb(tb, limit=2)[-1][:2] == pa_call_line_synth: + raise + finally: + del tb + + if limit[0] <= maxargs: + limit[0] += 1 + continue + raise + + # copy func name to wrapper for sensible debug output + func_name = "<parse action>" + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + wrapper.__name__ = func_name + + return wrapper + +class ParserElement(object): + """Abstract base level parser element class.""" + DEFAULT_WHITE_CHARS = " \n\t\r" + verbose_stacktrace = False + + @staticmethod + def setDefaultWhitespaceChars( chars ): + r""" + Overrides the default whitespace chars + + Example:: + # default whitespace chars are space, <TAB> and newline + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def', 'ghi', 'jkl'] + + # change to just treat newline as significant + ParserElement.setDefaultWhitespaceChars(" \t") + OneOrMore(Word(alphas)).parseString("abc def\nghi jkl") # -> ['abc', 'def'] + """ + ParserElement.DEFAULT_WHITE_CHARS = chars + + @staticmethod + def inlineLiteralsUsing(cls): + """ + Set class to be used for inclusion of string literals into a parser. + + Example:: + # default literal class used is Literal + integer = Word(nums) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + + # change to Suppress + ParserElement.inlineLiteralsUsing(Suppress) + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + + date_str.parseString("1999/12/31") # -> ['1999', '12', '31'] + """ + ParserElement._literalStringClass = cls + + def __init__( self, savelist=False ): + self.parseAction = list() + self.failAction = None + #~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall + self.strRepr = None + self.resultsName = None + self.saveAsList = savelist + self.skipWhitespace = True + self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + self.copyDefaultWhiteChars = True + self.mayReturnEmpty = False # used when checking for left-recursion + self.keepTabs = False + self.ignoreExprs = list() + self.debug = False + self.streamlined = False + self.mayIndexError = True # used to optimize exception handling for subclasses that don't advance parse index + self.errmsg = "" + self.modalResults = True # used to mark results names as modal (report only last) or cumulative (list all) + self.debugActions = ( None, None, None ) #custom debug actions + self.re = None + self.callPreparse = True # used to avoid redundant calls to preParse + self.callDuringTry = False + + def copy( self ): + """ + Make a copy of this C{ParserElement}. Useful for defining different parse actions + for the same parsing pattern, using copies of the original parse element. + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + integerK = integer.copy().addParseAction(lambda toks: toks[0]*1024) + Suppress("K") + integerM = integer.copy().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + + print(OneOrMore(integerK | integerM | integer).parseString("5K 100 640K 256M")) + prints:: + [5120, 100, 655360, 268435456] + Equivalent form of C{expr.copy()} is just C{expr()}:: + integerM = integer().addParseAction(lambda toks: toks[0]*1024*1024) + Suppress("M") + """ + cpy = copy.copy( self ) + cpy.parseAction = self.parseAction[:] + cpy.ignoreExprs = self.ignoreExprs[:] + if self.copyDefaultWhiteChars: + cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS + return cpy + + def setName( self, name ): + """ + Define name for this expression, makes debugging and exception messages clearer. + + Example:: + Word(nums).parseString("ABC") # -> Exception: Expected W:(0123...) (at char 0), (line:1, col:1) + Word(nums).setName("integer").parseString("ABC") # -> Exception: Expected integer (at char 0), (line:1, col:1) + """ + self.name = name + self.errmsg = "Expected " + self.name + if hasattr(self,"exception"): + self.exception.msg = self.errmsg + return self + + def setResultsName( self, name, listAllMatches=False ): + """ + Define name for referencing matching tokens as a nested attribute + of the returned parse results. + NOTE: this returns a *copy* of the original C{ParserElement} object; + this is so that the client can define a basic element, such as an + integer, and reference it in multiple places with different names. + + You can also set results names using the abbreviated syntax, + C{expr("name")} in place of C{expr.setResultsName("name")} - + see L{I{__call__}<__call__>}. + + Example:: + date_str = (integer.setResultsName("year") + '/' + + integer.setResultsName("month") + '/' + + integer.setResultsName("day")) + + # equivalent form: + date_str = integer("year") + '/' + integer("month") + '/' + integer("day") + """ + newself = self.copy() + if name.endswith("*"): + name = name[:-1] + listAllMatches=True + newself.resultsName = name + newself.modalResults = not listAllMatches + return newself + + def setBreak(self,breakFlag = True): + """Method to invoke the Python pdb debugger when this element is + about to be parsed. Set C{breakFlag} to True to enable, False to + disable. + """ + if breakFlag: + _parseMethod = self._parse + def breaker(instring, loc, doActions=True, callPreParse=True): + import pdb + pdb.set_trace() + return _parseMethod( instring, loc, doActions, callPreParse ) + breaker._originalParseMethod = _parseMethod + self._parse = breaker + else: + if hasattr(self._parse,"_originalParseMethod"): + self._parse = self._parse._originalParseMethod + return self + + def setParseAction( self, *fns, **kwargs ): + """ + Define one or more actions to perform when successfully matching parse element definition. + Parse action fn is a callable method with 0-3 arguments, called as C{fn(s,loc,toks)}, + C{fn(loc,toks)}, C{fn(toks)}, or just C{fn()}, where: + - s = the original string being parsed (see note below) + - loc = the location of the matching substring + - toks = a list of the matched tokens, packaged as a C{L{ParseResults}} object + If the functions in fns modify the tokens, they can return them as the return + value from fn, and the modified list of tokens will replace the original. + Otherwise, fn does not need to return any value. + + Optional keyword arguments: + - callDuringTry = (default=C{False}) indicate if parse action should be run during lookaheads and alternate testing + + Note: the default parsing behavior is to expand tabs in the input string + before starting the parsing process. See L{I{parseString}<parseString>} for more information + on parsing strings containing C{<TAB>}s, and suggested methods to maintain a + consistent view of the parsed string, the parse location, and line and column + positions within the parsed string. + + Example:: + integer = Word(nums) + date_str = integer + '/' + integer + '/' + integer + + date_str.parseString("1999/12/31") # -> ['1999', '/', '12', '/', '31'] + + # use parse action to convert to ints at parse time + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + date_str = integer + '/' + integer + '/' + integer + + # note that integer fields are now ints, not strings + date_str.parseString("1999/12/31") # -> [1999, '/', 12, '/', 31] + """ + self.parseAction = list(map(_trim_arity, list(fns))) + self.callDuringTry = kwargs.get("callDuringTry", False) + return self + + def addParseAction( self, *fns, **kwargs ): + """ + Add one or more parse actions to expression's list of parse actions. See L{I{setParseAction}<setParseAction>}. + + See examples in L{I{copy}<copy>}. + """ + self.parseAction += list(map(_trim_arity, list(fns))) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def addCondition(self, *fns, **kwargs): + """Add a boolean predicate function to expression's list of parse actions. See + L{I{setParseAction}<setParseAction>} for function call signatures. Unlike C{setParseAction}, + functions passed to C{addCondition} need to return boolean success/fail of the condition. + + Optional keyword arguments: + - message = define a custom message to be used in the raised exception + - fatal = if True, will raise ParseFatalException to stop parsing immediately; otherwise will raise ParseException + + Example:: + integer = Word(nums).setParseAction(lambda toks: int(toks[0])) + year_int = integer.copy() + year_int.addCondition(lambda toks: toks[0] >= 2000, message="Only support years 2000 and later") + date_str = year_int + '/' + integer + '/' + integer + + result = date_str.parseString("1999/12/31") # -> Exception: Only support years 2000 and later (at char 0), (line:1, col:1) + """ + msg = kwargs.get("message", "failed user-defined condition") + exc_type = ParseFatalException if kwargs.get("fatal", False) else ParseException + for fn in fns: + def pa(s,l,t): + if not bool(_trim_arity(fn)(s,l,t)): + raise exc_type(s,l,msg) + self.parseAction.append(pa) + self.callDuringTry = self.callDuringTry or kwargs.get("callDuringTry", False) + return self + + def setFailAction( self, fn ): + """Define action to perform if parsing fails at this expression. + Fail acton fn is a callable function that takes the arguments + C{fn(s,loc,expr,err)} where: + - s = string being parsed + - loc = location where expression match was attempted and failed + - expr = the parse expression that failed + - err = the exception thrown + The function returns no value. It may throw C{L{ParseFatalException}} + if it is desired to stop parsing immediately.""" + self.failAction = fn + return self + + def _skipIgnorables( self, instring, loc ): + exprsFound = True + while exprsFound: + exprsFound = False + for e in self.ignoreExprs: + try: + while 1: + loc,dummy = e._parse( instring, loc ) + exprsFound = True + except ParseException: + pass + return loc + + def preParse( self, instring, loc ): + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + + if self.skipWhitespace: + wt = self.whiteChars + instrlen = len(instring) + while loc < instrlen and instring[loc] in wt: + loc += 1 + + return loc + + def parseImpl( self, instring, loc, doActions=True ): + return loc, [] + + def postParse( self, instring, loc, tokenlist ): + return tokenlist + + #~ @profile + def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ): + debugging = ( self.debug ) #and doActions ) + + if debugging or self.failAction: + #~ print ("Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )) + if (self.debugActions[0] ): + self.debugActions[0]( instring, loc, self ) + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + try: + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + except ParseBaseException as err: + #~ print ("Exception raised:", err) + if self.debugActions[2]: + self.debugActions[2]( instring, tokensStart, self, err ) + if self.failAction: + self.failAction( instring, tokensStart, self, err ) + raise + else: + if callPreParse and self.callPreparse: + preloc = self.preParse( instring, loc ) + else: + preloc = loc + tokensStart = preloc + if self.mayIndexError or preloc >= len(instring): + try: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + except IndexError: + raise ParseException( instring, len(instring), self.errmsg, self ) + else: + loc,tokens = self.parseImpl( instring, preloc, doActions ) + + tokens = self.postParse( instring, loc, tokens ) + + retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults ) + if self.parseAction and (doActions or self.callDuringTry): + if debugging: + try: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + except ParseBaseException as err: + #~ print "Exception raised in user parse action:", err + if (self.debugActions[2] ): + self.debugActions[2]( instring, tokensStart, self, err ) + raise + else: + for fn in self.parseAction: + tokens = fn( instring, tokensStart, retTokens ) + if tokens is not None: + retTokens = ParseResults( tokens, + self.resultsName, + asList=self.saveAsList and isinstance(tokens,(ParseResults,list)), + modal=self.modalResults ) + if debugging: + #~ print ("Matched",self,"->",retTokens.asList()) + if (self.debugActions[1] ): + self.debugActions[1]( instring, tokensStart, loc, self, retTokens ) + + return loc, retTokens + + def tryParse( self, instring, loc ): + try: + return self._parse( instring, loc, doActions=False )[0] + except ParseFatalException: + raise ParseException( instring, loc, self.errmsg, self) + + def canParseNext(self, instring, loc): + try: + self.tryParse(instring, loc) + except (ParseException, IndexError): + return False + else: + return True + + class _UnboundedCache(object): + def __init__(self): + cache = {} + self.not_in_cache = not_in_cache = object() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + if _OrderedDict is not None: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = _OrderedDict() + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(cache) > size: + try: + cache.popitem(False) + except KeyError: + pass + + def clear(self): + cache.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + else: + class _FifoCache(object): + def __init__(self, size): + self.not_in_cache = not_in_cache = object() + + cache = {} + key_fifo = collections.deque([], size) + + def get(self, key): + return cache.get(key, not_in_cache) + + def set(self, key, value): + cache[key] = value + while len(key_fifo) > size: + cache.pop(key_fifo.popleft(), None) + key_fifo.append(key) + + def clear(self): + cache.clear() + key_fifo.clear() + + def cache_len(self): + return len(cache) + + self.get = types.MethodType(get, self) + self.set = types.MethodType(set, self) + self.clear = types.MethodType(clear, self) + self.__len__ = types.MethodType(cache_len, self) + + # argument cache for optimizing repeated calls when backtracking through recursive expressions + packrat_cache = {} # this is set later by enabledPackrat(); this is here so that resetCache() doesn't fail + packrat_cache_lock = RLock() + packrat_cache_stats = [0, 0] + + # this method gets repeatedly called during backtracking with the same arguments - + # we can cache these arguments and save ourselves the trouble of re-parsing the contained expression + def _parseCache( self, instring, loc, doActions=True, callPreParse=True ): + HIT, MISS = 0, 1 + lookup = (self, instring, loc, callPreParse, doActions) + with ParserElement.packrat_cache_lock: + cache = ParserElement.packrat_cache + value = cache.get(lookup) + if value is cache.not_in_cache: + ParserElement.packrat_cache_stats[MISS] += 1 + try: + value = self._parseNoCache(instring, loc, doActions, callPreParse) + except ParseBaseException as pe: + # cache a copy of the exception, without the traceback + cache.set(lookup, pe.__class__(*pe.args)) + raise + else: + cache.set(lookup, (value[0], value[1].copy())) + return value + else: + ParserElement.packrat_cache_stats[HIT] += 1 + if isinstance(value, Exception): + raise value + return (value[0], value[1].copy()) + + _parse = _parseNoCache + + @staticmethod + def resetCache(): + ParserElement.packrat_cache.clear() + ParserElement.packrat_cache_stats[:] = [0] * len(ParserElement.packrat_cache_stats) + + _packratEnabled = False + @staticmethod + def enablePackrat(cache_size_limit=128): + """Enables "packrat" parsing, which adds memoizing to the parsing logic. + Repeated parse attempts at the same string location (which happens + often in many complex grammars) can immediately return a cached value, + instead of re-executing parsing/validating code. Memoizing is done of + both valid results and parsing exceptions. + + Parameters: + - cache_size_limit - (default=C{128}) - if an integer value is provided + will limit the size of the packrat cache; if None is passed, then + the cache size will be unbounded; if 0 is passed, the cache will + be effectively disabled. + + This speedup may break existing programs that use parse actions that + have side-effects. For this reason, packrat parsing is disabled when + you first import pyparsing. To activate the packrat feature, your + program must call the class method C{ParserElement.enablePackrat()}. If + your program uses C{psyco} to "compile as you go", you must call + C{enablePackrat} before calling C{psyco.full()}. If you do not do this, + Python will crash. For best results, call C{enablePackrat()} immediately + after importing pyparsing. + + Example:: + import pyparsing + pyparsing.ParserElement.enablePackrat() + """ + if not ParserElement._packratEnabled: + ParserElement._packratEnabled = True + if cache_size_limit is None: + ParserElement.packrat_cache = ParserElement._UnboundedCache() + else: + ParserElement.packrat_cache = ParserElement._FifoCache(cache_size_limit) + ParserElement._parse = ParserElement._parseCache + + def parseString( self, instring, parseAll=False ): + """ + Execute the parse expression with the given string. + This is the main interface to the client code, once the complete + expression has been built. + + If you want the grammar to require that the entire input string be + successfully parsed, then set C{parseAll} to True (equivalent to ending + the grammar with C{L{StringEnd()}}). + + Note: C{parseString} implicitly calls C{expandtabs()} on the input string, + in order to report proper column numbers in parse actions. + If the input string contains tabs and + the grammar uses parse actions that use the C{loc} argument to index into the + string being parsed, you can ensure you have a consistent view of the input + string by: + - calling C{parseWithTabs} on your grammar before calling C{parseString} + (see L{I{parseWithTabs}<parseWithTabs>}) + - define your parse action using the full C{(s,loc,toks)} signature, and + reference the input string using the parse action's C{s} argument + - explictly expand the tabs in your input string before calling + C{parseString} + + Example:: + Word('a').parseString('aaaaabaaa') # -> ['aaaaa'] + Word('a').parseString('aaaaabaaa', parseAll=True) # -> Exception: Expected end of text + """ + ParserElement.resetCache() + if not self.streamlined: + self.streamline() + #~ self.saveAsList = True + for e in self.ignoreExprs: + e.streamline() + if not self.keepTabs: + instring = instring.expandtabs() + try: + loc, tokens = self._parse( instring, 0 ) + if parseAll: + loc = self.preParse( instring, loc ) + se = Empty() + StringEnd() + se._parse( instring, loc ) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + else: + return tokens + + def scanString( self, instring, maxMatches=_MAX_INT, overlap=False ): + """ + Scan the input string for expression matches. Each match will return the + matching tokens, start location, and end location. May be called with optional + C{maxMatches} argument, to clip scanning after 'n' matches are found. If + C{overlap} is specified, then overlapping matches will be reported. + + Note that the start and end locations are reported relative to the string + being parsed. See L{I{parseString}<parseString>} for more information on parsing + strings with embedded tabs. + + Example:: + source = "sldjf123lsdjjkf345sldkjf879lkjsfd987" + print(source) + for tokens,start,end in Word(alphas).scanString(source): + print(' '*start + '^'*(end-start)) + print(' '*start + tokens[0]) + + prints:: + + sldjf123lsdjjkf345sldkjf879lkjsfd987 + ^^^^^ + sldjf + ^^^^^^^ + lsdjjkf + ^^^^^^ + sldkjf + ^^^^^^ + lkjsfd + """ + if not self.streamlined: + self.streamline() + for e in self.ignoreExprs: + e.streamline() + + if not self.keepTabs: + instring = _ustr(instring).expandtabs() + instrlen = len(instring) + loc = 0 + preparseFn = self.preParse + parseFn = self._parse + ParserElement.resetCache() + matches = 0 + try: + while loc <= instrlen and matches < maxMatches: + try: + preloc = preparseFn( instring, loc ) + nextLoc,tokens = parseFn( instring, preloc, callPreParse=False ) + except ParseException: + loc = preloc+1 + else: + if nextLoc > loc: + matches += 1 + yield tokens, preloc, nextLoc + if overlap: + nextloc = preparseFn( instring, loc ) + if nextloc > loc: + loc = nextLoc + else: + loc += 1 + else: + loc = nextLoc + else: + loc = preloc+1 + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def transformString( self, instring ): + """ + Extension to C{L{scanString}}, to modify matching text with modified tokens that may + be returned from a parse action. To use C{transformString}, define a grammar and + attach a parse action to it that modifies the returned token list. + Invoking C{transformString()} on a target string will then scan for matches, + and replace the matched text patterns according to the logic in the parse + action. C{transformString()} returns the resulting transformed string. + + Example:: + wd = Word(alphas) + wd.setParseAction(lambda toks: toks[0].title()) + + print(wd.transformString("now is the winter of our discontent made glorious summer by this sun of york.")) + Prints:: + Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York. + """ + out = [] + lastE = 0 + # force preservation of <TAB>s, to minimize unwanted transformation of string, and to + # keep string locs straight between transformString and scanString + self.keepTabs = True + try: + for t,s,e in self.scanString( instring ): + out.append( instring[lastE:s] ) + if t: + if isinstance(t,ParseResults): + out += t.asList() + elif isinstance(t,list): + out += t + else: + out.append(t) + lastE = e + out.append(instring[lastE:]) + out = [o for o in out if o] + return "".join(map(_ustr,_flatten(out))) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def searchString( self, instring, maxMatches=_MAX_INT ): + """ + Another extension to C{L{scanString}}, simplifying the access to the tokens found + to match the given parse expression. May be called with optional + C{maxMatches} argument, to clip searching after 'n' matches are found. + + Example:: + # a capitalized word starts with an uppercase letter, followed by zero or more lowercase letters + cap_word = Word(alphas.upper(), alphas.lower()) + + print(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity")) + + # the sum() builtin can be used to merge results into a single ParseResults object + print(sum(cap_word.searchString("More than Iron, more than Lead, more than Gold I need Electricity"))) + prints:: + [['More'], ['Iron'], ['Lead'], ['Gold'], ['I'], ['Electricity']] + ['More', 'Iron', 'Lead', 'Gold', 'I', 'Electricity'] + """ + try: + return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ]) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def split(self, instring, maxsplit=_MAX_INT, includeSeparators=False): + """ + Generator method to split a string using the given expression as a separator. + May be called with optional C{maxsplit} argument, to limit the number of splits; + and the optional C{includeSeparators} argument (default=C{False}), if the separating + matching text should be included in the split results. + + Example:: + punc = oneOf(list(".,;:/-!?")) + print(list(punc.split("This, this?, this sentence, is badly punctuated!"))) + prints:: + ['This', ' this', '', ' this sentence', ' is badly punctuated', ''] + """ + splits = 0 + last = 0 + for t,s,e in self.scanString(instring, maxMatches=maxsplit): + yield instring[last:s] + if includeSeparators: + yield t[0] + last = e + yield instring[last:] + + def __add__(self, other ): + """ + Implementation of + operator - returns C{L{And}}. Adding strings to a ParserElement + converts them to L{Literal}s by default. + + Example:: + greet = Word(alphas) + "," + Word(alphas) + "!" + hello = "Hello, World!" + print (hello, "->", greet.parseString(hello)) + Prints:: + Hello, World! -> ['Hello', ',', 'World', '!'] + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return And( [ self, other ] ) + + def __radd__(self, other ): + """ + Implementation of + operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other + self + + def __sub__(self, other): + """ + Implementation of - operator, returns C{L{And}} with error stop + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return self + And._ErrorStop() + other + + def __rsub__(self, other ): + """ + Implementation of - operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other - self + + def __mul__(self,other): + """ + Implementation of * operator, allows use of C{expr * 3} in place of + C{expr + expr + expr}. Expressions may also me multiplied by a 2-integer + tuple, similar to C{{min,max}} multipliers in regular expressions. Tuples + may also include C{None} as in: + - C{expr*(n,None)} or C{expr*(n,)} is equivalent + to C{expr*n + L{ZeroOrMore}(expr)} + (read as "at least n instances of C{expr}") + - C{expr*(None,n)} is equivalent to C{expr*(0,n)} + (read as "0 to n instances of C{expr}") + - C{expr*(None,None)} is equivalent to C{L{ZeroOrMore}(expr)} + - C{expr*(1,None)} is equivalent to C{L{OneOrMore}(expr)} + + Note that C{expr*(None,n)} does not raise an exception if + more than n exprs exist in the input stream; that is, + C{expr*(None,n)} does not enforce a maximum number of expr + occurrences. If this behavior is desired, then write + C{expr*(None,n) + ~expr} + """ + if isinstance(other,int): + minElements, optElements = other,0 + elif isinstance(other,tuple): + other = (other + (None, None))[:2] + if other[0] is None: + other = (0, other[1]) + if isinstance(other[0],int) and other[1] is None: + if other[0] == 0: + return ZeroOrMore(self) + if other[0] == 1: + return OneOrMore(self) + else: + return self*other[0] + ZeroOrMore(self) + elif isinstance(other[0],int) and isinstance(other[1],int): + minElements, optElements = other + optElements -= minElements + else: + raise TypeError("cannot multiply 'ParserElement' and ('%s','%s') objects", type(other[0]),type(other[1])) + else: + raise TypeError("cannot multiply 'ParserElement' and '%s' objects", type(other)) + + if minElements < 0: + raise ValueError("cannot multiply ParserElement by negative value") + if optElements < 0: + raise ValueError("second tuple value must be greater or equal to first tuple value") + if minElements == optElements == 0: + raise ValueError("cannot multiply ParserElement by 0 or (0,0)") + + if (optElements): + def makeOptionalList(n): + if n>1: + return Optional(self + makeOptionalList(n-1)) + else: + return Optional(self) + if minElements: + if minElements == 1: + ret = self + makeOptionalList(optElements) + else: + ret = And([self]*minElements) + makeOptionalList(optElements) + else: + ret = makeOptionalList(optElements) + else: + if minElements == 1: + ret = self + else: + ret = And([self]*minElements) + return ret + + def __rmul__(self, other): + return self.__mul__(other) + + def __or__(self, other ): + """ + Implementation of | operator - returns C{L{MatchFirst}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return MatchFirst( [ self, other ] ) + + def __ror__(self, other ): + """ + Implementation of | operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other | self + + def __xor__(self, other ): + """ + Implementation of ^ operator - returns C{L{Or}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Or( [ self, other ] ) + + def __rxor__(self, other ): + """ + Implementation of ^ operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other ^ self + + def __and__(self, other ): + """ + Implementation of & operator - returns C{L{Each}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return Each( [ self, other ] ) + + def __rand__(self, other ): + """ + Implementation of & operator when left operand is not a C{L{ParserElement}} + """ + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + if not isinstance( other, ParserElement ): + warnings.warn("Cannot combine element of type %s with ParserElement" % type(other), + SyntaxWarning, stacklevel=2) + return None + return other & self + + def __invert__( self ): + """ + Implementation of ~ operator - returns C{L{NotAny}} + """ + return NotAny( self ) + + def __call__(self, name=None): + """ + Shortcut for C{L{setResultsName}}, with C{listAllMatches=False}. + + If C{name} is given with a trailing C{'*'} character, then C{listAllMatches} will be + passed as C{True}. + + If C{name} is omitted, same as calling C{L{copy}}. + + Example:: + # these are equivalent + userdata = Word(alphas).setResultsName("name") + Word(nums+"-").setResultsName("socsecno") + userdata = Word(alphas)("name") + Word(nums+"-")("socsecno") + """ + if name is not None: + return self.setResultsName(name) + else: + return self.copy() + + def suppress( self ): + """ + Suppresses the output of this C{ParserElement}; useful to keep punctuation from + cluttering up returned output. + """ + return Suppress( self ) + + def leaveWhitespace( self ): + """ + Disables the skipping of whitespace before matching the characters in the + C{ParserElement}'s defined pattern. This is normally only used internally by + the pyparsing module, but may be needed in some whitespace-sensitive grammars. + """ + self.skipWhitespace = False + return self + + def setWhitespaceChars( self, chars ): + """ + Overrides the default whitespace chars + """ + self.skipWhitespace = True + self.whiteChars = chars + self.copyDefaultWhiteChars = False + return self + + def parseWithTabs( self ): + """ + Overrides default behavior to expand C{<TAB>}s to spaces before parsing the input string. + Must be called before C{parseString} when the input grammar contains elements that + match C{<TAB>} characters. + """ + self.keepTabs = True + return self + + def ignore( self, other ): + """ + Define expression to be ignored (e.g., comments) while doing pattern + matching; may be called repeatedly, to define multiple comment or other + ignorable patterns. + + Example:: + patt = OneOrMore(Word(alphas)) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj'] + + patt.ignore(cStyleComment) + patt.parseString('ablaj /* comment */ lskjd') # -> ['ablaj', 'lskjd'] + """ + if isinstance(other, basestring): + other = Suppress(other) + + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + self.ignoreExprs.append(other) + else: + self.ignoreExprs.append( Suppress( other.copy() ) ) + return self + + def setDebugActions( self, startAction, successAction, exceptionAction ): + """ + Enable display of debugging messages while doing pattern matching. + """ + self.debugActions = (startAction or _defaultStartDebugAction, + successAction or _defaultSuccessDebugAction, + exceptionAction or _defaultExceptionDebugAction) + self.debug = True + return self + + def setDebug( self, flag=True ): + """ + Enable display of debugging messages while doing pattern matching. + Set C{flag} to True to enable, False to disable. + + Example:: + wd = Word(alphas).setName("alphaword") + integer = Word(nums).setName("numword") + term = wd | integer + + # turn on debugging for wd + wd.setDebug() + + OneOrMore(term).parseString("abc 123 xyz 890") + + prints:: + Match alphaword at loc 0(1,1) + Matched alphaword -> ['abc'] + Match alphaword at loc 3(1,4) + Exception raised:Expected alphaword (at char 4), (line:1, col:5) + Match alphaword at loc 7(1,8) + Matched alphaword -> ['xyz'] + Match alphaword at loc 11(1,12) + Exception raised:Expected alphaword (at char 12), (line:1, col:13) + Match alphaword at loc 15(1,16) + Exception raised:Expected alphaword (at char 15), (line:1, col:16) + + The output shown is that produced by the default debug actions - custom debug actions can be + specified using L{setDebugActions}. Prior to attempting + to match the C{wd} expression, the debugging message C{"Match <exprname> at loc <n>(<line>,<col>)"} + is shown. Then if the parse succeeds, a C{"Matched"} message is shown, or an C{"Exception raised"} + message is shown. Also note the use of L{setName} to assign a human-readable name to the expression, + which makes debugging and exception messages easier to understand - for instance, the default + name created for the C{Word} expression without calling C{setName} is C{"W:(ABCD...)"}. + """ + if flag: + self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction ) + else: + self.debug = False + return self + + def __str__( self ): + return self.name + + def __repr__( self ): + return _ustr(self) + + def streamline( self ): + self.streamlined = True + self.strRepr = None + return self + + def checkRecursion( self, parseElementList ): + pass + + def validate( self, validateTrace=[] ): + """ + Check defined expressions for valid structure, check for infinite recursive definitions. + """ + self.checkRecursion( [] ) + + def parseFile( self, file_or_filename, parseAll=False ): + """ + Execute the parse expression on the given file or filename. + If a filename is specified (instead of a file object), + the entire file is opened, read, and closed before parsing. + """ + try: + file_contents = file_or_filename.read() + except AttributeError: + with open(file_or_filename, "r") as f: + file_contents = f.read() + try: + return self.parseString(file_contents, parseAll) + except ParseBaseException as exc: + if ParserElement.verbose_stacktrace: + raise + else: + # catch and re-raise exception from here, clears out pyparsing internal stack trace + raise exc + + def __eq__(self,other): + if isinstance(other, ParserElement): + return self is other or vars(self) == vars(other) + elif isinstance(other, basestring): + return self.matches(other) + else: + return super(ParserElement,self)==other + + def __ne__(self,other): + return not (self == other) + + def __hash__(self): + return hash(id(self)) + + def __req__(self,other): + return self == other + + def __rne__(self,other): + return not (self == other) + + def matches(self, testString, parseAll=True): + """ + Method for quick testing of a parser against a test string. Good for simple + inline microtests of sub expressions while building up larger parser. + + Parameters: + - testString - to test against this expression for a match + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + + Example:: + expr = Word(nums) + assert expr.matches("100") + """ + try: + self.parseString(_ustr(testString), parseAll=parseAll) + return True + except ParseBaseException: + return False + + def runTests(self, tests, parseAll=True, comment='#', fullDump=True, printResults=True, failureTests=False): + """ + Execute the parse expression on a series of test strings, showing each + test, the parsed results or where the parse failed. Quick and easy way to + run a parse expression against a list of sample strings. + + Parameters: + - tests - a list of separate test strings, or a multiline string of test strings + - parseAll - (default=C{True}) - flag to pass to C{L{parseString}} when running tests + - comment - (default=C{'#'}) - expression for indicating embedded comments in the test + string; pass None to disable comment filtering + - fullDump - (default=C{True}) - dump results as list followed by results names in nested outline; + if False, only dump nested list + - printResults - (default=C{True}) prints test output to stdout + - failureTests - (default=C{False}) indicates if these tests are expected to fail parsing + + Returns: a (success, results) tuple, where success indicates that all tests succeeded + (or failed if C{failureTests} is True), and the results contain a list of lines of each + test's output + + Example:: + number_expr = pyparsing_common.number.copy() + + result = number_expr.runTests(''' + # unsigned integer + 100 + # negative integer + -100 + # float with scientific notation + 6.02e23 + # integer with scientific notation + 1e-12 + ''') + print("Success" if result[0] else "Failed!") + + result = number_expr.runTests(''' + # stray character + 100Z + # missing leading digit before '.' + -.100 + # too many '.' + 3.14.159 + ''', failureTests=True) + print("Success" if result[0] else "Failed!") + prints:: + # unsigned integer + 100 + [100] + + # negative integer + -100 + [-100] + + # float with scientific notation + 6.02e23 + [6.02e+23] + + # integer with scientific notation + 1e-12 + [1e-12] + + Success + + # stray character + 100Z + ^ + FAIL: Expected end of text (at char 3), (line:1, col:4) + + # missing leading digit before '.' + -.100 + ^ + FAIL: Expected {real number with scientific notation | real number | signed integer} (at char 0), (line:1, col:1) + + # too many '.' + 3.14.159 + ^ + FAIL: Expected end of text (at char 4), (line:1, col:5) + + Success + + Each test string must be on a single line. If you want to test a string that spans multiple + lines, create a test like this:: + + expr.runTest(r"this is a test\\n of strings that spans \\n 3 lines") + + (Note that this is a raw string literal, you must include the leading 'r'.) + """ + if isinstance(tests, basestring): + tests = list(map(str.strip, tests.rstrip().splitlines())) + if isinstance(comment, basestring): + comment = Literal(comment) + allResults = [] + comments = [] + success = True + for t in tests: + if comment is not None and comment.matches(t, False) or comments and not t: + comments.append(t) + continue + if not t: + continue + out = ['\n'.join(comments), t] + comments = [] + try: + t = t.replace(r'\n','\n') + result = self.parseString(t, parseAll=parseAll) + out.append(result.dump(full=fullDump)) + success = success and not failureTests + except ParseBaseException as pe: + fatal = "(FATAL)" if isinstance(pe, ParseFatalException) else "" + if '\n' in t: + out.append(line(pe.loc, t)) + out.append(' '*(col(pe.loc,t)-1) + '^' + fatal) + else: + out.append(' '*pe.loc + '^' + fatal) + out.append("FAIL: " + str(pe)) + success = success and failureTests + result = pe + except Exception as exc: + out.append("FAIL-EXCEPTION: " + str(exc)) + success = success and failureTests + result = exc + + if printResults: + if fullDump: + out.append('') + print('\n'.join(out)) + + allResults.append((t, result)) + + return success, allResults + + +class Token(ParserElement): + """ + Abstract C{ParserElement} subclass, for defining atomic matching patterns. + """ + def __init__( self ): + super(Token,self).__init__( savelist=False ) + + +class Empty(Token): + """ + An empty token, will always match. + """ + def __init__( self ): + super(Empty,self).__init__() + self.name = "Empty" + self.mayReturnEmpty = True + self.mayIndexError = False + + +class NoMatch(Token): + """ + A token that will never match. + """ + def __init__( self ): + super(NoMatch,self).__init__() + self.name = "NoMatch" + self.mayReturnEmpty = True + self.mayIndexError = False + self.errmsg = "Unmatchable token" + + def parseImpl( self, instring, loc, doActions=True ): + raise ParseException(instring, loc, self.errmsg, self) + + +class Literal(Token): + """ + Token to exactly match a specified string. + + Example:: + Literal('blah').parseString('blah') # -> ['blah'] + Literal('blah').parseString('blahfooblah') # -> ['blah'] + Literal('blah').parseString('bla') # -> Exception: Expected "blah" + + For case-insensitive matching, use L{CaselessLiteral}. + + For keyword matching (force word break before and after the matched string), + use L{Keyword} or L{CaselessKeyword}. + """ + def __init__( self, matchString ): + super(Literal,self).__init__() + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Literal; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.__class__ = Empty + self.name = '"%s"' % _ustr(self.match) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + + # Performance tuning: this routine gets called a *lot* + # if this is a single character match string and the first character matches, + # short-circuit as quickly as possible, and avoid calling startswith + #~ @profile + def parseImpl( self, instring, loc, doActions=True ): + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) +_L = Literal +ParserElement._literalStringClass = Literal + +class Keyword(Token): + """ + Token to exactly match a specified string as a keyword, that is, it must be + immediately followed by a non-keyword character. Compare with C{L{Literal}}: + - C{Literal("if")} will match the leading C{'if'} in C{'ifAndOnlyIf'}. + - C{Keyword("if")} will not; it will only match the leading C{'if'} in C{'if x=1'}, or C{'if(y==2)'} + Accepts two optional constructor arguments in addition to the keyword string: + - C{identChars} is a string of characters that would be valid identifier characters, + defaulting to all alphanumerics + "_" and "$" + - C{caseless} allows case-insensitive matching, default is C{False}. + + Example:: + Keyword("start").parseString("start") # -> ['start'] + Keyword("start").parseString("starting") # -> Exception + + For case-insensitive matching, use L{CaselessKeyword}. + """ + DEFAULT_KEYWORD_CHARS = alphanums+"_$" + + def __init__( self, matchString, identChars=None, caseless=False ): + super(Keyword,self).__init__() + if identChars is None: + identChars = Keyword.DEFAULT_KEYWORD_CHARS + self.match = matchString + self.matchLen = len(matchString) + try: + self.firstMatchChar = matchString[0] + except IndexError: + warnings.warn("null string passed to Keyword; use Empty() instead", + SyntaxWarning, stacklevel=2) + self.name = '"%s"' % self.match + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = False + self.mayIndexError = False + self.caseless = caseless + if caseless: + self.caselessmatch = matchString.upper() + identChars = identChars.upper() + self.identChars = set(identChars) + + def parseImpl( self, instring, loc, doActions=True ): + if self.caseless: + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and + (loc == 0 or instring[loc-1].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + else: + if (instring[loc] == self.firstMatchChar and + (self.matchLen==1 or instring.startswith(self.match,loc)) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and + (loc == 0 or instring[loc-1] not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + + def copy(self): + c = super(Keyword,self).copy() + c.identChars = Keyword.DEFAULT_KEYWORD_CHARS + return c + + @staticmethod + def setDefaultKeywordChars( chars ): + """Overrides the default Keyword chars + """ + Keyword.DEFAULT_KEYWORD_CHARS = chars + +class CaselessLiteral(Literal): + """ + Token to match a specified string, ignoring case of letters. + Note: the matched results will always be in the case of the given + match string, NOT the case of the input text. + + Example:: + OneOrMore(CaselessLiteral("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD', 'CMD'] + + (Contrast with example for L{CaselessKeyword}.) + """ + def __init__( self, matchString ): + super(CaselessLiteral,self).__init__( matchString.upper() ) + # Preserve the defining literal. + self.returnString = matchString + self.name = "'%s'" % self.returnString + self.errmsg = "Expected " + self.name + + def parseImpl( self, instring, loc, doActions=True ): + if instring[ loc:loc+self.matchLen ].upper() == self.match: + return loc+self.matchLen, self.returnString + raise ParseException(instring, loc, self.errmsg, self) + +class CaselessKeyword(Keyword): + """ + Caseless version of L{Keyword}. + + Example:: + OneOrMore(CaselessKeyword("CMD")).parseString("cmd CMD Cmd10") # -> ['CMD', 'CMD'] + + (Contrast with example for L{CaselessLiteral}.) + """ + def __init__( self, matchString, identChars=None ): + super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True ) + + def parseImpl( self, instring, loc, doActions=True ): + if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and + (loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ): + return loc+self.matchLen, self.match + raise ParseException(instring, loc, self.errmsg, self) + +class CloseMatch(Token): + """ + A variation on L{Literal} which matches "close" matches, that is, + strings with at most 'n' mismatching characters. C{CloseMatch} takes parameters: + - C{match_string} - string to be matched + - C{maxMismatches} - (C{default=1}) maximum number of mismatches allowed to count as a match + + The results from a successful parse will contain the matched text from the input string and the following named results: + - C{mismatches} - a list of the positions within the match_string where mismatches were found + - C{original} - the original match_string used to compare against the input string + + If C{mismatches} is an empty list, then the match was an exact match. + + Example:: + patt = CloseMatch("ATCATCGAATGGA") + patt.parseString("ATCATCGAAXGGA") # -> (['ATCATCGAAXGGA'], {'mismatches': [[9]], 'original': ['ATCATCGAATGGA']}) + patt.parseString("ATCAXCGAAXGGA") # -> Exception: Expected 'ATCATCGAATGGA' (with up to 1 mismatches) (at char 0), (line:1, col:1) + + # exact match + patt.parseString("ATCATCGAATGGA") # -> (['ATCATCGAATGGA'], {'mismatches': [[]], 'original': ['ATCATCGAATGGA']}) + + # close match allowing up to 2 mismatches + patt = CloseMatch("ATCATCGAATGGA", maxMismatches=2) + patt.parseString("ATCAXCGAAXGGA") # -> (['ATCAXCGAAXGGA'], {'mismatches': [[4, 9]], 'original': ['ATCATCGAATGGA']}) + """ + def __init__(self, match_string, maxMismatches=1): + super(CloseMatch,self).__init__() + self.name = match_string + self.match_string = match_string + self.maxMismatches = maxMismatches + self.errmsg = "Expected %r (with up to %d mismatches)" % (self.match_string, self.maxMismatches) + self.mayIndexError = False + self.mayReturnEmpty = False + + def parseImpl( self, instring, loc, doActions=True ): + start = loc + instrlen = len(instring) + maxloc = start + len(self.match_string) + + if maxloc <= instrlen: + match_string = self.match_string + match_stringloc = 0 + mismatches = [] + maxMismatches = self.maxMismatches + + for match_stringloc,s_m in enumerate(zip(instring[loc:maxloc], self.match_string)): + src,mat = s_m + if src != mat: + mismatches.append(match_stringloc) + if len(mismatches) > maxMismatches: + break + else: + loc = match_stringloc + 1 + results = ParseResults([instring[start:loc]]) + results['original'] = self.match_string + results['mismatches'] = mismatches + return loc, results + + raise ParseException(instring, loc, self.errmsg, self) + + +class Word(Token): + """ + Token for matching words composed of allowed character sets. + Defined with string containing all allowed initial characters, + an optional string containing allowed body characters (if omitted, + defaults to the initial character set), and an optional minimum, + maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. An optional + C{excludeChars} parameter can list characters that might be found in + the input C{bodyChars} string; useful to define a word of all printables + except for one or two characters, for instance. + + L{srange} is useful for defining custom character set strings for defining + C{Word} expressions, using range notation from regular expression character sets. + + A common mistake is to use C{Word} to match a specific literal string, as in + C{Word("Address")}. Remember that C{Word} uses the string argument to define + I{sets} of matchable characters. This expression would match "Add", "AAA", + "dAred", or any other word made up of the characters 'A', 'd', 'r', 'e', and 's'. + To match an exact literal string, use L{Literal} or L{Keyword}. + + pyparsing includes helper strings for building Words: + - L{alphas} + - L{nums} + - L{alphanums} + - L{hexnums} + - L{alphas8bit} (alphabetic characters in ASCII range 128-255 - accented, tilded, umlauted, etc.) + - L{punc8bit} (non-alphabetic characters in ASCII range 128-255 - currency, symbols, superscripts, diacriticals, etc.) + - L{printables} (any non-whitespace character) + + Example:: + # a word composed of digits + integer = Word(nums) # equivalent to Word("0123456789") or Word(srange("0-9")) + + # a word with a leading capital, and zero or more lowercase + capital_word = Word(alphas.upper(), alphas.lower()) + + # hostnames are alphanumeric, with leading alpha, and '-' + hostname = Word(alphas, alphanums+'-') + + # roman numeral (not a strict parser, accepts invalid mix of characters) + roman = Word("IVXLCDM") + + # any string of non-whitespace characters, except for ',' + csv_value = Word(printables, excludeChars=",") + """ + def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0, asKeyword=False, excludeChars=None ): + super(Word,self).__init__() + if excludeChars: + initChars = ''.join(c for c in initChars if c not in excludeChars) + if bodyChars: + bodyChars = ''.join(c for c in bodyChars if c not in excludeChars) + self.initCharsOrig = initChars + self.initChars = set(initChars) + if bodyChars : + self.bodyCharsOrig = bodyChars + self.bodyChars = set(bodyChars) + else: + self.bodyCharsOrig = initChars + self.bodyChars = set(initChars) + + self.maxSpecified = max > 0 + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(Word()) if zero-length word is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.asKeyword = asKeyword + + if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0): + if self.bodyCharsOrig == self.initCharsOrig: + self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig) + elif len(self.initCharsOrig) == 1: + self.reString = "%s[%s]*" % \ + (re.escape(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + else: + self.reString = "[%s][%s]*" % \ + (_escapeRegexRangeChars(self.initCharsOrig), + _escapeRegexRangeChars(self.bodyCharsOrig),) + if self.asKeyword: + self.reString = r"\b"+self.reString+r"\b" + try: + self.re = re.compile( self.reString ) + except Exception: + self.re = None + + def parseImpl( self, instring, loc, doActions=True ): + if self.re: + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + return loc, result.group() + + if not(instring[ loc ] in self.initChars): + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + instrlen = len(instring) + bodychars = self.bodyChars + maxloc = start + self.maxLen + maxloc = min( maxloc, instrlen ) + while loc < maxloc and instring[loc] in bodychars: + loc += 1 + + throwException = False + if loc - start < self.minLen: + throwException = True + if self.maxSpecified and loc < instrlen and instring[loc] in bodychars: + throwException = True + if self.asKeyword: + if (start>0 and instring[start-1] in bodychars) or (loc<instrlen and instring[loc] in bodychars): + throwException = True + + if throwException: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(Word,self).__str__() + except Exception: + pass + + + if self.strRepr is None: + + def charsAsStr(s): + if len(s)>4: + return s[:4]+"..." + else: + return s + + if ( self.initCharsOrig != self.bodyCharsOrig ): + self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) ) + else: + self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig) + + return self.strRepr + + +class Regex(Token): + r""" + Token for matching strings that match a given regular expression. + Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module. + If the given regex contains named groups (defined using C{(?P<name>...)}), these will be preserved as + named parse results. + + Example:: + realnum = Regex(r"[+-]?\d+\.\d*") + date = Regex(r'(?P<year>\d{4})-(?P<month>\d\d?)-(?P<day>\d\d?)') + # ref: http://stackoverflow.com/questions/267399/how-do-you-match-only-valid-roman-numerals-with-a-regular-expression + roman = Regex(r"M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})") + """ + compiledREtype = type(re.compile("[A-Z]")) + def __init__( self, pattern, flags=0): + """The parameters C{pattern} and C{flags} are passed to the C{re.compile()} function as-is. See the Python C{re} module for an explanation of the acceptable patterns and flags.""" + super(Regex,self).__init__() + + if isinstance(pattern, basestring): + if not pattern: + warnings.warn("null string passed to Regex; use Empty() instead", + SyntaxWarning, stacklevel=2) + + self.pattern = pattern + self.flags = flags + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % pattern, + SyntaxWarning, stacklevel=2) + raise + + elif isinstance(pattern, Regex.compiledREtype): + self.re = pattern + self.pattern = \ + self.reString = str(pattern) + self.flags = flags + + else: + raise ValueError("Regex may only be constructed with a string or a compiled RE object") + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = self.re.match(instring,loc) + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + d = result.groupdict() + ret = ParseResults(result.group()) + if d: + for k in d: + ret[k] = d[k] + return loc,ret + + def __str__( self ): + try: + return super(Regex,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "Re:(%s)" % repr(self.pattern) + + return self.strRepr + + +class QuotedString(Token): + r""" + Token for matching strings that are delimited by quoting characters. + + Defined with the following parameters: + - quoteChar - string of one or more characters defining the quote delimiting string + - escChar - character to escape quotes, typically backslash (default=C{None}) + - escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=C{None}) + - multiline - boolean indicating whether quotes can span multiple lines (default=C{False}) + - unquoteResults - boolean indicating whether the matched text should be unquoted (default=C{True}) + - endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=C{None} => same as quoteChar) + - convertWhitespaceEscapes - convert escaped whitespace (C{'\t'}, C{'\n'}, etc.) to actual whitespace (default=C{True}) + + Example:: + qs = QuotedString('"') + print(qs.searchString('lsjdf "This is the quote" sldjf')) + complex_qs = QuotedString('{{', endQuoteChar='}}') + print(complex_qs.searchString('lsjdf {{This is the "quote"}} sldjf')) + sql_qs = QuotedString('"', escQuote='""') + print(sql_qs.searchString('lsjdf "This is the quote with ""embedded"" quotes" sldjf')) + prints:: + [['This is the quote']] + [['This is the "quote"']] + [['This is the quote with "embedded" quotes']] + """ + def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None, convertWhitespaceEscapes=True): + super(QuotedString,self).__init__() + + # remove white space from quote chars - wont work anyway + quoteChar = quoteChar.strip() + if not quoteChar: + warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + if endQuoteChar is None: + endQuoteChar = quoteChar + else: + endQuoteChar = endQuoteChar.strip() + if not endQuoteChar: + warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2) + raise SyntaxError() + + self.quoteChar = quoteChar + self.quoteCharLen = len(quoteChar) + self.firstQuoteChar = quoteChar[0] + self.endQuoteChar = endQuoteChar + self.endQuoteCharLen = len(endQuoteChar) + self.escChar = escChar + self.escQuote = escQuote + self.unquoteResults = unquoteResults + self.convertWhitespaceEscapes = convertWhitespaceEscapes + + if multiline: + self.flags = re.MULTILINE | re.DOTALL + self.pattern = r'%s(?:[^%s%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + else: + self.flags = 0 + self.pattern = r'%s(?:[^%s\n\r%s]' % \ + ( re.escape(self.quoteChar), + _escapeRegexRangeChars(self.endQuoteChar[0]), + (escChar is not None and _escapeRegexRangeChars(escChar) or '') ) + if len(self.endQuoteChar) > 1: + self.pattern += ( + '|(?:' + ')|(?:'.join("%s[^%s]" % (re.escape(self.endQuoteChar[:i]), + _escapeRegexRangeChars(self.endQuoteChar[i])) + for i in range(len(self.endQuoteChar)-1,0,-1)) + ')' + ) + if escQuote: + self.pattern += (r'|(?:%s)' % re.escape(escQuote)) + if escChar: + self.pattern += (r'|(?:%s.)' % re.escape(escChar)) + self.escCharReplacePattern = re.escape(self.escChar)+"(.)" + self.pattern += (r')*%s' % re.escape(self.endQuoteChar)) + + try: + self.re = re.compile(self.pattern, self.flags) + self.reString = self.pattern + except sre_constants.error: + warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern, + SyntaxWarning, stacklevel=2) + raise + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayIndexError = False + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None + if not result: + raise ParseException(instring, loc, self.errmsg, self) + + loc = result.end() + ret = result.group() + + if self.unquoteResults: + + # strip off quotes + ret = ret[self.quoteCharLen:-self.endQuoteCharLen] + + if isinstance(ret,basestring): + # replace escaped whitespace + if '\\' in ret and self.convertWhitespaceEscapes: + ws_map = { + r'\t' : '\t', + r'\n' : '\n', + r'\f' : '\f', + r'\r' : '\r', + } + for wslit,wschar in ws_map.items(): + ret = ret.replace(wslit, wschar) + + # replace escaped characters + if self.escChar: + ret = re.sub(self.escCharReplacePattern, r"\g<1>", ret) + + # replace escaped quotes + if self.escQuote: + ret = ret.replace(self.escQuote, self.endQuoteChar) + + return loc, ret + + def __str__( self ): + try: + return super(QuotedString,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar) + + return self.strRepr + + +class CharsNotIn(Token): + """ + Token for matching words composed of characters I{not} in a given set (will + include whitespace in matched characters if not listed in the provided exclusion set - see example). + Defined with string containing all disallowed characters, and an optional + minimum, maximum, and/or exact length. The default value for C{min} is 1 (a + minimum value < 1 is not valid); the default values for C{max} and C{exact} + are 0, meaning no maximum or exact length restriction. + + Example:: + # define a comma-separated-value as anything that is not a ',' + csv_value = CharsNotIn(',') + print(delimitedList(csv_value).parseString("dkls,lsdkjf,s12 34,@!#,213")) + prints:: + ['dkls', 'lsdkjf', 's12 34', '@!#', '213'] + """ + def __init__( self, notChars, min=1, max=0, exact=0 ): + super(CharsNotIn,self).__init__() + self.skipWhitespace = False + self.notChars = notChars + + if min < 1: + raise ValueError("cannot specify a minimum length < 1; use Optional(CharsNotIn()) if zero-length char group is permitted") + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + self.name = _ustr(self) + self.errmsg = "Expected " + self.name + self.mayReturnEmpty = ( self.minLen == 0 ) + self.mayIndexError = False + + def parseImpl( self, instring, loc, doActions=True ): + if instring[loc] in self.notChars: + raise ParseException(instring, loc, self.errmsg, self) + + start = loc + loc += 1 + notchars = self.notChars + maxlen = min( start+self.maxLen, len(instring) ) + while loc < maxlen and \ + (instring[loc] not in notchars): + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + def __str__( self ): + try: + return super(CharsNotIn, self).__str__() + except Exception: + pass + + if self.strRepr is None: + if len(self.notChars) > 4: + self.strRepr = "!W:(%s...)" % self.notChars[:4] + else: + self.strRepr = "!W:(%s)" % self.notChars + + return self.strRepr + +class White(Token): + """ + Special matching class for matching whitespace. Normally, whitespace is ignored + by pyparsing grammars. This class is included when some whitespace structures + are significant. Define with a string containing the whitespace characters to be + matched; default is C{" \\t\\r\\n"}. Also takes optional C{min}, C{max}, and C{exact} arguments, + as defined for the C{L{Word}} class. + """ + whiteStrs = { + " " : "<SPC>", + "\t": "<TAB>", + "\n": "<LF>", + "\r": "<CR>", + "\f": "<FF>", + } + def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0): + super(White,self).__init__() + self.matchWhite = ws + self.setWhitespaceChars( "".join(c for c in self.whiteChars if c not in self.matchWhite) ) + #~ self.leaveWhitespace() + self.name = ("".join(White.whiteStrs[c] for c in self.matchWhite)) + self.mayReturnEmpty = True + self.errmsg = "Expected " + self.name + + self.minLen = min + + if max > 0: + self.maxLen = max + else: + self.maxLen = _MAX_INT + + if exact > 0: + self.maxLen = exact + self.minLen = exact + + def parseImpl( self, instring, loc, doActions=True ): + if not(instring[ loc ] in self.matchWhite): + raise ParseException(instring, loc, self.errmsg, self) + start = loc + loc += 1 + maxloc = start + self.maxLen + maxloc = min( maxloc, len(instring) ) + while loc < maxloc and instring[loc] in self.matchWhite: + loc += 1 + + if loc - start < self.minLen: + raise ParseException(instring, loc, self.errmsg, self) + + return loc, instring[start:loc] + + +class _PositionToken(Token): + def __init__( self ): + super(_PositionToken,self).__init__() + self.name=self.__class__.__name__ + self.mayReturnEmpty = True + self.mayIndexError = False + +class GoToColumn(_PositionToken): + """ + Token to advance to a specific column of input text; useful for tabular report scraping. + """ + def __init__( self, colno ): + super(GoToColumn,self).__init__() + self.col = colno + + def preParse( self, instring, loc ): + if col(loc,instring) != self.col: + instrlen = len(instring) + if self.ignoreExprs: + loc = self._skipIgnorables( instring, loc ) + while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col : + loc += 1 + return loc + + def parseImpl( self, instring, loc, doActions=True ): + thiscol = col( loc, instring ) + if thiscol > self.col: + raise ParseException( instring, loc, "Text not in expected column", self ) + newloc = loc + self.col - thiscol + ret = instring[ loc: newloc ] + return newloc, ret + + +class LineStart(_PositionToken): + """ + Matches if current position is at the beginning of a line within the parse string + + Example:: + + test = '''\ + AAA this line + AAA and this line + AAA but not this one + B AAA and definitely not this one + ''' + + for t in (LineStart() + 'AAA' + restOfLine).searchString(test): + print(t) + + Prints:: + ['AAA', ' this line'] + ['AAA', ' and this line'] + + """ + def __init__( self ): + super(LineStart,self).__init__() + self.errmsg = "Expected start of line" + + def parseImpl( self, instring, loc, doActions=True ): + if col(loc, instring) == 1: + return loc, [] + raise ParseException(instring, loc, self.errmsg, self) + +class LineEnd(_PositionToken): + """ + Matches if current position is at the end of a line within the parse string + """ + def __init__( self ): + super(LineEnd,self).__init__() + self.setWhitespaceChars( ParserElement.DEFAULT_WHITE_CHARS.replace("\n","") ) + self.errmsg = "Expected end of line" + + def parseImpl( self, instring, loc, doActions=True ): + if loc<len(instring): + if instring[loc] == "\n": + return loc+1, "\n" + else: + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class StringStart(_PositionToken): + """ + Matches if current position is at the beginning of the parse string + """ + def __init__( self ): + super(StringStart,self).__init__() + self.errmsg = "Expected start of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc != 0: + # see if entire string up to here is just whitespace and ignoreables + if loc != self.preParse( instring, 0 ): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class StringEnd(_PositionToken): + """ + Matches if current position is at the end of the parse string + """ + def __init__( self ): + super(StringEnd,self).__init__() + self.errmsg = "Expected end of text" + + def parseImpl( self, instring, loc, doActions=True ): + if loc < len(instring): + raise ParseException(instring, loc, self.errmsg, self) + elif loc == len(instring): + return loc+1, [] + elif loc > len(instring): + return loc, [] + else: + raise ParseException(instring, loc, self.errmsg, self) + +class WordStart(_PositionToken): + """ + Matches if the current position is at the beginning of a Word, and + is not preceded by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordStart(alphanums)}. C{WordStart} will also match at the beginning of + the string being parsed, or at the beginning of a line. + """ + def __init__(self, wordChars = printables): + super(WordStart,self).__init__() + self.wordChars = set(wordChars) + self.errmsg = "Not at the start of a word" + + def parseImpl(self, instring, loc, doActions=True ): + if loc != 0: + if (instring[loc-1] in self.wordChars or + instring[loc] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + +class WordEnd(_PositionToken): + """ + Matches if the current position is at the end of a Word, and + is not followed by any character in a given set of C{wordChars} + (default=C{printables}). To emulate the C{\b} behavior of regular expressions, + use C{WordEnd(alphanums)}. C{WordEnd} will also match at the end of + the string being parsed, or at the end of a line. + """ + def __init__(self, wordChars = printables): + super(WordEnd,self).__init__() + self.wordChars = set(wordChars) + self.skipWhitespace = False + self.errmsg = "Not at the end of a word" + + def parseImpl(self, instring, loc, doActions=True ): + instrlen = len(instring) + if instrlen>0 and loc<instrlen: + if (instring[loc] in self.wordChars or + instring[loc-1] not in self.wordChars): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + +class ParseExpression(ParserElement): + """ + Abstract subclass of ParserElement, for combining and post-processing parsed tokens. + """ + def __init__( self, exprs, savelist = False ): + super(ParseExpression,self).__init__(savelist) + if isinstance( exprs, _generatorType ): + exprs = list(exprs) + + if isinstance( exprs, basestring ): + self.exprs = [ ParserElement._literalStringClass( exprs ) ] + elif isinstance( exprs, Iterable ): + exprs = list(exprs) + # if sequence of strings provided, wrap with Literal + if all(isinstance(expr, basestring) for expr in exprs): + exprs = map(ParserElement._literalStringClass, exprs) + self.exprs = list(exprs) + else: + try: + self.exprs = list( exprs ) + except TypeError: + self.exprs = [ exprs ] + self.callPreparse = False + + def __getitem__( self, i ): + return self.exprs[i] + + def append( self, other ): + self.exprs.append( other ) + self.strRepr = None + return self + + def leaveWhitespace( self ): + """Extends C{leaveWhitespace} defined in base class, and also invokes C{leaveWhitespace} on + all contained expressions.""" + self.skipWhitespace = False + self.exprs = [ e.copy() for e in self.exprs ] + for e in self.exprs: + e.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + else: + super( ParseExpression, self).ignore( other ) + for e in self.exprs: + e.ignore( self.ignoreExprs[-1] ) + return self + + def __str__( self ): + try: + return super(ParseExpression,self).__str__() + except Exception: + pass + + if self.strRepr is None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) ) + return self.strRepr + + def streamline( self ): + super(ParseExpression,self).streamline() + + for e in self.exprs: + e.streamline() + + # collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d ) + # but only if there are no parse actions or resultsNames on the nested And's + # (likewise for Or's and MatchFirst's) + if ( len(self.exprs) == 2 ): + other = self.exprs[0] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = other.exprs[:] + [ self.exprs[1] ] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + other = self.exprs[-1] + if ( isinstance( other, self.__class__ ) and + not(other.parseAction) and + other.resultsName is None and + not other.debug ): + self.exprs = self.exprs[:-1] + other.exprs[:] + self.strRepr = None + self.mayReturnEmpty |= other.mayReturnEmpty + self.mayIndexError |= other.mayIndexError + + self.errmsg = "Expected " + _ustr(self) + + return self + + def setResultsName( self, name, listAllMatches=False ): + ret = super(ParseExpression,self).setResultsName(name,listAllMatches) + return ret + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + for e in self.exprs: + e.validate(tmp) + self.checkRecursion( [] ) + + def copy(self): + ret = super(ParseExpression,self).copy() + ret.exprs = [e.copy() for e in self.exprs] + return ret + +class And(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found in the given order. + Expressions may be separated by whitespace. + May be constructed using the C{'+'} operator. + May also be constructed using the C{'-'} operator, which will suppress backtracking. + + Example:: + integer = Word(nums) + name_expr = OneOrMore(Word(alphas)) + + expr = And([integer("id"),name_expr("name"),integer("age")]) + # more easily written as: + expr = integer("id") + name_expr("name") + integer("age") + """ + + class _ErrorStop(Empty): + def __init__(self, *args, **kwargs): + super(And._ErrorStop,self).__init__(*args, **kwargs) + self.name = '-' + self.leaveWhitespace() + + def __init__( self, exprs, savelist = True ): + super(And,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.setWhitespaceChars( self.exprs[0].whiteChars ) + self.skipWhitespace = self.exprs[0].skipWhitespace + self.callPreparse = True + + def parseImpl( self, instring, loc, doActions=True ): + # pass False as last arg to _parse for first element, since we already + # pre-parsed the string as part of our And pre-parsing + loc, resultlist = self.exprs[0]._parse( instring, loc, doActions, callPreParse=False ) + errorStop = False + for e in self.exprs[1:]: + if isinstance(e, And._ErrorStop): + errorStop = True + continue + if errorStop: + try: + loc, exprtokens = e._parse( instring, loc, doActions ) + except ParseSyntaxException: + raise + except ParseBaseException as pe: + pe.__traceback__ = None + raise ParseSyntaxException._from_exception(pe) + except IndexError: + raise ParseSyntaxException(instring, len(instring), self.errmsg, self) + else: + loc, exprtokens = e._parse( instring, loc, doActions ) + if exprtokens or exprtokens.haskeys(): + resultlist += exprtokens + return loc, resultlist + + def __iadd__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #And( [ self, other ] ) + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + if not e.mayReturnEmpty: + break + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + +class Or(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the expression that matches the longest string will be used. + May be constructed using the C{'^'} operator. + + Example:: + # construct Or using '^' operator + + number = Word(nums) ^ Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) + prints:: + [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(Or,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + matches = [] + for e in self.exprs: + try: + loc2 = e.tryParse( instring, loc ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + else: + # save match among all matches, to retry longest to shortest + matches.append((loc2, e)) + + if matches: + matches.sort(key=lambda x: -x[0]) + for _,e in matches: + try: + return e._parse( instring, loc, doActions ) + except ParseException as err: + err.__traceback__ = None + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + + def __ixor__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #Or( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " ^ ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class MatchFirst(ParseExpression): + """ + Requires that at least one C{ParseExpression} is found. + If two expressions match, the first one listed is the one that will match. + May be constructed using the C{'|'} operator. + + Example:: + # construct MatchFirst using '|' operator + + # watch the order of expressions to match + number = Word(nums) | Combine(Word(nums) + '.' + Word(nums)) + print(number.searchString("123 3.1416 789")) # Fail! -> [['123'], ['3'], ['1416'], ['789']] + + # put more selective expression first + number = Combine(Word(nums) + '.' + Word(nums)) | Word(nums) + print(number.searchString("123 3.1416 789")) # Better -> [['123'], ['3.1416'], ['789']] + """ + def __init__( self, exprs, savelist = False ): + super(MatchFirst,self).__init__(exprs, savelist) + if self.exprs: + self.mayReturnEmpty = any(e.mayReturnEmpty for e in self.exprs) + else: + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + maxExcLoc = -1 + maxException = None + for e in self.exprs: + try: + ret = e._parse( instring, loc, doActions ) + return ret + except ParseException as err: + if err.loc > maxExcLoc: + maxException = err + maxExcLoc = err.loc + except IndexError: + if len(instring) > maxExcLoc: + maxException = ParseException(instring,len(instring),e.errmsg,self) + maxExcLoc = len(instring) + + # only got here if no expression matched, raise exception for match that made it the furthest + else: + if maxException is not None: + maxException.msg = self.errmsg + raise maxException + else: + raise ParseException(instring, loc, "no defined alternatives to match", self) + + def __ior__(self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass( other ) + return self.append( other ) #MatchFirst( [ self, other ] ) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " | ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class Each(ParseExpression): + """ + Requires all given C{ParseExpression}s to be found, but in any order. + Expressions may be separated by whitespace. + May be constructed using the C{'&'} operator. + + Example:: + color = oneOf("RED ORANGE YELLOW GREEN BLUE PURPLE BLACK WHITE BROWN") + shape_type = oneOf("SQUARE CIRCLE TRIANGLE STAR HEXAGON OCTAGON") + integer = Word(nums) + shape_attr = "shape:" + shape_type("shape") + posn_attr = "posn:" + Group(integer("x") + ',' + integer("y"))("posn") + color_attr = "color:" + color("color") + size_attr = "size:" + integer("size") + + # use Each (using operator '&') to accept attributes in any order + # (shape and posn are required, color and size are optional) + shape_spec = shape_attr & posn_attr & Optional(color_attr) & Optional(size_attr) + + shape_spec.runTests(''' + shape: SQUARE color: BLACK posn: 100, 120 + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + color:GREEN size:20 shape:TRIANGLE posn:20,40 + ''' + ) + prints:: + shape: SQUARE color: BLACK posn: 100, 120 + ['shape:', 'SQUARE', 'color:', 'BLACK', 'posn:', ['100', ',', '120']] + - color: BLACK + - posn: ['100', ',', '120'] + - x: 100 + - y: 120 + - shape: SQUARE + + + shape: CIRCLE size: 50 color: BLUE posn: 50,80 + ['shape:', 'CIRCLE', 'size:', '50', 'color:', 'BLUE', 'posn:', ['50', ',', '80']] + - color: BLUE + - posn: ['50', ',', '80'] + - x: 50 + - y: 80 + - shape: CIRCLE + - size: 50 + + + color: GREEN size: 20 shape: TRIANGLE posn: 20,40 + ['color:', 'GREEN', 'size:', '20', 'shape:', 'TRIANGLE', 'posn:', ['20', ',', '40']] + - color: GREEN + - posn: ['20', ',', '40'] + - x: 20 + - y: 40 + - shape: TRIANGLE + - size: 20 + """ + def __init__( self, exprs, savelist = True ): + super(Each,self).__init__(exprs, savelist) + self.mayReturnEmpty = all(e.mayReturnEmpty for e in self.exprs) + self.skipWhitespace = True + self.initExprGroups = True + + def parseImpl( self, instring, loc, doActions=True ): + if self.initExprGroups: + self.opt1map = dict((id(e.expr),e) for e in self.exprs if isinstance(e,Optional)) + opt1 = [ e.expr for e in self.exprs if isinstance(e,Optional) ] + opt2 = [ e for e in self.exprs if e.mayReturnEmpty and not isinstance(e,Optional)] + self.optionals = opt1 + opt2 + self.multioptionals = [ e.expr for e in self.exprs if isinstance(e,ZeroOrMore) ] + self.multirequired = [ e.expr for e in self.exprs if isinstance(e,OneOrMore) ] + self.required = [ e for e in self.exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ] + self.required += self.multirequired + self.initExprGroups = False + tmpLoc = loc + tmpReqd = self.required[:] + tmpOpt = self.optionals[:] + matchOrder = [] + + keepMatching = True + while keepMatching: + tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired + failed = [] + for e in tmpExprs: + try: + tmpLoc = e.tryParse( instring, tmpLoc ) + except ParseException: + failed.append(e) + else: + matchOrder.append(self.opt1map.get(id(e),e)) + if e in tmpReqd: + tmpReqd.remove(e) + elif e in tmpOpt: + tmpOpt.remove(e) + if len(failed) == len(tmpExprs): + keepMatching = False + + if tmpReqd: + missing = ", ".join(_ustr(e) for e in tmpReqd) + raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing ) + + # add any unmatched Optionals, in case they have default values defined + matchOrder += [e for e in self.exprs if isinstance(e,Optional) and e.expr in tmpOpt] + + resultlist = [] + for e in matchOrder: + loc,results = e._parse(instring,loc,doActions) + resultlist.append(results) + + finalResults = sum(resultlist, ParseResults([])) + return loc, finalResults + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + " & ".join(_ustr(e) for e in self.exprs) + "}" + + return self.strRepr + + def checkRecursion( self, parseElementList ): + subRecCheckList = parseElementList[:] + [ self ] + for e in self.exprs: + e.checkRecursion( subRecCheckList ) + + +class ParseElementEnhance(ParserElement): + """ + Abstract subclass of C{ParserElement}, for combining and post-processing parsed tokens. + """ + def __init__( self, expr, savelist=False ): + super(ParseElementEnhance,self).__init__(savelist) + if isinstance( expr, basestring ): + if issubclass(ParserElement._literalStringClass, Token): + expr = ParserElement._literalStringClass(expr) + else: + expr = ParserElement._literalStringClass(Literal(expr)) + self.expr = expr + self.strRepr = None + if expr is not None: + self.mayIndexError = expr.mayIndexError + self.mayReturnEmpty = expr.mayReturnEmpty + self.setWhitespaceChars( expr.whiteChars ) + self.skipWhitespace = expr.skipWhitespace + self.saveAsList = expr.saveAsList + self.callPreparse = expr.callPreparse + self.ignoreExprs.extend(expr.ignoreExprs) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr is not None: + return self.expr._parse( instring, loc, doActions, callPreParse=False ) + else: + raise ParseException("",loc,self.errmsg,self) + + def leaveWhitespace( self ): + self.skipWhitespace = False + self.expr = self.expr.copy() + if self.expr is not None: + self.expr.leaveWhitespace() + return self + + def ignore( self, other ): + if isinstance( other, Suppress ): + if other not in self.ignoreExprs: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + else: + super( ParseElementEnhance, self).ignore( other ) + if self.expr is not None: + self.expr.ignore( self.ignoreExprs[-1] ) + return self + + def streamline( self ): + super(ParseElementEnhance,self).streamline() + if self.expr is not None: + self.expr.streamline() + return self + + def checkRecursion( self, parseElementList ): + if self in parseElementList: + raise RecursiveGrammarException( parseElementList+[self] ) + subRecCheckList = parseElementList[:] + [ self ] + if self.expr is not None: + self.expr.checkRecursion( subRecCheckList ) + + def validate( self, validateTrace=[] ): + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion( [] ) + + def __str__( self ): + try: + return super(ParseElementEnhance,self).__str__() + except Exception: + pass + + if self.strRepr is None and self.expr is not None: + self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) ) + return self.strRepr + + +class FollowedBy(ParseElementEnhance): + """ + Lookahead matching of the given parse expression. C{FollowedBy} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression matches at the current + position. C{FollowedBy} always returns a null token list. + + Example:: + # use FollowedBy to match a label only if it is followed by a ':' + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + OneOrMore(attr_expr).parseString("shape: SQUARE color: BLACK posn: upper left").pprint() + prints:: + [['shape', 'SQUARE'], ['color', 'BLACK'], ['posn', 'upper left']] + """ + def __init__( self, expr ): + super(FollowedBy,self).__init__(expr) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + self.expr.tryParse( instring, loc ) + return loc, [] + + +class NotAny(ParseElementEnhance): + """ + Lookahead to disallow matching with the given parse expression. C{NotAny} + does I{not} advance the parsing position within the input string, it only + verifies that the specified parse expression does I{not} match at the current + position. Also, C{NotAny} does I{not} skip over leading whitespace. C{NotAny} + always returns a null token list. May be constructed using the '~' operator. + + Example:: + + """ + def __init__( self, expr ): + super(NotAny,self).__init__(expr) + #~ self.leaveWhitespace() + self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs + self.mayReturnEmpty = True + self.errmsg = "Found unwanted token, "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + if self.expr.canParseNext(instring, loc): + raise ParseException(instring, loc, self.errmsg, self) + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "~{" + _ustr(self.expr) + "}" + + return self.strRepr + +class _MultipleMatch(ParseElementEnhance): + def __init__( self, expr, stopOn=None): + super(_MultipleMatch, self).__init__(expr) + self.saveAsList = True + ender = stopOn + if isinstance(ender, basestring): + ender = ParserElement._literalStringClass(ender) + self.not_ender = ~ender if ender is not None else None + + def parseImpl( self, instring, loc, doActions=True ): + self_expr_parse = self.expr._parse + self_skip_ignorables = self._skipIgnorables + check_ender = self.not_ender is not None + if check_ender: + try_not_ender = self.not_ender.tryParse + + # must be at least one (but first see if we are the stopOn sentinel; + # if so, fail) + if check_ender: + try_not_ender(instring, loc) + loc, tokens = self_expr_parse( instring, loc, doActions, callPreParse=False ) + try: + hasIgnoreExprs = (not not self.ignoreExprs) + while 1: + if check_ender: + try_not_ender(instring, loc) + if hasIgnoreExprs: + preloc = self_skip_ignorables( instring, loc ) + else: + preloc = loc + loc, tmptokens = self_expr_parse( instring, preloc, doActions ) + if tmptokens or tmptokens.haskeys(): + tokens += tmptokens + except (ParseException,IndexError): + pass + + return loc, tokens + +class OneOrMore(_MultipleMatch): + """ + Repetition of one or more of the given expression. + + Parameters: + - expr - expression that must match one or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: BLACK" + OneOrMore(attr_expr).parseString(text).pprint() # Fail! read 'color' as data instead of next label -> [['shape', 'SQUARE color']] + + # use stopOn attribute for OneOrMore to avoid reading label string as part of the data + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + OneOrMore(attr_expr).parseString(text).pprint() # Better -> [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'BLACK']] + + # could also be written as + (attr_expr * (1,)).parseString(text).pprint() + """ + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "{" + _ustr(self.expr) + "}..." + + return self.strRepr + +class ZeroOrMore(_MultipleMatch): + """ + Optional repetition of zero or more of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - stopOn - (default=C{None}) - expression for a terminating sentinel + (only required if the sentinel would ordinarily match the repetition + expression) + + Example: similar to L{OneOrMore} + """ + def __init__( self, expr, stopOn=None): + super(ZeroOrMore,self).__init__(expr, stopOn=stopOn) + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + return super(ZeroOrMore, self).parseImpl(instring, loc, doActions) + except (ParseException,IndexError): + return loc, [] + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]..." + + return self.strRepr + +class _NullToken(object): + def __bool__(self): + return False + __nonzero__ = __bool__ + def __str__(self): + return "" + +_optionalNotMatched = _NullToken() +class Optional(ParseElementEnhance): + """ + Optional matching of the given expression. + + Parameters: + - expr - expression that must match zero or more times + - default (optional) - value to be returned if the optional expression is not found. + + Example:: + # US postal code can be a 5-digit zip, plus optional 4-digit qualifier + zip = Combine(Word(nums, exact=5) + Optional('-' + Word(nums, exact=4))) + zip.runTests(''' + # traditional ZIP code + 12345 + + # ZIP+4 form + 12101-0001 + + # invalid ZIP + 98765- + ''') + prints:: + # traditional ZIP code + 12345 + ['12345'] + + # ZIP+4 form + 12101-0001 + ['12101-0001'] + + # invalid ZIP + 98765- + ^ + FAIL: Expected end of text (at char 5), (line:1, col:6) + """ + def __init__( self, expr, default=_optionalNotMatched ): + super(Optional,self).__init__( expr, savelist=False ) + self.saveAsList = self.expr.saveAsList + self.defaultValue = default + self.mayReturnEmpty = True + + def parseImpl( self, instring, loc, doActions=True ): + try: + loc, tokens = self.expr._parse( instring, loc, doActions, callPreParse=False ) + except (ParseException,IndexError): + if self.defaultValue is not _optionalNotMatched: + if self.expr.resultsName: + tokens = ParseResults([ self.defaultValue ]) + tokens[self.expr.resultsName] = self.defaultValue + else: + tokens = [ self.defaultValue ] + else: + tokens = [] + return loc, tokens + + def __str__( self ): + if hasattr(self,"name"): + return self.name + + if self.strRepr is None: + self.strRepr = "[" + _ustr(self.expr) + "]" + + return self.strRepr + +class SkipTo(ParseElementEnhance): + """ + Token for skipping over all undefined text until the matched expression is found. + + Parameters: + - expr - target expression marking the end of the data to be skipped + - include - (default=C{False}) if True, the target expression is also parsed + (the skipped text and target expression are returned as a 2-element list). + - ignore - (default=C{None}) used to define grammars (typically quoted strings and + comments) that might contain false matches to the target expression + - failOn - (default=C{None}) define expressions that are not allowed to be + included in the skipped test; if found before the target expression is found, + the SkipTo is not a match + + Example:: + report = ''' + Outstanding Issues Report - 1 Jan 2000 + + # | Severity | Description | Days Open + -----+----------+-------------------------------------------+----------- + 101 | Critical | Intermittent system crash | 6 + 94 | Cosmetic | Spelling error on Login ('log|n') | 14 + 79 | Minor | System slow when running too many reports | 47 + ''' + integer = Word(nums) + SEP = Suppress('|') + # use SkipTo to simply match everything up until the next SEP + # - ignore quoted strings, so that a '|' character inside a quoted string does not match + # - parse action will call token.strip() for each matched token, i.e., the description body + string_data = SkipTo(SEP, ignore=quotedString) + string_data.setParseAction(tokenMap(str.strip)) + ticket_expr = (integer("issue_num") + SEP + + string_data("sev") + SEP + + string_data("desc") + SEP + + integer("days_open")) + + for tkt in ticket_expr.searchString(report): + print tkt.dump() + prints:: + ['101', 'Critical', 'Intermittent system crash', '6'] + - days_open: 6 + - desc: Intermittent system crash + - issue_num: 101 + - sev: Critical + ['94', 'Cosmetic', "Spelling error on Login ('log|n')", '14'] + - days_open: 14 + - desc: Spelling error on Login ('log|n') + - issue_num: 94 + - sev: Cosmetic + ['79', 'Minor', 'System slow when running too many reports', '47'] + - days_open: 47 + - desc: System slow when running too many reports + - issue_num: 79 + - sev: Minor + """ + def __init__( self, other, include=False, ignore=None, failOn=None ): + super( SkipTo, self ).__init__( other ) + self.ignoreExpr = ignore + self.mayReturnEmpty = True + self.mayIndexError = False + self.includeMatch = include + self.asList = False + if isinstance(failOn, basestring): + self.failOn = ParserElement._literalStringClass(failOn) + else: + self.failOn = failOn + self.errmsg = "No match found for "+_ustr(self.expr) + + def parseImpl( self, instring, loc, doActions=True ): + startloc = loc + instrlen = len(instring) + expr = self.expr + expr_parse = self.expr._parse + self_failOn_canParseNext = self.failOn.canParseNext if self.failOn is not None else None + self_ignoreExpr_tryParse = self.ignoreExpr.tryParse if self.ignoreExpr is not None else None + + tmploc = loc + while tmploc <= instrlen: + if self_failOn_canParseNext is not None: + # break if failOn expression matches + if self_failOn_canParseNext(instring, tmploc): + break + + if self_ignoreExpr_tryParse is not None: + # advance past ignore expressions + while 1: + try: + tmploc = self_ignoreExpr_tryParse(instring, tmploc) + except ParseBaseException: + break + + try: + expr_parse(instring, tmploc, doActions=False, callPreParse=False) + except (ParseException, IndexError): + # no match, advance loc in string + tmploc += 1 + else: + # matched skipto expr, done + break + + else: + # ran off the end of the input string without matching skipto expr, fail + raise ParseException(instring, loc, self.errmsg, self) + + # build up return values + loc = tmploc + skiptext = instring[startloc:loc] + skipresult = ParseResults(skiptext) + + if self.includeMatch: + loc, mat = expr_parse(instring,loc,doActions,callPreParse=False) + skipresult += mat + + return loc, skipresult + +class Forward(ParseElementEnhance): + """ + Forward declaration of an expression to be defined later - + used for recursive grammars, such as algebraic infix notation. + When the expression is known, it is assigned to the C{Forward} variable using the '<<' operator. + + Note: take care when assigning to C{Forward} not to overlook precedence of operators. + Specifically, '|' has a lower precedence than '<<', so that:: + fwdExpr << a | b | c + will actually be evaluated as:: + (fwdExpr << a) | b | c + thereby leaving b and c out as parseable alternatives. It is recommended that you + explicitly group the values inserted into the C{Forward}:: + fwdExpr << (a | b | c) + Converting to use the '<<=' operator instead will avoid this problem. + + See L{ParseResults.pprint} for an example of a recursive parser created using + C{Forward}. + """ + def __init__( self, other=None ): + super(Forward,self).__init__( other, savelist=False ) + + def __lshift__( self, other ): + if isinstance( other, basestring ): + other = ParserElement._literalStringClass(other) + self.expr = other + self.strRepr = None + self.mayIndexError = self.expr.mayIndexError + self.mayReturnEmpty = self.expr.mayReturnEmpty + self.setWhitespaceChars( self.expr.whiteChars ) + self.skipWhitespace = self.expr.skipWhitespace + self.saveAsList = self.expr.saveAsList + self.ignoreExprs.extend(self.expr.ignoreExprs) + return self + + def __ilshift__(self, other): + return self << other + + def leaveWhitespace( self ): + self.skipWhitespace = False + return self + + def streamline( self ): + if not self.streamlined: + self.streamlined = True + if self.expr is not None: + self.expr.streamline() + return self + + def validate( self, validateTrace=[] ): + if self not in validateTrace: + tmp = validateTrace[:]+[self] + if self.expr is not None: + self.expr.validate(tmp) + self.checkRecursion([]) + + def __str__( self ): + if hasattr(self,"name"): + return self.name + return self.__class__.__name__ + ": ..." + + # stubbed out for now - creates awful memory and perf issues + self._revertClass = self.__class__ + self.__class__ = _ForwardNoRecurse + try: + if self.expr is not None: + retString = _ustr(self.expr) + else: + retString = "None" + finally: + self.__class__ = self._revertClass + return self.__class__.__name__ + ": " + retString + + def copy(self): + if self.expr is not None: + return super(Forward,self).copy() + else: + ret = Forward() + ret <<= self + return ret + +class _ForwardNoRecurse(Forward): + def __str__( self ): + return "..." + +class TokenConverter(ParseElementEnhance): + """ + Abstract subclass of C{ParseExpression}, for converting parsed results. + """ + def __init__( self, expr, savelist=False ): + super(TokenConverter,self).__init__( expr )#, savelist ) + self.saveAsList = False + +class Combine(TokenConverter): + """ + Converter to concatenate all matching tokens to a single string. + By default, the matching patterns must also be contiguous in the input string; + this can be disabled by specifying C{'adjacent=False'} in the constructor. + + Example:: + real = Word(nums) + '.' + Word(nums) + print(real.parseString('3.1416')) # -> ['3', '.', '1416'] + # will also erroneously match the following + print(real.parseString('3. 1416')) # -> ['3', '.', '1416'] + + real = Combine(Word(nums) + '.' + Word(nums)) + print(real.parseString('3.1416')) # -> ['3.1416'] + # no match when there are internal spaces + print(real.parseString('3. 1416')) # -> Exception: Expected W:(0123...) + """ + def __init__( self, expr, joinString="", adjacent=True ): + super(Combine,self).__init__( expr ) + # suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself + if adjacent: + self.leaveWhitespace() + self.adjacent = adjacent + self.skipWhitespace = True + self.joinString = joinString + self.callPreparse = True + + def ignore( self, other ): + if self.adjacent: + ParserElement.ignore(self, other) + else: + super( Combine, self).ignore( other ) + return self + + def postParse( self, instring, loc, tokenlist ): + retToks = tokenlist.copy() + del retToks[:] + retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults) + + if self.resultsName and retToks.haskeys(): + return [ retToks ] + else: + return retToks + +class Group(TokenConverter): + """ + Converter to return the matched tokens as a list - useful for returning tokens of C{L{ZeroOrMore}} and C{L{OneOrMore}} expressions. + + Example:: + ident = Word(alphas) + num = Word(nums) + term = ident | num + func = ident + Optional(delimitedList(term)) + print(func.parseString("fn a,b,100")) # -> ['fn', 'a', 'b', '100'] + + func = ident + Group(Optional(delimitedList(term))) + print(func.parseString("fn a,b,100")) # -> ['fn', ['a', 'b', '100']] + """ + def __init__( self, expr ): + super(Group,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + return [ tokenlist ] + +class Dict(TokenConverter): + """ + Converter to return a repetitive expression as a list, but also as a dictionary. + Each element can also be referenced using the first token in the expression as its key. + Useful for tabular report scraping when the first column can be used as a item key. + + Example:: + data_word = Word(alphas) + label = data_word + FollowedBy(':') + attr_expr = Group(label + Suppress(':') + OneOrMore(data_word).setParseAction(' '.join)) + + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + + # print attributes as plain groups + print(OneOrMore(attr_expr).parseString(text).dump()) + + # instead of OneOrMore(expr), parse using Dict(OneOrMore(Group(expr))) - Dict will auto-assign names + result = Dict(OneOrMore(Group(attr_expr))).parseString(text) + print(result.dump()) + + # access named fields as dict entries, or output as dict + print(result['shape']) + print(result.asDict()) + prints:: + ['shape', 'SQUARE', 'posn', 'upper left', 'color', 'light blue', 'texture', 'burlap'] + + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + {'color': 'light blue', 'posn': 'upper left', 'texture': 'burlap', 'shape': 'SQUARE'} + See more examples at L{ParseResults} of accessing fields by results name. + """ + def __init__( self, expr ): + super(Dict,self).__init__( expr ) + self.saveAsList = True + + def postParse( self, instring, loc, tokenlist ): + for i,tok in enumerate(tokenlist): + if len(tok) == 0: + continue + ikey = tok[0] + if isinstance(ikey,int): + ikey = _ustr(tok[0]).strip() + if len(tok)==1: + tokenlist[ikey] = _ParseResultsWithOffset("",i) + elif len(tok)==2 and not isinstance(tok[1],ParseResults): + tokenlist[ikey] = _ParseResultsWithOffset(tok[1],i) + else: + dictvalue = tok.copy() #ParseResults(i) + del dictvalue[0] + if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.haskeys()): + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue,i) + else: + tokenlist[ikey] = _ParseResultsWithOffset(dictvalue[0],i) + + if self.resultsName: + return [ tokenlist ] + else: + return tokenlist + + +class Suppress(TokenConverter): + """ + Converter for ignoring the results of a parsed expression. + + Example:: + source = "a, b, c,d" + wd = Word(alphas) + wd_list1 = wd + ZeroOrMore(',' + wd) + print(wd_list1.parseString(source)) + + # often, delimiters that are useful during parsing are just in the + # way afterward - use Suppress to keep them out of the parsed output + wd_list2 = wd + ZeroOrMore(Suppress(',') + wd) + print(wd_list2.parseString(source)) + prints:: + ['a', ',', 'b', ',', 'c', ',', 'd'] + ['a', 'b', 'c', 'd'] + (See also L{delimitedList}.) + """ + def postParse( self, instring, loc, tokenlist ): + return [] + + def suppress( self ): + return self + + +class OnlyOnce(object): + """ + Wrapper for parse actions, to ensure they are only called once. + """ + def __init__(self, methodCall): + self.callable = _trim_arity(methodCall) + self.called = False + def __call__(self,s,l,t): + if not self.called: + results = self.callable(s,l,t) + self.called = True + return results + raise ParseException(s,l,"") + def reset(self): + self.called = False + +def traceParseAction(f): + """ + Decorator for debugging parse actions. + + When the parse action is called, this decorator will print C{">> entering I{method-name}(line:I{current_source_line}, I{parse_location}, I{matched_tokens})".} + When the parse action completes, the decorator will print C{"<<"} followed by the returned value, or any exception that the parse action raised. + + Example:: + wd = Word(alphas) + + @traceParseAction + def remove_duplicate_chars(tokens): + return ''.join(sorted(set(''.join(tokens)))) + + wds = OneOrMore(wd).setParseAction(remove_duplicate_chars) + print(wds.parseString("slkdjs sld sldd sdlf sdljf")) + prints:: + >>entering remove_duplicate_chars(line: 'slkdjs sld sldd sdlf sdljf', 0, (['slkdjs', 'sld', 'sldd', 'sdlf', 'sdljf'], {})) + <<leaving remove_duplicate_chars (ret: 'dfjkls') + ['dfjkls'] + """ + f = _trim_arity(f) + def z(*paArgs): + thisFunc = f.__name__ + s,l,t = paArgs[-3:] + if len(paArgs)>3: + thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc + sys.stderr.write( ">>entering %s(line: '%s', %d, %r)\n" % (thisFunc,line(l,s),l,t) ) + try: + ret = f(*paArgs) + except Exception as exc: + sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) ) + raise + sys.stderr.write( "<<leaving %s (ret: %r)\n" % (thisFunc,ret) ) + return ret + try: + z.__name__ = f.__name__ + except AttributeError: + pass + return z + +# +# global helpers +# +def delimitedList( expr, delim=",", combine=False ): + """ + Helper to define a delimited list of expressions - the delimiter defaults to ','. + By default, the list elements and delimiters can have intervening whitespace, and + comments, but this can be overridden by passing C{combine=True} in the constructor. + If C{combine} is set to C{True}, the matching tokens are returned as a single token + string, with the delimiters included; otherwise, the matching tokens are returned + as a list of tokens, with the delimiters suppressed. + + Example:: + delimitedList(Word(alphas)).parseString("aa,bb,cc") # -> ['aa', 'bb', 'cc'] + delimitedList(Word(hexnums), delim=':', combine=True).parseString("AA:BB:CC:DD:EE") # -> ['AA:BB:CC:DD:EE'] + """ + dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..." + if combine: + return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName) + else: + return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName) + +def countedArray( expr, intExpr=None ): + """ + Helper to define a counted list of expressions. + This helper defines a pattern of the form:: + integer expr expr expr... + where the leading integer tells how many expr expressions follow. + The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed. + + If C{intExpr} is specified, it should be a pyparsing expression that produces an integer value. + + Example:: + countedArray(Word(alphas)).parseString('2 ab cd ef') # -> ['ab', 'cd'] + + # in this parser, the leading integer value is given in binary, + # '10' indicating that 2 values are in the array + binaryConstant = Word('01').setParseAction(lambda t: int(t[0], 2)) + countedArray(Word(alphas), intExpr=binaryConstant).parseString('10 ab cd ef') # -> ['ab', 'cd'] + """ + arrayExpr = Forward() + def countFieldParseAction(s,l,t): + n = t[0] + arrayExpr << (n and Group(And([expr]*n)) or Group(empty)) + return [] + if intExpr is None: + intExpr = Word(nums).setParseAction(lambda t:int(t[0])) + else: + intExpr = intExpr.copy() + intExpr.setName("arrayLen") + intExpr.addParseAction(countFieldParseAction, callDuringTry=True) + return ( intExpr + arrayExpr ).setName('(len) ' + _ustr(expr) + '...') + +def _flatten(L): + ret = [] + for i in L: + if isinstance(i,list): + ret.extend(_flatten(i)) + else: + ret.append(i) + return ret + +def matchPreviousLiteral(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousLiteral(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches a + previous literal, will also match the leading C{"1:1"} in C{"1:10"}. + If this is not desired, use C{matchPreviousExpr}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + def copyTokenToRepeater(s,l,t): + if t: + if len(t) == 1: + rep << t[0] + else: + # flatten t tokens + tflat = _flatten(t.asList()) + rep << And(Literal(tt) for tt in tflat) + else: + rep << Empty() + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def matchPreviousExpr(expr): + """ + Helper to define an expression that is indirectly defined from + the tokens matched in a previous expression, that is, it looks + for a 'repeat' of a previous expression. For example:: + first = Word(nums) + second = matchPreviousExpr(first) + matchExpr = first + ":" + second + will match C{"1:1"}, but not C{"1:2"}. Because this matches by + expressions, will I{not} match the leading C{"1:1"} in C{"1:10"}; + the expressions are evaluated first, and then compared, so + C{"1"} is compared with C{"10"}. + Do I{not} use with packrat parsing enabled. + """ + rep = Forward() + e2 = expr.copy() + rep <<= e2 + def copyTokenToRepeater(s,l,t): + matchTokens = _flatten(t.asList()) + def mustMatchTheseTokens(s,l,t): + theseTokens = _flatten(t.asList()) + if theseTokens != matchTokens: + raise ParseException("",0,"") + rep.setParseAction( mustMatchTheseTokens, callDuringTry=True ) + expr.addParseAction(copyTokenToRepeater, callDuringTry=True) + rep.setName('(prev) ' + _ustr(expr)) + return rep + +def _escapeRegexRangeChars(s): + #~ escape these chars: ^-] + for c in r"\^-]": + s = s.replace(c,_bslash+c) + s = s.replace("\n",r"\n") + s = s.replace("\t",r"\t") + return _ustr(s) + +def oneOf( strs, caseless=False, useRegex=True ): + """ + Helper to quickly define a set of alternative Literals, and makes sure to do + longest-first testing when there is a conflict, regardless of the input order, + but returns a C{L{MatchFirst}} for best performance. + + Parameters: + - strs - a string of space-delimited literals, or a collection of string literals + - caseless - (default=C{False}) - treat all literals as caseless + - useRegex - (default=C{True}) - as an optimization, will generate a Regex + object; otherwise, will generate a C{MatchFirst} object (if C{caseless=True}, or + if creating a C{Regex} raises an exception) + + Example:: + comp_oper = oneOf("< = > <= >= !=") + var = Word(alphas) + number = Word(nums) + term = var | number + comparison_expr = term + comp_oper + term + print(comparison_expr.searchString("B = 12 AA=23 B<=AA AA>12")) + prints:: + [['B', '=', '12'], ['AA', '=', '23'], ['B', '<=', 'AA'], ['AA', '>', '12']] + """ + if caseless: + isequal = ( lambda a,b: a.upper() == b.upper() ) + masks = ( lambda a,b: b.upper().startswith(a.upper()) ) + parseElementClass = CaselessLiteral + else: + isequal = ( lambda a,b: a == b ) + masks = ( lambda a,b: b.startswith(a) ) + parseElementClass = Literal + + symbols = [] + if isinstance(strs,basestring): + symbols = strs.split() + elif isinstance(strs, Iterable): + symbols = list(strs) + else: + warnings.warn("Invalid argument to oneOf, expected string or iterable", + SyntaxWarning, stacklevel=2) + if not symbols: + return NoMatch() + + i = 0 + while i < len(symbols)-1: + cur = symbols[i] + for j,other in enumerate(symbols[i+1:]): + if ( isequal(other, cur) ): + del symbols[i+j+1] + break + elif ( masks(cur, other) ): + del symbols[i+j+1] + symbols.insert(i,other) + cur = other + break + else: + i += 1 + + if not caseless and useRegex: + #~ print (strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )) + try: + if len(symbols)==len("".join(symbols)): + return Regex( "[%s]" % "".join(_escapeRegexRangeChars(sym) for sym in symbols) ).setName(' | '.join(symbols)) + else: + return Regex( "|".join(re.escape(sym) for sym in symbols) ).setName(' | '.join(symbols)) + except Exception: + warnings.warn("Exception creating Regex for oneOf, building MatchFirst", + SyntaxWarning, stacklevel=2) + + + # last resort, just use MatchFirst + return MatchFirst(parseElementClass(sym) for sym in symbols).setName(' | '.join(symbols)) + +def dictOf( key, value ): + """ + Helper to easily and clearly define a dictionary by specifying the respective patterns + for the key and value. Takes care of defining the C{L{Dict}}, C{L{ZeroOrMore}}, and C{L{Group}} tokens + in the proper order. The key pattern can include delimiting markers or punctuation, + as long as they are suppressed, thereby leaving the significant key text. The value + pattern can include named results, so that the C{Dict} results can include named token + fields. + + Example:: + text = "shape: SQUARE posn: upper left color: light blue texture: burlap" + attr_expr = (label + Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join)) + print(OneOrMore(attr_expr).parseString(text).dump()) + + attr_label = label + attr_value = Suppress(':') + OneOrMore(data_word, stopOn=label).setParseAction(' '.join) + + # similar to Dict, but simpler call format + result = dictOf(attr_label, attr_value).parseString(text) + print(result.dump()) + print(result['shape']) + print(result.shape) # object attribute access works too + print(result.asDict()) + prints:: + [['shape', 'SQUARE'], ['posn', 'upper left'], ['color', 'light blue'], ['texture', 'burlap']] + - color: light blue + - posn: upper left + - shape: SQUARE + - texture: burlap + SQUARE + SQUARE + {'color': 'light blue', 'shape': 'SQUARE', 'posn': 'upper left', 'texture': 'burlap'} + """ + return Dict( ZeroOrMore( Group ( key + value ) ) ) + +def originalTextFor(expr, asString=True): + """ + Helper to return the original, untokenized text for a given expression. Useful to + restore the parsed fields of an HTML start tag into the raw tag text itself, or to + revert separate tokens with intervening whitespace back to the original matching + input text. By default, returns astring containing the original parsed text. + + If the optional C{asString} argument is passed as C{False}, then the return value is a + C{L{ParseResults}} containing any results names that were originally matched, and a + single token containing the original matched text from the input string. So if + the expression passed to C{L{originalTextFor}} contains expressions with defined + results names, you must set C{asString} to C{False} if you want to preserve those + results name values. + + Example:: + src = "this is test <b> bold <i>text</i> </b> normal text " + for tag in ("b","i"): + opener,closer = makeHTMLTags(tag) + patt = originalTextFor(opener + SkipTo(closer) + closer) + print(patt.searchString(src)[0]) + prints:: + ['<b> bold <i>text</i> </b>'] + ['<i>text</i>'] + """ + locMarker = Empty().setParseAction(lambda s,loc,t: loc) + endlocMarker = locMarker.copy() + endlocMarker.callPreparse = False + matchExpr = locMarker("_original_start") + expr + endlocMarker("_original_end") + if asString: + extractText = lambda s,l,t: s[t._original_start:t._original_end] + else: + def extractText(s,l,t): + t[:] = [s[t.pop('_original_start'):t.pop('_original_end')]] + matchExpr.setParseAction(extractText) + matchExpr.ignoreExprs = expr.ignoreExprs + return matchExpr + +def ungroup(expr): + """ + Helper to undo pyparsing's default grouping of And expressions, even + if all but one are non-empty. + """ + return TokenConverter(expr).setParseAction(lambda t:t[0]) + +def locatedExpr(expr): + """ + Helper to decorate a returned token with its starting and ending locations in the input string. + This helper adds the following results names: + - locn_start = location where matched expression begins + - locn_end = location where matched expression ends + - value = the actual parsed results + + Be careful if the input text contains C{<TAB>} characters, you may want to call + C{L{ParserElement.parseWithTabs}} + + Example:: + wd = Word(alphas) + for match in locatedExpr(wd).searchString("ljsdf123lksdjjf123lkkjj1222"): + print(match) + prints:: + [[0, 'ljsdf', 5]] + [[8, 'lksdjjf', 15]] + [[18, 'lkkjj', 23]] + """ + locator = Empty().setParseAction(lambda s,l,t: l) + return Group(locator("locn_start") + expr("value") + locator.copy().leaveWhitespace()("locn_end")) + + +# convenience constants for positional expressions +empty = Empty().setName("empty") +lineStart = LineStart().setName("lineStart") +lineEnd = LineEnd().setName("lineEnd") +stringStart = StringStart().setName("stringStart") +stringEnd = StringEnd().setName("stringEnd") + +_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1]) +_escapedHexChar = Regex(r"\\0?[xX][0-9a-fA-F]+").setParseAction(lambda s,l,t:unichr(int(t[0].lstrip(r'\0x'),16))) +_escapedOctChar = Regex(r"\\0[0-7]+").setParseAction(lambda s,l,t:unichr(int(t[0][1:],8))) +_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | CharsNotIn(r'\]', exact=1) +_charRange = Group(_singleChar + Suppress("-") + _singleChar) +_reBracketExpr = Literal("[") + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]" + +def srange(s): + r""" + Helper to easily define string ranges for use in Word construction. Borrows + syntax from regexp '[]' string range definitions:: + srange("[0-9]") -> "0123456789" + srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz" + srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_" + The input string must be enclosed in []'s, and the returned string is the expanded + character set joined into a single string. + The values enclosed in the []'s may be: + - a single character + - an escaped character with a leading backslash (such as C{\-} or C{\]}) + - an escaped hex character with a leading C{'\x'} (C{\x21}, which is a C{'!'} character) + (C{\0x##} is also supported for backwards compatibility) + - an escaped octal character with a leading C{'\0'} (C{\041}, which is a C{'!'} character) + - a range of any of the above, separated by a dash (C{'a-z'}, etc.) + - any combination of the above (C{'aeiouy'}, C{'a-zA-Z0-9_$'}, etc.) + """ + _expanded = lambda p: p if not isinstance(p,ParseResults) else ''.join(unichr(c) for c in range(ord(p[0]),ord(p[1])+1)) + try: + return "".join(_expanded(part) for part in _reBracketExpr.parseString(s).body) + except Exception: + return "" + +def matchOnlyAtCol(n): + """ + Helper method for defining parse actions that require matching at a specific + column in the input text. + """ + def verifyCol(strg,locn,toks): + if col(locn,strg) != n: + raise ParseException(strg,locn,"matched token not at column %d" % n) + return verifyCol + +def replaceWith(replStr): + """ + Helper method for common parse actions that simply return a literal value. Especially + useful when used with C{L{transformString<ParserElement.transformString>}()}. + + Example:: + num = Word(nums).setParseAction(lambda toks: int(toks[0])) + na = oneOf("N/A NA").setParseAction(replaceWith(math.nan)) + term = na | num + + OneOrMore(term).parseString("324 234 N/A 234") # -> [324, 234, nan, 234] + """ + return lambda s,l,t: [replStr] + +def removeQuotes(s,l,t): + """ + Helper parse action for removing quotation marks from parsed quoted strings. + + Example:: + # by default, quotation marks are included in parsed results + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["'Now is the Winter of our Discontent'"] + + # use removeQuotes to strip quotation marks from parsed results + quotedString.setParseAction(removeQuotes) + quotedString.parseString("'Now is the Winter of our Discontent'") # -> ["Now is the Winter of our Discontent"] + """ + return t[0][1:-1] + +def tokenMap(func, *args): + """ + Helper to define a parse action by mapping a function to all elements of a ParseResults list.If any additional + args are passed, they are forwarded to the given function as additional arguments after + the token, as in C{hex_integer = Word(hexnums).setParseAction(tokenMap(int, 16))}, which will convert the + parsed data to an integer using base 16. + + Example (compare the last to example in L{ParserElement.transformString}:: + hex_ints = OneOrMore(Word(hexnums)).setParseAction(tokenMap(int, 16)) + hex_ints.runTests(''' + 00 11 22 aa FF 0a 0d 1a + ''') + + upperword = Word(alphas).setParseAction(tokenMap(str.upper)) + OneOrMore(upperword).runTests(''' + my kingdom for a horse + ''') + + wd = Word(alphas).setParseAction(tokenMap(str.title)) + OneOrMore(wd).setParseAction(' '.join).runTests(''' + now is the winter of our discontent made glorious summer by this sun of york + ''') + prints:: + 00 11 22 aa FF 0a 0d 1a + [0, 17, 34, 170, 255, 10, 13, 26] + + my kingdom for a horse + ['MY', 'KINGDOM', 'FOR', 'A', 'HORSE'] + + now is the winter of our discontent made glorious summer by this sun of york + ['Now Is The Winter Of Our Discontent Made Glorious Summer By This Sun Of York'] + """ + def pa(s,l,t): + return [func(tokn, *args) for tokn in t] + + try: + func_name = getattr(func, '__name__', + getattr(func, '__class__').__name__) + except Exception: + func_name = str(func) + pa.__name__ = func_name + + return pa + +upcaseTokens = tokenMap(lambda t: _ustr(t).upper()) +"""(Deprecated) Helper parse action to convert tokens to upper case. Deprecated in favor of L{pyparsing_common.upcaseTokens}""" + +downcaseTokens = tokenMap(lambda t: _ustr(t).lower()) +"""(Deprecated) Helper parse action to convert tokens to lower case. Deprecated in favor of L{pyparsing_common.downcaseTokens}""" + +def _makeTags(tagStr, xml): + """Internal helper to construct opening and closing tag expressions, given a tag name""" + if isinstance(tagStr,basestring): + resname = tagStr + tagStr = Keyword(tagStr, caseless=not xml) + else: + resname = tagStr.name + + tagAttrName = Word(alphas,alphanums+"_-:") + if (xml): + tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes ) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + else: + printablesLessRAbrack = "".join(c for c in printables if c not in ">") + tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack) + openTag = Suppress("<") + tagStr("tag") + \ + Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \ + Optional( Suppress("=") + tagAttrValue ) ))) + \ + Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">") + closeTag = Combine(_L("</") + tagStr + ">") + + openTag = openTag.setResultsName("start"+"".join(resname.replace(":"," ").title().split())).setName("<%s>" % resname) + closeTag = closeTag.setResultsName("end"+"".join(resname.replace(":"," ").title().split())).setName("</%s>" % resname) + openTag.tag = resname + closeTag.tag = resname + return openTag, closeTag + +def makeHTMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for HTML, given a tag name. Matches + tags in either upper or lower case, attributes with namespaces and with quoted or unquoted values. + + Example:: + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + # makeHTMLTags returns pyparsing expressions for the opening and closing tags as a 2-tuple + a,a_end = makeHTMLTags("A") + link_expr = a + SkipTo(a_end)("link_text") + a_end + + for link in link_expr.searchString(text): + # attributes in the <A> tag (like "href" shown here) are also accessible as named results + print(link.link_text, '->', link.href) + prints:: + pyparsing -> http://pyparsing.wikispaces.com + """ + return _makeTags( tagStr, False ) + +def makeXMLTags(tagStr): + """ + Helper to construct opening and closing tag expressions for XML, given a tag name. Matches + tags only in the given upper/lower case. + + Example: similar to L{makeHTMLTags} + """ + return _makeTags( tagStr, True ) + +def withAttribute(*args,**attrDict): + """ + Helper to create a validating parse action to be used with start tags created + with C{L{makeXMLTags}} or C{L{makeHTMLTags}}. Use C{withAttribute} to qualify a starting tag + with a required attribute value, to avoid false matches on common tags such as + C{<TD>} or C{<DIV>}. + + Call C{withAttribute} with a series of attribute names and values. Specify the list + of filter attributes names and values as: + - keyword arguments, as in C{(align="right")}, or + - as an explicit dict with C{**} operator, when an attribute name is also a Python + reserved word, as in C{**{"class":"Customer", "align":"right"}} + - a list of name-value tuples, as in ( ("ns1:class", "Customer"), ("ns2:align","right") ) + For attribute names with a namespace prefix, you must use the second form. Attribute + names are matched insensitive to upper/lower case. + + If just testing for C{class} (with or without a namespace), use C{L{withClass}}. + + To verify that the attribute exists, but without specifying a value, pass + C{withAttribute.ANY_VALUE} as the value. + + Example:: + html = ''' + <div> + Some text + <div type="grid">1 4 0 1 0</div> + <div type="graph">1,3 2,3 1,1</div> + <div>this has no type</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + + # only match div tag having a type attribute with value "grid" + div_grid = div().setParseAction(withAttribute(type="grid")) + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + # construct a match with any div tag having a type attribute, regardless of the value + div_any_type = div().setParseAction(withAttribute(type=withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + if args: + attrs = args[:] + else: + attrs = attrDict.items() + attrs = [(k,v) for k,v in attrs] + def pa(s,l,tokens): + for attrName,attrValue in attrs: + if attrName not in tokens: + raise ParseException(s,l,"no matching attribute " + attrName) + if attrValue != withAttribute.ANY_VALUE and tokens[attrName] != attrValue: + raise ParseException(s,l,"attribute '%s' has value '%s', must be '%s'" % + (attrName, tokens[attrName], attrValue)) + return pa +withAttribute.ANY_VALUE = object() + +def withClass(classname, namespace=''): + """ + Simplified version of C{L{withAttribute}} when matching on a div class - made + difficult because C{class} is a reserved word in Python. + + Example:: + html = ''' + <div> + Some text + <div class="grid">1 4 0 1 0</div> + <div class="graph">1,3 2,3 1,1</div> + <div>this <div> has no class</div> + </div> + + ''' + div,div_end = makeHTMLTags("div") + div_grid = div().setParseAction(withClass("grid")) + + grid_expr = div_grid + SkipTo(div | div_end)("body") + for grid_header in grid_expr.searchString(html): + print(grid_header.body) + + div_any_type = div().setParseAction(withClass(withAttribute.ANY_VALUE)) + div_expr = div_any_type + SkipTo(div | div_end)("body") + for div_header in div_expr.searchString(html): + print(div_header.body) + prints:: + 1 4 0 1 0 + + 1 4 0 1 0 + 1,3 2,3 1,1 + """ + classattr = "%s:class" % namespace if namespace else "class" + return withAttribute(**{classattr : classname}) + +opAssoc = _Constants() +opAssoc.LEFT = object() +opAssoc.RIGHT = object() + +def infixNotation( baseExpr, opList, lpar=Suppress('('), rpar=Suppress(')') ): + """ + Helper method for constructing grammars of expressions made up of + operators working in a precedence hierarchy. Operators may be unary or + binary, left- or right-associative. Parse actions can also be attached + to operator expressions. The generated parser will also recognize the use + of parentheses to override operator precedences (see example below). + + Note: if you define a deep operator list, you may see performance issues + when using infixNotation. See L{ParserElement.enablePackrat} for a + mechanism to potentially improve your parser performance. + + Parameters: + - baseExpr - expression representing the most basic element for the nested + - opList - list of tuples, one for each operator precedence level in the + expression grammar; each tuple is of the form + (opExpr, numTerms, rightLeftAssoc, parseAction), where: + - opExpr is the pyparsing expression for the operator; + may also be a string, which will be converted to a Literal; + if numTerms is 3, opExpr is a tuple of two expressions, for the + two operators separating the 3 terms + - numTerms is the number of terms for this operator (must + be 1, 2, or 3) + - rightLeftAssoc is the indicator whether the operator is + right or left associative, using the pyparsing-defined + constants C{opAssoc.RIGHT} and C{opAssoc.LEFT}. + - parseAction is the parse action to be associated with + expressions matching this operator expression (the + parse action tuple member may be omitted); if the parse action + is passed a tuple or list of functions, this is equivalent to + calling C{setParseAction(*fn)} (L{ParserElement.setParseAction}) + - lpar - expression for matching left-parentheses (default=C{Suppress('(')}) + - rpar - expression for matching right-parentheses (default=C{Suppress(')')}) + + Example:: + # simple example of four-function arithmetic with ints and variable names + integer = pyparsing_common.signed_integer + varname = pyparsing_common.identifier + + arith_expr = infixNotation(integer | varname, + [ + ('-', 1, opAssoc.RIGHT), + (oneOf('* /'), 2, opAssoc.LEFT), + (oneOf('+ -'), 2, opAssoc.LEFT), + ]) + + arith_expr.runTests(''' + 5+3*6 + (5+3)*6 + -2--11 + ''', fullDump=False) + prints:: + 5+3*6 + [[5, '+', [3, '*', 6]]] + + (5+3)*6 + [[[5, '+', 3], '*', 6]] + + -2--11 + [[['-', 2], '-', ['-', 11]]] + """ + ret = Forward() + lastExpr = baseExpr | ( lpar + ret + rpar ) + for i,operDef in enumerate(opList): + opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4] + termName = "%s term" % opExpr if arity < 3 else "%s%s term" % opExpr + if arity == 3: + if opExpr is None or len(opExpr) != 2: + raise ValueError("if numterms=3, opExpr must be a tuple or list of two expressions") + opExpr1, opExpr2 = opExpr + thisExpr = Forward().setName(termName) + if rightLeftAssoc == opAssoc.LEFT: + if arity == 1: + matchExpr = FollowedBy(lastExpr + opExpr) + Group( lastExpr + OneOrMore( opExpr ) ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + lastExpr) + Group( lastExpr + OneOrMore( opExpr + lastExpr ) ) + else: + matchExpr = FollowedBy(lastExpr+lastExpr) + Group( lastExpr + OneOrMore(lastExpr) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr) + \ + Group( lastExpr + opExpr1 + lastExpr + opExpr2 + lastExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + elif rightLeftAssoc == opAssoc.RIGHT: + if arity == 1: + # try to avoid LR with this extra test + if not isinstance(opExpr, Optional): + opExpr = Optional(opExpr) + matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr ) + elif arity == 2: + if opExpr is not None: + matchExpr = FollowedBy(lastExpr + opExpr + thisExpr) + Group( lastExpr + OneOrMore( opExpr + thisExpr ) ) + else: + matchExpr = FollowedBy(lastExpr + thisExpr) + Group( lastExpr + OneOrMore( thisExpr ) ) + elif arity == 3: + matchExpr = FollowedBy(lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr) + \ + Group( lastExpr + opExpr1 + thisExpr + opExpr2 + thisExpr ) + else: + raise ValueError("operator must be unary (1), binary (2), or ternary (3)") + else: + raise ValueError("operator must indicate right or left associativity") + if pa: + if isinstance(pa, (tuple, list)): + matchExpr.setParseAction(*pa) + else: + matchExpr.setParseAction(pa) + thisExpr <<= ( matchExpr.setName(termName) | lastExpr ) + lastExpr = thisExpr + ret <<= lastExpr + return ret + +operatorPrecedence = infixNotation +"""(Deprecated) Former name of C{L{infixNotation}}, will be dropped in a future release.""" + +dblQuotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"').setName("string enclosed in double quotes") +sglQuotedString = Combine(Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("string enclosed in single quotes") +quotedString = Combine(Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*')+'"'| + Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\(?:[^x]|x[0-9a-fA-F]+)))*")+"'").setName("quotedString using single or double quotes") +unicodeString = Combine(_L('u') + quotedString.copy()).setName("unicode string literal") + +def nestedExpr(opener="(", closer=")", content=None, ignoreExpr=quotedString.copy()): + """ + Helper method for defining nested lists enclosed in opening and closing + delimiters ("(" and ")" are the default). + + Parameters: + - opener - opening character for a nested list (default=C{"("}); can also be a pyparsing expression + - closer - closing character for a nested list (default=C{")"}); can also be a pyparsing expression + - content - expression for items within the nested lists (default=C{None}) + - ignoreExpr - expression for ignoring opening and closing delimiters (default=C{quotedString}) + + If an expression is not provided for the content argument, the nested + expression will capture all whitespace-delimited content between delimiters + as a list of separate values. + + Use the C{ignoreExpr} argument to define expressions that may contain + opening or closing characters that should not be treated as opening + or closing characters for nesting, such as quotedString or a comment + expression. Specify multiple expressions using an C{L{Or}} or C{L{MatchFirst}}. + The default is L{quotedString}, but if no expressions are to be ignored, + then pass C{None} for this argument. + + Example:: + data_type = oneOf("void int short long char float double") + decl_data_type = Combine(data_type + Optional(Word('*'))) + ident = Word(alphas+'_', alphanums+'_') + number = pyparsing_common.number + arg = Group(decl_data_type + ident) + LPAR,RPAR = map(Suppress, "()") + + code_body = nestedExpr('{', '}', ignoreExpr=(quotedString | cStyleComment)) + + c_function = (decl_data_type("type") + + ident("name") + + LPAR + Optional(delimitedList(arg), [])("args") + RPAR + + code_body("body")) + c_function.ignore(cStyleComment) + + source_code = ''' + int is_odd(int x) { + return (x%2); + } + + int dec_to_hex(char hchar) { + if (hchar >= '0' && hchar <= '9') { + return (ord(hchar)-ord('0')); + } else { + return (10+ord(hchar)-ord('A')); + } + } + ''' + for func in c_function.searchString(source_code): + print("%(name)s (%(type)s) args: %(args)s" % func) + + prints:: + is_odd (int) args: [['int', 'x']] + dec_to_hex (int) args: [['char', 'hchar']] + """ + if opener == closer: + raise ValueError("opening and closing strings cannot be the same") + if content is None: + if isinstance(opener,basestring) and isinstance(closer,basestring): + if len(opener) == 1 and len(closer)==1: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (empty.copy()+CharsNotIn(opener+closer+ParserElement.DEFAULT_WHITE_CHARS + ).setParseAction(lambda t:t[0].strip())) + else: + if ignoreExpr is not None: + content = (Combine(OneOrMore(~ignoreExpr + + ~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + content = (Combine(OneOrMore(~Literal(opener) + ~Literal(closer) + + CharsNotIn(ParserElement.DEFAULT_WHITE_CHARS,exact=1)) + ).setParseAction(lambda t:t[0].strip())) + else: + raise ValueError("opening and closing arguments must be strings if no content expression is given") + ret = Forward() + if ignoreExpr is not None: + ret <<= Group( Suppress(opener) + ZeroOrMore( ignoreExpr | ret | content ) + Suppress(closer) ) + else: + ret <<= Group( Suppress(opener) + ZeroOrMore( ret | content ) + Suppress(closer) ) + ret.setName('nested %s%s expression' % (opener,closer)) + return ret + +def indentedBlock(blockStatementExpr, indentStack, indent=True): + """ + Helper method for defining space-delimited indentation blocks, such as + those used to define block statements in Python source code. + + Parameters: + - blockStatementExpr - expression defining syntax of statement that + is repeated within the indented block + - indentStack - list created by caller to manage indentation stack + (multiple statementWithIndentedBlock expressions within a single grammar + should share a common indentStack) + - indent - boolean indicating whether block must be indented beyond the + the current level; set to False for block of left-most statements + (default=C{True}) + + A valid block must contain at least one C{blockStatement}. + + Example:: + data = ''' + def A(z): + A1 + B = 100 + G = A2 + A2 + A3 + B + def BB(a,b,c): + BB1 + def BBA(): + bba1 + bba2 + bba3 + C + D + def spam(x,y): + def eggs(z): + pass + ''' + + + indentStack = [1] + stmt = Forward() + + identifier = Word(alphas, alphanums) + funcDecl = ("def" + identifier + Group( "(" + Optional( delimitedList(identifier) ) + ")" ) + ":") + func_body = indentedBlock(stmt, indentStack) + funcDef = Group( funcDecl + func_body ) + + rvalue = Forward() + funcCall = Group(identifier + "(" + Optional(delimitedList(rvalue)) + ")") + rvalue << (funcCall | identifier | Word(nums)) + assignment = Group(identifier + "=" + rvalue) + stmt << ( funcDef | assignment | identifier ) + + module_body = OneOrMore(stmt) + + parseTree = module_body.parseString(data) + parseTree.pprint() + prints:: + [['def', + 'A', + ['(', 'z', ')'], + ':', + [['A1'], [['B', '=', '100']], [['G', '=', 'A2']], ['A2'], ['A3']]], + 'B', + ['def', + 'BB', + ['(', 'a', 'b', 'c', ')'], + ':', + [['BB1'], [['def', 'BBA', ['(', ')'], ':', [['bba1'], ['bba2'], ['bba3']]]]]], + 'C', + 'D', + ['def', + 'spam', + ['(', 'x', 'y', ')'], + ':', + [[['def', 'eggs', ['(', 'z', ')'], ':', [['pass']]]]]]] + """ + def checkPeerIndent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if curCol != indentStack[-1]: + if curCol > indentStack[-1]: + raise ParseFatalException(s,l,"illegal nesting") + raise ParseException(s,l,"not a peer entry") + + def checkSubIndent(s,l,t): + curCol = col(l,s) + if curCol > indentStack[-1]: + indentStack.append( curCol ) + else: + raise ParseException(s,l,"not a subentry") + + def checkUnindent(s,l,t): + if l >= len(s): return + curCol = col(l,s) + if not(indentStack and curCol < indentStack[-1] and curCol <= indentStack[-2]): + raise ParseException(s,l,"not an unindent") + indentStack.pop() + + NL = OneOrMore(LineEnd().setWhitespaceChars("\t ").suppress()) + INDENT = (Empty() + Empty().setParseAction(checkSubIndent)).setName('INDENT') + PEER = Empty().setParseAction(checkPeerIndent).setName('') + UNDENT = Empty().setParseAction(checkUnindent).setName('UNINDENT') + if indent: + smExpr = Group( Optional(NL) + + #~ FollowedBy(blockStatementExpr) + + INDENT + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) + UNDENT) + else: + smExpr = Group( Optional(NL) + + (OneOrMore( PEER + Group(blockStatementExpr) + Optional(NL) )) ) + blockStatementExpr.ignore(_bslash + LineEnd()) + return smExpr.setName('indented block') + +alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xff]") +punc8bit = srange(r"[\0xa1-\0xbf\0xd7\0xf7]") + +anyOpenTag,anyCloseTag = makeHTMLTags(Word(alphas,alphanums+"_:").setName('any tag')) +_htmlEntityMap = dict(zip("gt lt amp nbsp quot apos".split(),'><& "\'')) +commonHTMLEntity = Regex('&(?P<entity>' + '|'.join(_htmlEntityMap.keys()) +");").setName("common HTML entity") +def replaceHTMLEntity(t): + """Helper parser action to replace common HTML entities with their special characters""" + return _htmlEntityMap.get(t.entity) + +# it's easy to get these comment structures wrong - they're very common, so may as well make them available +cStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/').setName("C style comment") +"Comment of the form C{/* ... */}" + +htmlComment = Regex(r"<!--[\s\S]*?-->").setName("HTML comment") +"Comment of the form C{<!-- ... -->}" + +restOfLine = Regex(r".*").leaveWhitespace().setName("rest of line") +dblSlashComment = Regex(r"//(?:\\\n|[^\n])*").setName("// comment") +"Comment of the form C{// ... (to end of line)}" + +cppStyleComment = Combine(Regex(r"/\*(?:[^*]|\*(?!/))*") + '*/'| dblSlashComment).setName("C++ style comment") +"Comment of either form C{L{cStyleComment}} or C{L{dblSlashComment}}" + +javaStyleComment = cppStyleComment +"Same as C{L{cppStyleComment}}" + +pythonStyleComment = Regex(r"#.*").setName("Python style comment") +"Comment of the form C{# ... (to end of line)}" + +_commasepitem = Combine(OneOrMore(Word(printables, excludeChars=',') + + Optional( Word(" \t") + + ~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem") +commaSeparatedList = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("commaSeparatedList") +"""(Deprecated) Predefined expression of 1 or more printable words or quoted strings, separated by commas. + This expression is deprecated in favor of L{pyparsing_common.comma_separated_list}.""" + +# some other useful expressions - using lower-case class name since we are really using this as a namespace +class pyparsing_common: + """ + Here are some common low-level expressions that may be useful in jump-starting parser development: + - numeric forms (L{integers<integer>}, L{reals<real>}, L{scientific notation<sci_real>}) + - common L{programming identifiers<identifier>} + - network addresses (L{MAC<mac_address>}, L{IPv4<ipv4_address>}, L{IPv6<ipv6_address>}) + - ISO8601 L{dates<iso8601_date>} and L{datetime<iso8601_datetime>} + - L{UUID<uuid>} + - L{comma-separated list<comma_separated_list>} + Parse actions: + - C{L{convertToInteger}} + - C{L{convertToFloat}} + - C{L{convertToDate}} + - C{L{convertToDatetime}} + - C{L{stripHTMLTags}} + - C{L{upcaseTokens}} + - C{L{downcaseTokens}} + + Example:: + pyparsing_common.number.runTests(''' + # any int or real number, returned as the appropriate type + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.fnumber.runTests(''' + # any int or real number, returned as float + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + ''') + + pyparsing_common.hex_integer.runTests(''' + # hex numbers + 100 + FF + ''') + + pyparsing_common.fraction.runTests(''' + # fractions + 1/2 + -3/4 + ''') + + pyparsing_common.mixed_integer.runTests(''' + # mixed fractions + 1 + 1/2 + -3/4 + 1-3/4 + ''') + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(''' + # uuid + 12345678-1234-5678-1234-567812345678 + ''') + prints:: + # any int or real number, returned as the appropriate type + 100 + [100] + + -100 + [-100] + + +100 + [100] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # any int or real number, returned as float + 100 + [100.0] + + -100 + [-100.0] + + +100 + [100.0] + + 3.14159 + [3.14159] + + 6.02e23 + [6.02e+23] + + 1e-12 + [1e-12] + + # hex numbers + 100 + [256] + + FF + [255] + + # fractions + 1/2 + [0.5] + + -3/4 + [-0.75] + + # mixed fractions + 1 + [1] + + 1/2 + [0.5] + + -3/4 + [-0.75] + + 1-3/4 + [1.75] + + # uuid + 12345678-1234-5678-1234-567812345678 + [UUID('12345678-1234-5678-1234-567812345678')] + """ + + convertToInteger = tokenMap(int) + """ + Parse action for converting parsed integers to Python int + """ + + convertToFloat = tokenMap(float) + """ + Parse action for converting parsed numbers to Python float + """ + + integer = Word(nums).setName("integer").setParseAction(convertToInteger) + """expression that parses an unsigned integer, returns an int""" + + hex_integer = Word(hexnums).setName("hex integer").setParseAction(tokenMap(int,16)) + """expression that parses a hexadecimal integer, returns an int""" + + signed_integer = Regex(r'[+-]?\d+').setName("signed integer").setParseAction(convertToInteger) + """expression that parses an integer with optional leading sign, returns an int""" + + fraction = (signed_integer().setParseAction(convertToFloat) + '/' + signed_integer().setParseAction(convertToFloat)).setName("fraction") + """fractional expression of an integer divided by an integer, returns a float""" + fraction.addParseAction(lambda t: t[0]/t[-1]) + + mixed_integer = (fraction | signed_integer + Optional(Optional('-').suppress() + fraction)).setName("fraction or mixed integer-fraction") + """mixed integer of the form 'integer - fraction', with optional leading integer, returns float""" + mixed_integer.addParseAction(sum) + + real = Regex(r'[+-]?\d+\.\d*').setName("real number").setParseAction(convertToFloat) + """expression that parses a floating point number and returns a float""" + + sci_real = Regex(r'[+-]?\d+([eE][+-]?\d+|\.\d*([eE][+-]?\d+)?)').setName("real number with scientific notation").setParseAction(convertToFloat) + """expression that parses a floating point number with optional scientific notation and returns a float""" + + # streamlining this expression makes the docs nicer-looking + number = (sci_real | real | signed_integer).streamline() + """any numeric expression, returns the corresponding Python type""" + + fnumber = Regex(r'[+-]?\d+\.?\d*([eE][+-]?\d+)?').setName("fnumber").setParseAction(convertToFloat) + """any int or real number, returned as float""" + + identifier = Word(alphas+'_', alphanums+'_').setName("identifier") + """typical code identifier (leading alpha or '_', followed by 0 or more alphas, nums, or '_')""" + + ipv4_address = Regex(r'(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})(\.(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})){3}').setName("IPv4 address") + "IPv4 address (C{0.0.0.0 - 255.255.255.255})" + + _ipv6_part = Regex(r'[0-9a-fA-F]{1,4}').setName("hex_integer") + _full_ipv6_address = (_ipv6_part + (':' + _ipv6_part)*7).setName("full IPv6 address") + _short_ipv6_address = (Optional(_ipv6_part + (':' + _ipv6_part)*(0,6)) + "::" + Optional(_ipv6_part + (':' + _ipv6_part)*(0,6))).setName("short IPv6 address") + _short_ipv6_address.addCondition(lambda t: sum(1 for tt in t if pyparsing_common._ipv6_part.matches(tt)) < 8) + _mixed_ipv6_address = ("::ffff:" + ipv4_address).setName("mixed IPv6 address") + ipv6_address = Combine((_full_ipv6_address | _mixed_ipv6_address | _short_ipv6_address).setName("IPv6 address")).setName("IPv6 address") + "IPv6 address (long, short, or mixed form)" + + mac_address = Regex(r'[0-9a-fA-F]{2}([:.-])[0-9a-fA-F]{2}(?:\1[0-9a-fA-F]{2}){4}').setName("MAC address") + "MAC address xx:xx:xx:xx:xx (may also have '-' or '.' delimiters)" + + @staticmethod + def convertToDate(fmt="%Y-%m-%d"): + """ + Helper to create a parse action for converting parsed date string to Python datetime.date + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%d"}) + + Example:: + date_expr = pyparsing_common.iso8601_date.copy() + date_expr.setParseAction(pyparsing_common.convertToDate()) + print(date_expr.parseString("1999-12-31")) + prints:: + [datetime.date(1999, 12, 31)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt).date() + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + @staticmethod + def convertToDatetime(fmt="%Y-%m-%dT%H:%M:%S.%f"): + """ + Helper to create a parse action for converting parsed datetime string to Python datetime.datetime + + Params - + - fmt - format to be passed to datetime.strptime (default=C{"%Y-%m-%dT%H:%M:%S.%f"}) + + Example:: + dt_expr = pyparsing_common.iso8601_datetime.copy() + dt_expr.setParseAction(pyparsing_common.convertToDatetime()) + print(dt_expr.parseString("1999-12-31T23:59:59.999")) + prints:: + [datetime.datetime(1999, 12, 31, 23, 59, 59, 999000)] + """ + def cvt_fn(s,l,t): + try: + return datetime.strptime(t[0], fmt) + except ValueError as ve: + raise ParseException(s, l, str(ve)) + return cvt_fn + + iso8601_date = Regex(r'(?P<year>\d{4})(?:-(?P<month>\d\d)(?:-(?P<day>\d\d))?)?').setName("ISO8601 date") + "ISO8601 date (C{yyyy-mm-dd})" + + iso8601_datetime = Regex(r'(?P<year>\d{4})-(?P<month>\d\d)-(?P<day>\d\d)[T ](?P<hour>\d\d):(?P<minute>\d\d)(:(?P<second>\d\d(\.\d*)?)?)?(?P<tz>Z|[+-]\d\d:?\d\d)?').setName("ISO8601 datetime") + "ISO8601 datetime (C{yyyy-mm-ddThh:mm:ss.s(Z|+-00:00)}) - trailing seconds, milliseconds, and timezone optional; accepts separating C{'T'} or C{' '}" + + uuid = Regex(r'[0-9a-fA-F]{8}(-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}').setName("UUID") + "UUID (C{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx})" + + _html_stripper = anyOpenTag.suppress() | anyCloseTag.suppress() + @staticmethod + def stripHTMLTags(s, l, tokens): + """ + Parse action to remove HTML tags from web page HTML source + + Example:: + # strip HTML links from normal text + text = '<td>More info at the <a href="http://pyparsing.wikispaces.com">pyparsing</a> wiki page</td>' + td,td_end = makeHTMLTags("TD") + table_text = td + SkipTo(td_end).setParseAction(pyparsing_common.stripHTMLTags)("body") + td_end + + print(table_text.parseString(text).body) # -> 'More info at the pyparsing wiki page' + """ + return pyparsing_common._html_stripper.transformString(tokens[0]) + + _commasepitem = Combine(OneOrMore(~Literal(",") + ~LineEnd() + Word(printables, excludeChars=',') + + Optional( White(" \t") ) ) ).streamline().setName("commaItem") + comma_separated_list = delimitedList( Optional( quotedString.copy() | _commasepitem, default="") ).setName("comma separated list") + """Predefined expression of 1 or more printable words or quoted strings, separated by commas.""" + + upcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).upper())) + """Parse action to convert tokens to upper case.""" + + downcaseTokens = staticmethod(tokenMap(lambda t: _ustr(t).lower())) + """Parse action to convert tokens to lower case.""" + + +if __name__ == "__main__": + + selectToken = CaselessLiteral("select") + fromToken = CaselessLiteral("from") + + ident = Word(alphas, alphanums + "_$") + + columnName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + columnNameList = Group(delimitedList(columnName)).setName("columns") + columnSpec = ('*' | columnNameList) + + tableName = delimitedList(ident, ".", combine=True).setParseAction(upcaseTokens) + tableNameList = Group(delimitedList(tableName)).setName("tables") + + simpleSQL = selectToken("command") + columnSpec("columns") + fromToken + tableNameList("tables") + + # demo runTests method, including embedded comments in test string + simpleSQL.runTests(""" + # '*' as column list and dotted table name + select * from SYS.XYZZY + + # caseless match on "SELECT", and casts back to "select" + SELECT * from XYZZY, ABC + + # list of column names, and mixed case SELECT keyword + Select AA,BB,CC from Sys.dual + + # multiple tables + Select A, B, C from Sys.dual, Table2 + + # invalid SELECT keyword - should fail + Xelect A, B, C from Sys.dual + + # incomplete command - should fail + Select + + # invalid column name - should fail + Select ^^^ frox Sys.dual + + """) + + pyparsing_common.number.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + # any int or real number, returned as float + pyparsing_common.fnumber.runTests(""" + 100 + -100 + +100 + 3.14159 + 6.02e23 + 1e-12 + """) + + pyparsing_common.hex_integer.runTests(""" + 100 + FF + """) + + import uuid + pyparsing_common.uuid.setParseAction(tokenMap(uuid.UUID)) + pyparsing_common.uuid.runTests(""" + 12345678-1234-5678-1234-567812345678 + """) diff --git a/env/lib/python3.7/site-packages/setuptools/_vendor/six.py b/env/lib/python3.7/site-packages/setuptools/_vendor/six.py new file mode 100644 index 0000000..190c023 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/_vendor/six.py @@ -0,0 +1,868 @@ +"""Utilities for writing code that runs on Python 2 and 3""" + +# Copyright (c) 2010-2015 Benjamin Peterson +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +from __future__ import absolute_import + +import functools +import itertools +import operator +import sys +import types + +__author__ = "Benjamin Peterson <benjamin@python.org>" +__version__ = "1.10.0" + + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 +PY34 = sys.version_info[0:2] >= (3, 4) + +if PY3: + string_types = str, + integer_types = int, + class_types = type, + text_type = str + binary_type = bytes + + MAXSIZE = sys.maxsize +else: + string_types = basestring, + integer_types = (int, long) + class_types = (type, types.ClassType) + text_type = unicode + binary_type = str + + if sys.platform.startswith("java"): + # Jython always uses 32 bits. + MAXSIZE = int((1 << 31) - 1) + else: + # It's possible to have sizeof(long) != sizeof(Py_ssize_t). + class X(object): + + def __len__(self): + return 1 << 31 + try: + len(X()) + except OverflowError: + # 32-bit + MAXSIZE = int((1 << 31) - 1) + else: + # 64-bit + MAXSIZE = int((1 << 63) - 1) + del X + + +def _add_doc(func, doc): + """Add documentation to a function.""" + func.__doc__ = doc + + +def _import_module(name): + """Import module, returning the module after the last dot.""" + __import__(name) + return sys.modules[name] + + +class _LazyDescr(object): + + def __init__(self, name): + self.name = name + + def __get__(self, obj, tp): + result = self._resolve() + setattr(obj, self.name, result) # Invokes __set__. + try: + # This is a bit ugly, but it avoids running this again by + # removing this descriptor. + delattr(obj.__class__, self.name) + except AttributeError: + pass + return result + + +class MovedModule(_LazyDescr): + + def __init__(self, name, old, new=None): + super(MovedModule, self).__init__(name) + if PY3: + if new is None: + new = name + self.mod = new + else: + self.mod = old + + def _resolve(self): + return _import_module(self.mod) + + def __getattr__(self, attr): + _module = self._resolve() + value = getattr(_module, attr) + setattr(self, attr, value) + return value + + +class _LazyModule(types.ModuleType): + + def __init__(self, name): + super(_LazyModule, self).__init__(name) + self.__doc__ = self.__class__.__doc__ + + def __dir__(self): + attrs = ["__doc__", "__name__"] + attrs += [attr.name for attr in self._moved_attributes] + return attrs + + # Subclasses should override this + _moved_attributes = [] + + +class MovedAttribute(_LazyDescr): + + def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None): + super(MovedAttribute, self).__init__(name) + if PY3: + if new_mod is None: + new_mod = name + self.mod = new_mod + if new_attr is None: + if old_attr is None: + new_attr = name + else: + new_attr = old_attr + self.attr = new_attr + else: + self.mod = old_mod + if old_attr is None: + old_attr = name + self.attr = old_attr + + def _resolve(self): + module = _import_module(self.mod) + return getattr(module, self.attr) + + +class _SixMetaPathImporter(object): + + """ + A meta path importer to import six.moves and its submodules. + + This class implements a PEP302 finder and loader. It should be compatible + with Python 2.5 and all existing versions of Python3 + """ + + def __init__(self, six_module_name): + self.name = six_module_name + self.known_modules = {} + + def _add_module(self, mod, *fullnames): + for fullname in fullnames: + self.known_modules[self.name + "." + fullname] = mod + + def _get_module(self, fullname): + return self.known_modules[self.name + "." + fullname] + + def find_module(self, fullname, path=None): + if fullname in self.known_modules: + return self + return None + + def __get_module(self, fullname): + try: + return self.known_modules[fullname] + except KeyError: + raise ImportError("This loader does not know module " + fullname) + + def load_module(self, fullname): + try: + # in case of a reload + return sys.modules[fullname] + except KeyError: + pass + mod = self.__get_module(fullname) + if isinstance(mod, MovedModule): + mod = mod._resolve() + else: + mod.__loader__ = self + sys.modules[fullname] = mod + return mod + + def is_package(self, fullname): + """ + Return true, if the named module is a package. + + We need this method to get correct spec objects with + Python 3.4 (see PEP451) + """ + return hasattr(self.__get_module(fullname), "__path__") + + def get_code(self, fullname): + """Return None + + Required, if is_package is implemented""" + self.__get_module(fullname) # eventually raises ImportError + return None + get_source = get_code # same as get_code + +_importer = _SixMetaPathImporter(__name__) + + +class _MovedItems(_LazyModule): + + """Lazy loading of moved objects""" + __path__ = [] # mark as package + + +_moved_attributes = [ + MovedAttribute("cStringIO", "cStringIO", "io", "StringIO"), + MovedAttribute("filter", "itertools", "builtins", "ifilter", "filter"), + MovedAttribute("filterfalse", "itertools", "itertools", "ifilterfalse", "filterfalse"), + MovedAttribute("input", "__builtin__", "builtins", "raw_input", "input"), + MovedAttribute("intern", "__builtin__", "sys"), + MovedAttribute("map", "itertools", "builtins", "imap", "map"), + MovedAttribute("getcwd", "os", "os", "getcwdu", "getcwd"), + MovedAttribute("getcwdb", "os", "os", "getcwd", "getcwdb"), + MovedAttribute("range", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("reload_module", "__builtin__", "importlib" if PY34 else "imp", "reload"), + MovedAttribute("reduce", "__builtin__", "functools"), + MovedAttribute("shlex_quote", "pipes", "shlex", "quote"), + MovedAttribute("StringIO", "StringIO", "io"), + MovedAttribute("UserDict", "UserDict", "collections"), + MovedAttribute("UserList", "UserList", "collections"), + MovedAttribute("UserString", "UserString", "collections"), + MovedAttribute("xrange", "__builtin__", "builtins", "xrange", "range"), + MovedAttribute("zip", "itertools", "builtins", "izip", "zip"), + MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest"), + MovedModule("builtins", "__builtin__"), + MovedModule("configparser", "ConfigParser"), + MovedModule("copyreg", "copy_reg"), + MovedModule("dbm_gnu", "gdbm", "dbm.gnu"), + MovedModule("_dummy_thread", "dummy_thread", "_dummy_thread"), + MovedModule("http_cookiejar", "cookielib", "http.cookiejar"), + MovedModule("http_cookies", "Cookie", "http.cookies"), + MovedModule("html_entities", "htmlentitydefs", "html.entities"), + MovedModule("html_parser", "HTMLParser", "html.parser"), + MovedModule("http_client", "httplib", "http.client"), + MovedModule("email_mime_multipart", "email.MIMEMultipart", "email.mime.multipart"), + MovedModule("email_mime_nonmultipart", "email.MIMENonMultipart", "email.mime.nonmultipart"), + MovedModule("email_mime_text", "email.MIMEText", "email.mime.text"), + MovedModule("email_mime_base", "email.MIMEBase", "email.mime.base"), + MovedModule("BaseHTTPServer", "BaseHTTPServer", "http.server"), + MovedModule("CGIHTTPServer", "CGIHTTPServer", "http.server"), + MovedModule("SimpleHTTPServer", "SimpleHTTPServer", "http.server"), + MovedModule("cPickle", "cPickle", "pickle"), + MovedModule("queue", "Queue"), + MovedModule("reprlib", "repr"), + MovedModule("socketserver", "SocketServer"), + MovedModule("_thread", "thread", "_thread"), + MovedModule("tkinter", "Tkinter"), + MovedModule("tkinter_dialog", "Dialog", "tkinter.dialog"), + MovedModule("tkinter_filedialog", "FileDialog", "tkinter.filedialog"), + MovedModule("tkinter_scrolledtext", "ScrolledText", "tkinter.scrolledtext"), + MovedModule("tkinter_simpledialog", "SimpleDialog", "tkinter.simpledialog"), + MovedModule("tkinter_tix", "Tix", "tkinter.tix"), + MovedModule("tkinter_ttk", "ttk", "tkinter.ttk"), + MovedModule("tkinter_constants", "Tkconstants", "tkinter.constants"), + MovedModule("tkinter_dnd", "Tkdnd", "tkinter.dnd"), + MovedModule("tkinter_colorchooser", "tkColorChooser", + "tkinter.colorchooser"), + MovedModule("tkinter_commondialog", "tkCommonDialog", + "tkinter.commondialog"), + MovedModule("tkinter_tkfiledialog", "tkFileDialog", "tkinter.filedialog"), + MovedModule("tkinter_font", "tkFont", "tkinter.font"), + MovedModule("tkinter_messagebox", "tkMessageBox", "tkinter.messagebox"), + MovedModule("tkinter_tksimpledialog", "tkSimpleDialog", + "tkinter.simpledialog"), + MovedModule("urllib_parse", __name__ + ".moves.urllib_parse", "urllib.parse"), + MovedModule("urllib_error", __name__ + ".moves.urllib_error", "urllib.error"), + MovedModule("urllib", __name__ + ".moves.urllib", __name__ + ".moves.urllib"), + MovedModule("urllib_robotparser", "robotparser", "urllib.robotparser"), + MovedModule("xmlrpc_client", "xmlrpclib", "xmlrpc.client"), + MovedModule("xmlrpc_server", "SimpleXMLRPCServer", "xmlrpc.server"), +] +# Add windows specific modules. +if sys.platform == "win32": + _moved_attributes += [ + MovedModule("winreg", "_winreg"), + ] + +for attr in _moved_attributes: + setattr(_MovedItems, attr.name, attr) + if isinstance(attr, MovedModule): + _importer._add_module(attr, "moves." + attr.name) +del attr + +_MovedItems._moved_attributes = _moved_attributes + +moves = _MovedItems(__name__ + ".moves") +_importer._add_module(moves, "moves") + + +class Module_six_moves_urllib_parse(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_parse""" + + +_urllib_parse_moved_attributes = [ + MovedAttribute("ParseResult", "urlparse", "urllib.parse"), + MovedAttribute("SplitResult", "urlparse", "urllib.parse"), + MovedAttribute("parse_qs", "urlparse", "urllib.parse"), + MovedAttribute("parse_qsl", "urlparse", "urllib.parse"), + MovedAttribute("urldefrag", "urlparse", "urllib.parse"), + MovedAttribute("urljoin", "urlparse", "urllib.parse"), + MovedAttribute("urlparse", "urlparse", "urllib.parse"), + MovedAttribute("urlsplit", "urlparse", "urllib.parse"), + MovedAttribute("urlunparse", "urlparse", "urllib.parse"), + MovedAttribute("urlunsplit", "urlparse", "urllib.parse"), + MovedAttribute("quote", "urllib", "urllib.parse"), + MovedAttribute("quote_plus", "urllib", "urllib.parse"), + MovedAttribute("unquote", "urllib", "urllib.parse"), + MovedAttribute("unquote_plus", "urllib", "urllib.parse"), + MovedAttribute("urlencode", "urllib", "urllib.parse"), + MovedAttribute("splitquery", "urllib", "urllib.parse"), + MovedAttribute("splittag", "urllib", "urllib.parse"), + MovedAttribute("splituser", "urllib", "urllib.parse"), + MovedAttribute("uses_fragment", "urlparse", "urllib.parse"), + MovedAttribute("uses_netloc", "urlparse", "urllib.parse"), + MovedAttribute("uses_params", "urlparse", "urllib.parse"), + MovedAttribute("uses_query", "urlparse", "urllib.parse"), + MovedAttribute("uses_relative", "urlparse", "urllib.parse"), +] +for attr in _urllib_parse_moved_attributes: + setattr(Module_six_moves_urllib_parse, attr.name, attr) +del attr + +Module_six_moves_urllib_parse._moved_attributes = _urllib_parse_moved_attributes + +_importer._add_module(Module_six_moves_urllib_parse(__name__ + ".moves.urllib_parse"), + "moves.urllib_parse", "moves.urllib.parse") + + +class Module_six_moves_urllib_error(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_error""" + + +_urllib_error_moved_attributes = [ + MovedAttribute("URLError", "urllib2", "urllib.error"), + MovedAttribute("HTTPError", "urllib2", "urllib.error"), + MovedAttribute("ContentTooShortError", "urllib", "urllib.error"), +] +for attr in _urllib_error_moved_attributes: + setattr(Module_six_moves_urllib_error, attr.name, attr) +del attr + +Module_six_moves_urllib_error._moved_attributes = _urllib_error_moved_attributes + +_importer._add_module(Module_six_moves_urllib_error(__name__ + ".moves.urllib.error"), + "moves.urllib_error", "moves.urllib.error") + + +class Module_six_moves_urllib_request(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_request""" + + +_urllib_request_moved_attributes = [ + MovedAttribute("urlopen", "urllib2", "urllib.request"), + MovedAttribute("install_opener", "urllib2", "urllib.request"), + MovedAttribute("build_opener", "urllib2", "urllib.request"), + MovedAttribute("pathname2url", "urllib", "urllib.request"), + MovedAttribute("url2pathname", "urllib", "urllib.request"), + MovedAttribute("getproxies", "urllib", "urllib.request"), + MovedAttribute("Request", "urllib2", "urllib.request"), + MovedAttribute("OpenerDirector", "urllib2", "urllib.request"), + MovedAttribute("HTTPDefaultErrorHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPRedirectHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPCookieProcessor", "urllib2", "urllib.request"), + MovedAttribute("ProxyHandler", "urllib2", "urllib.request"), + MovedAttribute("BaseHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgr", "urllib2", "urllib.request"), + MovedAttribute("HTTPPasswordMgrWithDefaultRealm", "urllib2", "urllib.request"), + MovedAttribute("AbstractBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyBasicAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("AbstractDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("ProxyDigestAuthHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPSHandler", "urllib2", "urllib.request"), + MovedAttribute("FileHandler", "urllib2", "urllib.request"), + MovedAttribute("FTPHandler", "urllib2", "urllib.request"), + MovedAttribute("CacheFTPHandler", "urllib2", "urllib.request"), + MovedAttribute("UnknownHandler", "urllib2", "urllib.request"), + MovedAttribute("HTTPErrorProcessor", "urllib2", "urllib.request"), + MovedAttribute("urlretrieve", "urllib", "urllib.request"), + MovedAttribute("urlcleanup", "urllib", "urllib.request"), + MovedAttribute("URLopener", "urllib", "urllib.request"), + MovedAttribute("FancyURLopener", "urllib", "urllib.request"), + MovedAttribute("proxy_bypass", "urllib", "urllib.request"), +] +for attr in _urllib_request_moved_attributes: + setattr(Module_six_moves_urllib_request, attr.name, attr) +del attr + +Module_six_moves_urllib_request._moved_attributes = _urllib_request_moved_attributes + +_importer._add_module(Module_six_moves_urllib_request(__name__ + ".moves.urllib.request"), + "moves.urllib_request", "moves.urllib.request") + + +class Module_six_moves_urllib_response(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_response""" + + +_urllib_response_moved_attributes = [ + MovedAttribute("addbase", "urllib", "urllib.response"), + MovedAttribute("addclosehook", "urllib", "urllib.response"), + MovedAttribute("addinfo", "urllib", "urllib.response"), + MovedAttribute("addinfourl", "urllib", "urllib.response"), +] +for attr in _urllib_response_moved_attributes: + setattr(Module_six_moves_urllib_response, attr.name, attr) +del attr + +Module_six_moves_urllib_response._moved_attributes = _urllib_response_moved_attributes + +_importer._add_module(Module_six_moves_urllib_response(__name__ + ".moves.urllib.response"), + "moves.urllib_response", "moves.urllib.response") + + +class Module_six_moves_urllib_robotparser(_LazyModule): + + """Lazy loading of moved objects in six.moves.urllib_robotparser""" + + +_urllib_robotparser_moved_attributes = [ + MovedAttribute("RobotFileParser", "robotparser", "urllib.robotparser"), +] +for attr in _urllib_robotparser_moved_attributes: + setattr(Module_six_moves_urllib_robotparser, attr.name, attr) +del attr + +Module_six_moves_urllib_robotparser._moved_attributes = _urllib_robotparser_moved_attributes + +_importer._add_module(Module_six_moves_urllib_robotparser(__name__ + ".moves.urllib.robotparser"), + "moves.urllib_robotparser", "moves.urllib.robotparser") + + +class Module_six_moves_urllib(types.ModuleType): + + """Create a six.moves.urllib namespace that resembles the Python 3 namespace""" + __path__ = [] # mark as package + parse = _importer._get_module("moves.urllib_parse") + error = _importer._get_module("moves.urllib_error") + request = _importer._get_module("moves.urllib_request") + response = _importer._get_module("moves.urllib_response") + robotparser = _importer._get_module("moves.urllib_robotparser") + + def __dir__(self): + return ['parse', 'error', 'request', 'response', 'robotparser'] + +_importer._add_module(Module_six_moves_urllib(__name__ + ".moves.urllib"), + "moves.urllib") + + +def add_move(move): + """Add an item to six.moves.""" + setattr(_MovedItems, move.name, move) + + +def remove_move(name): + """Remove item from six.moves.""" + try: + delattr(_MovedItems, name) + except AttributeError: + try: + del moves.__dict__[name] + except KeyError: + raise AttributeError("no such move, %r" % (name,)) + + +if PY3: + _meth_func = "__func__" + _meth_self = "__self__" + + _func_closure = "__closure__" + _func_code = "__code__" + _func_defaults = "__defaults__" + _func_globals = "__globals__" +else: + _meth_func = "im_func" + _meth_self = "im_self" + + _func_closure = "func_closure" + _func_code = "func_code" + _func_defaults = "func_defaults" + _func_globals = "func_globals" + + +try: + advance_iterator = next +except NameError: + def advance_iterator(it): + return it.next() +next = advance_iterator + + +try: + callable = callable +except NameError: + def callable(obj): + return any("__call__" in klass.__dict__ for klass in type(obj).__mro__) + + +if PY3: + def get_unbound_function(unbound): + return unbound + + create_bound_method = types.MethodType + + def create_unbound_method(func, cls): + return func + + Iterator = object +else: + def get_unbound_function(unbound): + return unbound.im_func + + def create_bound_method(func, obj): + return types.MethodType(func, obj, obj.__class__) + + def create_unbound_method(func, cls): + return types.MethodType(func, None, cls) + + class Iterator(object): + + def next(self): + return type(self).__next__(self) + + callable = callable +_add_doc(get_unbound_function, + """Get the function out of a possibly unbound function""") + + +get_method_function = operator.attrgetter(_meth_func) +get_method_self = operator.attrgetter(_meth_self) +get_function_closure = operator.attrgetter(_func_closure) +get_function_code = operator.attrgetter(_func_code) +get_function_defaults = operator.attrgetter(_func_defaults) +get_function_globals = operator.attrgetter(_func_globals) + + +if PY3: + def iterkeys(d, **kw): + return iter(d.keys(**kw)) + + def itervalues(d, **kw): + return iter(d.values(**kw)) + + def iteritems(d, **kw): + return iter(d.items(**kw)) + + def iterlists(d, **kw): + return iter(d.lists(**kw)) + + viewkeys = operator.methodcaller("keys") + + viewvalues = operator.methodcaller("values") + + viewitems = operator.methodcaller("items") +else: + def iterkeys(d, **kw): + return d.iterkeys(**kw) + + def itervalues(d, **kw): + return d.itervalues(**kw) + + def iteritems(d, **kw): + return d.iteritems(**kw) + + def iterlists(d, **kw): + return d.iterlists(**kw) + + viewkeys = operator.methodcaller("viewkeys") + + viewvalues = operator.methodcaller("viewvalues") + + viewitems = operator.methodcaller("viewitems") + +_add_doc(iterkeys, "Return an iterator over the keys of a dictionary.") +_add_doc(itervalues, "Return an iterator over the values of a dictionary.") +_add_doc(iteritems, + "Return an iterator over the (key, value) pairs of a dictionary.") +_add_doc(iterlists, + "Return an iterator over the (key, [values]) pairs of a dictionary.") + + +if PY3: + def b(s): + return s.encode("latin-1") + + def u(s): + return s + unichr = chr + import struct + int2byte = struct.Struct(">B").pack + del struct + byte2int = operator.itemgetter(0) + indexbytes = operator.getitem + iterbytes = iter + import io + StringIO = io.StringIO + BytesIO = io.BytesIO + _assertCountEqual = "assertCountEqual" + if sys.version_info[1] <= 1: + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" + else: + _assertRaisesRegex = "assertRaisesRegex" + _assertRegex = "assertRegex" +else: + def b(s): + return s + # Workaround for standalone backslash + + def u(s): + return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + unichr = unichr + int2byte = chr + + def byte2int(bs): + return ord(bs[0]) + + def indexbytes(buf, i): + return ord(buf[i]) + iterbytes = functools.partial(itertools.imap, ord) + import StringIO + StringIO = BytesIO = StringIO.StringIO + _assertCountEqual = "assertItemsEqual" + _assertRaisesRegex = "assertRaisesRegexp" + _assertRegex = "assertRegexpMatches" +_add_doc(b, """Byte literal""") +_add_doc(u, """Text literal""") + + +def assertCountEqual(self, *args, **kwargs): + return getattr(self, _assertCountEqual)(*args, **kwargs) + + +def assertRaisesRegex(self, *args, **kwargs): + return getattr(self, _assertRaisesRegex)(*args, **kwargs) + + +def assertRegex(self, *args, **kwargs): + return getattr(self, _assertRegex)(*args, **kwargs) + + +if PY3: + exec_ = getattr(moves.builtins, "exec") + + def reraise(tp, value, tb=None): + if value is None: + value = tp() + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + +else: + def exec_(_code_, _globs_=None, _locs_=None): + """Execute code in a namespace.""" + if _globs_ is None: + frame = sys._getframe(1) + _globs_ = frame.f_globals + if _locs_ is None: + _locs_ = frame.f_locals + del frame + elif _locs_ is None: + _locs_ = _globs_ + exec("""exec _code_ in _globs_, _locs_""") + + exec_("""def reraise(tp, value, tb=None): + raise tp, value, tb +""") + + +if sys.version_info[:2] == (3, 2): + exec_("""def raise_from(value, from_value): + if from_value is None: + raise value + raise value from from_value +""") +elif sys.version_info[:2] > (3, 2): + exec_("""def raise_from(value, from_value): + raise value from from_value +""") +else: + def raise_from(value, from_value): + raise value + + +print_ = getattr(moves.builtins, "print", None) +if print_ is None: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5.""" + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + if (isinstance(fp, file) and + isinstance(data, unicode) and + fp.encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(fp.encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +if sys.version_info[:2] < (3, 3): + _print = print_ + + def print_(*args, **kwargs): + fp = kwargs.get("file", sys.stdout) + flush = kwargs.pop("flush", False) + _print(*args, **kwargs) + if flush and fp is not None: + fp.flush() + +_add_doc(reraise, """Reraise an exception.""") + +if sys.version_info[0:2] < (3, 4): + def wraps(wrapped, assigned=functools.WRAPPER_ASSIGNMENTS, + updated=functools.WRAPPER_UPDATES): + def wrapper(f): + f = functools.wraps(wrapped, assigned, updated)(f) + f.__wrapped__ = wrapped + return f + return wrapper +else: + wraps = functools.wraps + + +def with_metaclass(meta, *bases): + """Create a base class with a metaclass.""" + # This requires a bit of explanation: the basic idea is to make a dummy + # metaclass for one level of class instantiation that replaces itself with + # the actual metaclass. + class metaclass(meta): + + def __new__(cls, name, this_bases, d): + return meta(name, bases, d) + return type.__new__(metaclass, 'temporary_class', (), {}) + + +def add_metaclass(metaclass): + """Class decorator for creating a class with a metaclass.""" + def wrapper(cls): + orig_vars = cls.__dict__.copy() + slots = orig_vars.get('__slots__') + if slots is not None: + if isinstance(slots, str): + slots = [slots] + for slots_var in slots: + orig_vars.pop(slots_var) + orig_vars.pop('__dict__', None) + orig_vars.pop('__weakref__', None) + return metaclass(cls.__name__, cls.__bases__, orig_vars) + return wrapper + + +def python_2_unicode_compatible(klass): + """ + A decorator that defines __unicode__ and __str__ methods under Python 2. + Under Python 3 it does nothing. + + To support Python 2 and 3 with a single code base, define a __str__ method + returning text and apply this decorator to the class. + """ + if PY2: + if '__str__' not in klass.__dict__: + raise ValueError("@python_2_unicode_compatible cannot be applied " + "to %s because it doesn't define __str__()." % + klass.__name__) + klass.__unicode__ = klass.__str__ + klass.__str__ = lambda self: self.__unicode__().encode('utf-8') + return klass + + +# Complete the moves implementation. +# This code is at the end of this module to speed up module loading. +# Turn this module into a package. +__path__ = [] # required for PEP 302 and PEP 451 +__package__ = __name__ # see PEP 366 @ReservedAssignment +if globals().get("__spec__") is not None: + __spec__.submodule_search_locations = [] # PEP 451 @UndefinedVariable +# Remove other six meta path importers, since they cause problems. This can +# happen if six is removed from sys.modules and then reloaded. (Setuptools does +# this for some reason.) +if sys.meta_path: + for i, importer in enumerate(sys.meta_path): + # Here's some real nastiness: Another "instance" of the six module might + # be floating around. Therefore, we can't use isinstance() to check for + # the six meta path importer, since the other six instance will have + # inserted an importer with different class. + if (type(importer).__name__ == "_SixMetaPathImporter" and + importer.name == __name__): + del sys.meta_path[i] + break + del i, importer +# Finally, add the importer to the meta path import hook. +sys.meta_path.append(_importer) diff --git a/env/lib/python3.7/site-packages/setuptools/archive_util.py b/env/lib/python3.7/site-packages/setuptools/archive_util.py new file mode 100644 index 0000000..8143604 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/archive_util.py @@ -0,0 +1,173 @@ +"""Utilities for extracting common archive formats""" + +import zipfile +import tarfile +import os +import shutil +import posixpath +import contextlib +from distutils.errors import DistutilsError + +from pkg_resources import ensure_directory + +__all__ = [ + "unpack_archive", "unpack_zipfile", "unpack_tarfile", "default_filter", + "UnrecognizedFormat", "extraction_drivers", "unpack_directory", +] + + +class UnrecognizedFormat(DistutilsError): + """Couldn't recognize the archive type""" + + +def default_filter(src, dst): + """The default progress/filter callback; returns True for all files""" + return dst + + +def unpack_archive(filename, extract_dir, progress_filter=default_filter, + drivers=None): + """Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat`` + + `progress_filter` is a function taking two arguments: a source path + internal to the archive ('/'-separated), and a filesystem path where it + will be extracted. The callback must return the desired extract path + (which may be the same as the one passed in), or else ``None`` to skip + that file or directory. The callback can thus be used to report on the + progress of the extraction, as well as to filter the items extracted or + alter their extraction paths. + + `drivers`, if supplied, must be a non-empty sequence of functions with the + same signature as this function (minus the `drivers` argument), that raise + ``UnrecognizedFormat`` if they do not support extracting the designated + archive type. The `drivers` are tried in sequence until one is found that + does not raise an error, or until all are exhausted (in which case + ``UnrecognizedFormat`` is raised). If you do not supply a sequence of + drivers, the module's ``extraction_drivers`` constant will be used, which + means that ``unpack_zipfile`` and ``unpack_tarfile`` will be tried, in that + order. + """ + for driver in drivers or extraction_drivers: + try: + driver(filename, extract_dir, progress_filter) + except UnrecognizedFormat: + continue + else: + return + else: + raise UnrecognizedFormat( + "Not a recognized archive type: %s" % filename + ) + + +def unpack_directory(filename, extract_dir, progress_filter=default_filter): + """"Unpack" a directory, using the same interface as for archives + + Raises ``UnrecognizedFormat`` if `filename` is not a directory + """ + if not os.path.isdir(filename): + raise UnrecognizedFormat("%s is not a directory" % filename) + + paths = { + filename: ('', extract_dir), + } + for base, dirs, files in os.walk(filename): + src, dst = paths[base] + for d in dirs: + paths[os.path.join(base, d)] = src + d + '/', os.path.join(dst, d) + for f in files: + target = os.path.join(dst, f) + target = progress_filter(src + f, target) + if not target: + # skip non-files + continue + ensure_directory(target) + f = os.path.join(base, f) + shutil.copyfile(f, target) + shutil.copystat(f, target) + + +def unpack_zipfile(filename, extract_dir, progress_filter=default_filter): + """Unpack zip `filename` to `extract_dir` + + Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined + by ``zipfile.is_zipfile()``). See ``unpack_archive()`` for an explanation + of the `progress_filter` argument. + """ + + if not zipfile.is_zipfile(filename): + raise UnrecognizedFormat("%s is not a zip file" % (filename,)) + + with zipfile.ZipFile(filename) as z: + for info in z.infolist(): + name = info.filename + + # don't extract absolute paths or ones with .. in them + if name.startswith('/') or '..' in name.split('/'): + continue + + target = os.path.join(extract_dir, *name.split('/')) + target = progress_filter(name, target) + if not target: + continue + if name.endswith('/'): + # directory + ensure_directory(target) + else: + # file + ensure_directory(target) + data = z.read(info.filename) + with open(target, 'wb') as f: + f.write(data) + unix_attributes = info.external_attr >> 16 + if unix_attributes: + os.chmod(target, unix_attributes) + + +def unpack_tarfile(filename, extract_dir, progress_filter=default_filter): + """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` + + Raises ``UnrecognizedFormat`` if `filename` is not a tarfile (as determined + by ``tarfile.open()``). See ``unpack_archive()`` for an explanation + of the `progress_filter` argument. + """ + try: + tarobj = tarfile.open(filename) + except tarfile.TarError: + raise UnrecognizedFormat( + "%s is not a compressed or uncompressed tar file" % (filename,) + ) + with contextlib.closing(tarobj): + # don't do any chowning! + tarobj.chown = lambda *args: None + for member in tarobj: + name = member.name + # don't extract absolute paths or ones with .. in them + if not name.startswith('/') and '..' not in name.split('/'): + prelim_dst = os.path.join(extract_dir, *name.split('/')) + + # resolve any links and to extract the link targets as normal + # files + while member is not None and (member.islnk() or member.issym()): + linkpath = member.linkname + if member.issym(): + base = posixpath.dirname(member.name) + linkpath = posixpath.join(base, linkpath) + linkpath = posixpath.normpath(linkpath) + member = tarobj._getmember(linkpath) + + if member is not None and (member.isfile() or member.isdir()): + final_dst = progress_filter(name, prelim_dst) + if final_dst: + if final_dst.endswith(os.sep): + final_dst = final_dst[:-1] + try: + # XXX Ugh + tarobj._extract_member(member, final_dst) + except tarfile.ExtractError: + # chown/chmod/mkfifo/mknode/makedev failed + pass + return True + + +extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile diff --git a/env/lib/python3.7/site-packages/setuptools/build_meta.py b/env/lib/python3.7/site-packages/setuptools/build_meta.py new file mode 100644 index 0000000..463d375 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/build_meta.py @@ -0,0 +1,182 @@ +"""A PEP 517 interface to setuptools + +Previously, when a user or a command line tool (let's call it a "frontend") +needed to make a request of setuptools to take a certain action, for +example, generating a list of installation requirements, the frontend would +would call "setup.py egg_info" or "setup.py bdist_wheel" on the command line. + +PEP 517 defines a different method of interfacing with setuptools. Rather +than calling "setup.py" directly, the frontend should: + + 1. Set the current directory to the directory with a setup.py file + 2. Import this module into a safe python interpreter (one in which + setuptools can potentially set global variables or crash hard). + 3. Call one of the functions defined in PEP 517. + +What each function does is defined in PEP 517. However, here is a "casual" +definition of the functions (this definition should not be relied on for +bug reports or API stability): + + - `build_wheel`: build a wheel in the folder and return the basename + - `get_requires_for_build_wheel`: get the `setup_requires` to build + - `prepare_metadata_for_build_wheel`: get the `install_requires` + - `build_sdist`: build an sdist in the folder and return the basename + - `get_requires_for_build_sdist`: get the `setup_requires` to build + +Again, this is not a formal definition! Just a "taste" of the module. +""" + +import os +import sys +import tokenize +import shutil +import contextlib + +import setuptools +import distutils + + +class SetupRequirementsError(BaseException): + def __init__(self, specifiers): + self.specifiers = specifiers + + +class Distribution(setuptools.dist.Distribution): + def fetch_build_eggs(self, specifiers): + raise SetupRequirementsError(specifiers) + + @classmethod + @contextlib.contextmanager + def patch(cls): + """ + Replace + distutils.dist.Distribution with this class + for the duration of this context. + """ + orig = distutils.core.Distribution + distutils.core.Distribution = cls + try: + yield + finally: + distutils.core.Distribution = orig + + +def _to_str(s): + """ + Convert a filename to a string (on Python 2, explicitly + a byte string, not Unicode) as distutils checks for the + exact type str. + """ + if sys.version_info[0] == 2 and not isinstance(s, str): + # Assume it's Unicode, as that's what the PEP says + # should be provided. + return s.encode(sys.getfilesystemencoding()) + return s + + +def _run_setup(setup_script='setup.py'): + # Note that we can reuse our build directory between calls + # Correctness comes first, then optimization later + __file__ = setup_script + __name__ = '__main__' + f = getattr(tokenize, 'open', open)(__file__) + code = f.read().replace('\\r\\n', '\\n') + f.close() + exec(compile(code, __file__, 'exec'), locals()) + + +def _fix_config(config_settings): + config_settings = config_settings or {} + config_settings.setdefault('--global-option', []) + return config_settings + + +def _get_build_requires(config_settings, requirements): + config_settings = _fix_config(config_settings) + + sys.argv = sys.argv[:1] + ['egg_info'] + \ + config_settings["--global-option"] + try: + with Distribution.patch(): + _run_setup() + except SetupRequirementsError as e: + requirements += e.specifiers + + return requirements + + +def _get_immediate_subdirectories(a_dir): + return [name for name in os.listdir(a_dir) + if os.path.isdir(os.path.join(a_dir, name))] + + +def get_requires_for_build_wheel(config_settings=None): + config_settings = _fix_config(config_settings) + return _get_build_requires(config_settings, requirements=['wheel']) + + +def get_requires_for_build_sdist(config_settings=None): + config_settings = _fix_config(config_settings) + return _get_build_requires(config_settings, requirements=[]) + + +def prepare_metadata_for_build_wheel(metadata_directory, config_settings=None): + sys.argv = sys.argv[:1] + ['dist_info', '--egg-base', _to_str(metadata_directory)] + _run_setup() + + dist_info_directory = metadata_directory + while True: + dist_infos = [f for f in os.listdir(dist_info_directory) + if f.endswith('.dist-info')] + + if len(dist_infos) == 0 and \ + len(_get_immediate_subdirectories(dist_info_directory)) == 1: + dist_info_directory = os.path.join( + dist_info_directory, os.listdir(dist_info_directory)[0]) + continue + + assert len(dist_infos) == 1 + break + + # PEP 517 requires that the .dist-info directory be placed in the + # metadata_directory. To comply, we MUST copy the directory to the root + if dist_info_directory != metadata_directory: + shutil.move( + os.path.join(dist_info_directory, dist_infos[0]), + metadata_directory) + shutil.rmtree(dist_info_directory, ignore_errors=True) + + return dist_infos[0] + + +def build_wheel(wheel_directory, config_settings=None, + metadata_directory=None): + config_settings = _fix_config(config_settings) + wheel_directory = os.path.abspath(wheel_directory) + sys.argv = sys.argv[:1] + ['bdist_wheel'] + \ + config_settings["--global-option"] + _run_setup() + if wheel_directory != 'dist': + shutil.rmtree(wheel_directory) + shutil.copytree('dist', wheel_directory) + + wheels = [f for f in os.listdir(wheel_directory) + if f.endswith('.whl')] + + assert len(wheels) == 1 + return wheels[0] + + +def build_sdist(sdist_directory, config_settings=None): + config_settings = _fix_config(config_settings) + sdist_directory = os.path.abspath(sdist_directory) + sys.argv = sys.argv[:1] + ['sdist'] + \ + config_settings["--global-option"] + \ + ["--dist-dir", sdist_directory] + _run_setup() + + sdists = [f for f in os.listdir(sdist_directory) + if f.endswith('.tar.gz')] + + assert len(sdists) == 1 + return sdists[0] diff --git a/env/lib/python3.7/site-packages/setuptools/cli-32.exe b/env/lib/python3.7/site-packages/setuptools/cli-32.exe new file mode 100644 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/cli-64.exe b/env/lib/python3.7/site-packages/setuptools/cli-64.exe new file mode 100644 index 0000000000000000000000000000000000000000..675e6bf3743f3d3011c238657e7128ee9960ef7f GIT binary patch literal 74752 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 &sjKl@1{;unAiW2w^OujNoW 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/cli.exe b/env/lib/python3.7/site-packages/setuptools/cli.exe new file mode 100644 index 0000000000000000000000000000000000000000..b1487b7819e7286577a043c7726fbe0ca1543083 GIT binary patch literal 65536 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[c}i<OXTz6k>I#RErv3nvcIClH@!{vM)zJ_weD zu_-L8NU*G<xQC7$Bg`f~d>lC{d0L!!VW10^+~>qmNB~Y8H+F}!P8_d(PpvjzMJQmr z)F<LB!IdzF`7%cck^aLb_J<@DD#CfB0B$E^bzV@-Vr`q!&`=<s^68_Wa_GZ_v^?aY zU=VZGXAzm5x{LcyVkUd8JxnNsqtS!3fw-nje@5tui@0AmI$b-*P5O7)s<z9AVj!{a zusK!aLirXkGmKBs9|=}}+<^)RB1ao<^{^>kX;2B~<|3JfJeWv@IXo~nTtp$}Gjie> zs8UDG*kid(%i5QCBp~MA;#I186PI-nZ&k7!k8BiLJSuR>h7ArSYHD~<iO|JiNP|OD zR=9Lm@@Ua+Eq87EAwAZBPGrH*)zP)xEF>B0I<PUu3WRluor4HwG59U@*GT3C4#)*> z=T6L{zqglekt0JjG5z&|GWb4?+B5+{p^fgTufl_KesA{@I&g7rNq==^SGc5GcM%$N zDBG2)qExz*Z;jGN_-iD-y8i2BCq)p}2lKcspLg>w-;qwg(()HXrZa3jd!}spuwBVX zwmX!iwU<Qo&ds@10tJ4pnneT?LI)M|HS1v7YY$x9Bv-SsJ$Cl+xPAV;6Eqk-srxG9 z{LT5_#k!V#{GO}ibh%Xvw5jxHs@yzGY~@?`(yJD$GqsX;X$pypI5DT^o5eVu9#Z@z zw!tumU}_j8#vZXTB&Vb!;K(WYBw))aIfHo=I@urFFfxYS9PyXWVFQN5U;5Dw%tIz$ zw`nTQR_c;mZr;Y5QwPf3_^KR#GvcZKkFXD~jQGWdi~_bGh!>?#7uoQnunw|OlU~+c z^L5Ak3zWhaA4B^FhMMboO0k*O2GL)lD9_<$5b>czbCvKcSt+u*gA*=%dH>Q-Bc11h zzO7jbXN)&5mBf=w2anK6P$YcJZQoWa2#E!v{hFKxxm7Fc)Fc9iC35{|Lp7bIDjrhC zgMiGf4r2yquH{U7WdMio;XS4Y%Ry{q7#kv#gZ07i`7eo#MMh_o68E*Fd_#nrri^4b zX+slbsv>+8pmck%oLDU<yTk`c&RTk8mVQAOK~qMQ#2raos*zaqlvJZo>L()8NRJ#Z z8DReF_eq2zsjEXGs)yS{k}ykS1B!ZrY0f6O65^lslJv3g&wfpDg-&EwF8wrc=hSwm zPlV&n%%yE_@onOwK?)`GNJ6MQ0drMuBYWCH5dkD)uErh@*k}#GcFl<-;;TN+5vb|b zctkCv;*zL7f)A;QuO%(81r0)&aUz4EQu;kA!k@7i8RZ)koMaWW`5cC6n@{w!!J$5d zx}l)4VP4xL=BKi&c^{n_Qi`q@G{vimblcVR53b#<Dz&@nl0LRIeY=p^I1%{g=J)$y zJ4tny{}tcKG0i7qLLJtU;jl;LnJu8bQak(kB&;UDjom{#=dp=&3s}YXYz3C()*?Ie zpOr>*X$FUOQFm!A8JKahNSiBdY+x3bJZfD8n{--FLUM4+Mx@{vM<W!B9QJEa7>_ep zkk)U=K8R(rhU(X_faI*ZO}cn`5t*O}lx^j8|0rt-)o=Axn^DGcQTi!#7hxLTq?|HQ zB;T6(nrsCeYK0_o%)IO+CP{n#+|;w1ZmvD2c-J{i88bp63RjyKOE!B!D3U{RCs*Zh z&^%65VM(J34230U4bHS}M@SYS9TEK}c%)2<$h1|T;##zRtjRt@#1T%J=kAhOiw+Z% z7DpyWVK@6%9K^uVD9LDKj)dR^aZK6$@Lt)l;sj@`QSzBm{TlLG{JKM_^60Zr2w~nr zr>P-BaV8OjjWm?hQ3$ZCx+lyD%q`~4iNF9xWKi$t&pzBhwN9Dq-o^v9@=abLR#|<P zZAhQVQAqt{KX8b!o72`jV*h~V{I<6~6`|CSYi!tcFRq-OP_ri!l#8;keBk$FyRh37 zh-vx<nho1V<uSlQEH;(ry7_afSZop_PK$8boQKoq+i)shoyMOs4}aFK<j<xGJnq14 zb2)CC*WtE#b4An68qy4#ciQ16Pbjcq3r`~(syir#2qbbvYtKWddcXwdfk_9bi9C9n ze)1pT^3siP-~5MsCpR}_o2eh^LneJBm*p>KZqkLal4YCRR9VNhIM|rBqmzzcImvcx z66fD`zj4}M-A;gyA17cSC-oI$`q?*q&8~)Qv|C#(aSFd|hYbf}FFVB?n3Q?Svt+Td z#AW4x=9X}?aizE|`r{}3l-H&b6-{_j#STR!lD001vu;K>KT;*^ChCevBwCMFpg{JI zv``4YsjK1&142Pl%%A#u3rbGso1<_fngd1`+}!pMu@z5Me_5UFxiPYKqFL4_`WXmY zeWJrZUKzrrMuBcHupOq4Wr12sE*T-*CXh;FA=)Q+BMN(?DJ!kq?%Ww`xlG3e;lz2t zY?tl;i?gHO_79VwJ_cThq^>FqRUPlqS?IuI+CfSbNkv_1l~7eGaCwRmuOF|ic1ac2 z9ldo$TN~LhX~J01P75nyi&d8=Y@QNZ5e<=6v_R3rM}nN}5ae`^LV&sAD<=;*z=!~` zvJ0@i!orMuT*5kyXNzJnxfU!+#FTW(syy@yj7XX8#zD_9TWBSg(;KZ25VO;is;-&R zf(29n3U}agkC`j4sjX{=`D1EkCC@enOA~v{GOLYQKAdPN6+?W+QE4fLMhrW4RG<SI z@?qI-KY>bH5^K(rm4T}`=ra<6GP2}cRBE9K8^r(O+ZvKpJDL~qNguPmwQZp-8m7V@ zN^KFU8@Q*E7UJswZD=OYtct4KqA&NDKSOfc-#M>@o#)4;YLqtENdFS^3K9&dFBr|M z*loqE3X2sMmi8hv#7H5<kgna*Z>rqGc_y=ShEbHT^m7S`?4d%B+(-6dYGI-*t5E+< z^P3gqvBIHjFQNKiDKj-p;Y*MmMAXOK^8{gVhrBn?Un}%9(JqaGPiann?Ll$aX-{n1 z!AnT<v!xN*zo+dH+)yR$d)}fNUUOcJ)Xz$%vH5mur0%L;@p((;IW$raH52Q@7``Z{ z?rO>WyjwZ7y=hrziEYVZVX)-}D^!8a+Bc<5#*3h1xvWqS7I$WL>iwNNvp;P<;TX`| zOF6ZibFB4T(YJC~mj~?Ev*ln|9sgYVFTcLiEi{YE;!ZWj>X*aK9|va;HulW-D`RH9 zw=O#R&of(j+rwMS%oCi;+oFskQ}@q2q4x)O3<fKs&%WtzzFD};-G{Hxx)V?F$WHWF z7(*i07&g=2&}`P4G>k5e6yDx`kLvQs@M`+D)vGA+`X6%Dl9YOA?Qrurfg>XqT9E@^ zgWxOT&hX+yo>7=HCb!3BO$p54I3{j@qbN!+nu>Ti*O~vw`5RU!f_JXS+*x#-zFp@m zr}GGVhgT1=p-TFp#dtAVjM3QdpDoi{l*z?1s=d~(E;Fkn=*i8+oB<M)E&5W?I^M)M zknOw+hdKDcP%Q}tuai)WoEa!7&-Iumsf3KA>cJ3Ib?Vh+rZWNZ$pO`dl8LcBv_cAA zc18lYB|rc<0u%wEdTGEup|%_S`L>@ui4LTkvnNApm<q=y*er!iCv8V>#>+b4WIF<} z^J}=w7L&$J%unXCb|Wy{z3WVlMDNhz3o7S-3)6oqjx)7WX0HTEH<C-Do)>{-=9>q+ zXXtoVPHKfVJMk8bt&h;MII}u~0l79^#`5CdW6Ef!eb|E&Q{UJ$n$yP;^Jd)qhw~ej zB?c~nN*%0zm%$}MD%|<q*x?^2$-sGY)_qDIsjoQeKH{k^*%_~Mm`JG>VZuS8W+Qtf zS+Uu?;oSPL<h#s;p3UgxZ3c;@9(LZhh9?&RH`z;Ufi?^GL|RbrQ|i$u#k>L}G`jMH zn3`(J{6K%B(Gykos(!d}z)Wr!%sjC6=V@s)qG1MJN~uoVlq{jeI#XKPMI;@L^`RBZ z<X%K$e<C_&9&p~HQ%fuI$-p5?U{jDsR}QoVqzzw}E77mP5v&U`27f1F&0F8zlxE2) ze=M@fh-;2;q_!ewec2frY%fKQkh6Y#Ck=~JBu;z6vOFXzd7O1mkt`yaC)8Gn>0Fhm zEI{|uQr0z1gk4W{mj*%4Z*00DBL5ko{4X}2{Dl0wAi#aSmq_r~FBHL|;}P&0k>OU! zhx64h5vSKwffV0W4JQs2dFBrfQx(B{AK=BGc`U!}S&BFnE6QSvw?`~m^}8j(4$IzQ z_WzjR?fD!VI8Aa=N;O96$f<JeDN}@@k24)dnpa7nV{o~|y480HWd%qi09M-w5HA7H z5t)dJA9OeU2(Ddz+nofIxgaM#sfN{v)}n+p872aEFyGb(<(TUTpJ(1Bv9RRP<lWbe zn*X9W;yA^EqlAv1#u2Gg|1wrNw~{@z1W#o_GFNuVYLs|BsZ*hkg_h`Il0YDiCHm+W zmS~Y0wwCC%sMd>IWzW@IV2KtfOm4MwFVU~FM5pwL+-yY-+$4mvEEjvjP+5JUm8n(w zTE>U0(q9W!VAi2soP~_07HUw%Pt_tTYxD^79a6Fw-(PjP4xwLxv3Ycv!%RV}m`xvC zX`nx*(H@IF+EJ)392Ul)-t@Oj>L>VGb7%C~V}eWde6yYkCcYR2>L5_BFiz*D#3I_* zY)|v0XvW#xv=Y0=d;t!!=&NUW2H8t2>2H>>rUwQga=@Hd8s$Z+x+rNk0%K7J*cGvn za#2GFTwHgcx}(hY&AoeJJ>OtvvdouZfGLkWz?5@JX6KrhfDJ0`xz(qU+f2hY)2ykx zl5dMrs#`m^OO;aljpVNpXHI7j?NBazjFr-P<5NZ{lysyym6ILI!i}auR#r=s8-sHH zo|F}x&aDr!mLdRfA3dBON<#lrL!uSm7=o9syd*hDuX`F0HkX``(5Ixonj|KOyUg3^ zQc-Q1zi|oXoEJ7t`z@l)r8HbVnV=3@R147(4T%Z?MF>|u+vhb+dmd}f?PMV8SW8Om zNGeF;<~ukE61hiT7Fejt`7XmU^|R{ev+p#`i$*Qly)%e2TjDu=LV)p<*h6u5gyTBv zF2X}pxW+%<Fj!P}AZas9RZ`k$Jvv1owwn8%W?{}x!+bkqQCghlz9l!;d?w_cXMXg@ z&=}JPT7tF@L2ahnMB72@q!wG|Y3@>;eRIVAvq#45Tg=WlQSFR|)0f>5G`p(9xM7}| zFKtPEbWZkN=1qLjD*3c&W=C5QZ78nOyIt7^bEIKqkTQs5B8y0Tx?-c7F3RU`pPOs` z_?hl<U&@p~CMd0Mfz5AN1#S&Vwsi0NvWloHbK|_KEOMjJm}q8E=E&9JuvOv6IZ8ov zcoQ8$o#cQM?=kPAi}LePW480inT%^k+4bRRjjowT_3NF_?RV~cwfUrD02;pIjR9GK zQO@U%q%4cq2SOIu>A-(AYe*|k@#n%-mt4P66m+?M)nmWXqWP-^>As_PEzQPQQFQR8 z8-h3Q39C3Q91oVz2*#A-KL%2bY;8!cmJ9uHA`|<v{z~0`eQ`+GHZb5=o_|mCd#>C8 z$NX`>3!Xc-34zzMQ(s0p^HbkPL0@}t>MK)QkhQHnsYONA8Y3sjLq95yD8o_vXX;;L z>_rtUVz~Yrx{&>y!BX_$%=h%m(WLsmNbc^@hvIY`rx=`G3p{Y^ZC06YKwy@l-|)Hh zU=6u>PjJFvP!kJ(Tc+sbM_EIjrY|G=W}4NvvWB>k^nM4`K&TNt=8t0byviN1Lph6= zm_yLKL?eam;`vUGWXllNQpvgH+$3sPb_yL=Bg|EjmK*vv&mK-$JqW8%=|ASK>2#&P z_Hr|Y5Dkgu7#^X*C_?v-?p6bh!n7?WmSW!JeSwnSm}M7T5((zV1Sgd@d05#6N@`iq zIof-m%Wyrh&Os_zmvwFpf)UBIy{<8BeDtovo%NaL&_|tBV$bJ-C;E$apFPY)zG1$1 z&owMVml>CDJKAdL5zE6EYkt$pYmLfF?wDG0`I8N*#DQu4-A7E6KcN`U27=18Fz;s6 zgRIKZJ=&bE;>8osoUL9Ryh=TbC>SSDx$a_ae4Sb3Y{(ciQKVJ&x*C=an(TMl4xLH2 zXX$$5{C?<{&`X7#bw|C!?@WU>(wf=M60Egk4C)t`yyBd`(C=(qFld4VoFf6R4+pHN zK8Ll6cJ>?zJRuIOK|)?8A%{uGgm6egv3W?S%i_2=V{%GzdHk`#X)(c}lhxAXtow#+ zFHp)}cHUdTEBD@=-@HTIVx!PQ#~t7^T8*<#^hS~|xc9~6%di^At;m{`IHO;U1JyJ& z?$6LV#Y%45gWjnIu3a5-`VNydN5;meS;L)mKjUK-hMMbbbJA&Cbq9~|S=gw!q$wS} z<Z(t^y7;u%;xGk;LG3lcOw_zt$NHvB?!ZTuJIo+vtIY)W*7UDg7nZYhgoJ`|`U@?# zf&SRW>>!$M`UNJWuIMmgl*gmkLk_ZS(?`c%lMZ(&XFK8NP#)0^vSl6vFEG>}Yt=qY z>WCarV-#iQR(@uObO3d9Zj~Ae<}6f(n;Hky?Oz`=r|lj-I0#^gmZN5;ee)19uN-uf zbLW7xnioz$Qqpv@afoy00q1WU<dahvrqv*^Tb#kb-RY_O47=@EAgz1AjGqJEU%$BD z#{P{%{LcENgC^i$Gs0h&&6#v8aM9Ug50ykMQMk~#qpD^cswS=IIHD-)jLMD@Eu?Zl zXzx^j#tYp#^O##HK)x^gH2Y8oBzw6P^DLtqvNE>|&pEgH8343To6masFPXZZ+i2fw zw(TOJh6NWV1zH#tgBTU7eP2E-U^0`E%lVvRweM3##v6R|Hc)r2ZWu6UP8uu_SKF^7 z5Ei+b&tX|(bW>KeN_C)b7q?VhC2@*pFT<#gaK20zQb%f_ppm8Xf&=AdHBgp?2g=0N zzUt06{THYVS>0fh!O|&%MP5GTWr9DpB_rmtxWJV%cw()<Th-`+9pNw^epR)x<&H5y zNn}p<5E>yvDADh1(g)ek#K;gD6diD^_G>B>y~3*2ri=>?y@k#|fr6r^y=jEkKl3E7 z4M}aqf+KgXac<4$1&vT`xA250AV##H0=5ek@I!)vK3Iwme$0oDmHS)WNy*wIdYTYj zZRu7LFxIS58JMfP!&x-K4>+HK()5vW=nSz9Me#w3T`4{giqU44ixK<NS-`KgQcF~+ z$)Xx~#$%3oPu5N7C1^%ShRb#_>rd!tunBaOeaO;`@Gg0VSi}FyYeUlc*jfuoTFFEd zOR8Z4RTBHrnM_v=qLS_KTIyGvYt1|?i!+C4y??`sV=b9MS0Ju6Q)C6T`W3;Z%o85d ziENh~l0#_RtCgzGELP8JHB9M!#^AHfT3W1T^h?P+q1$V+gEe9y%{FPzuSsRs@Ay-r z&&$%MWa*cg*GZ8R;SHL@d5gHczoSYe+a|;+l&uAZooROH4pP=g`GeNXPLfFzb`#S1 z2_-JE19Kg4B`^wb`OGw9drEbu!t~n%qeIJiU}$Ld55)5#)skz}?aZlPlQ8z#UJ#-| zYO^vmzd2P;V*j5ETWQQ}A;NIjCB|%xCEmF;jXrG6JdLv!xSAK@X@Sdl!B-26nk^;Q zowGGGn&>N2cRRN_tq77S`L(hZ^0u`V19Af$;OpSM*@-NJvG_<B4C7r?o87^iy*8Wb zMrpq6c67@_sMBrzt2>@@hy5J^v<IIiJ1y|!Q!YK$isdqQoTPDML_TG>d5CVZ8v5tF zwQ7lkRx1I6-#=R@`m)Md`q#Na+?08k)vz7fn~b?P7;2Kt8t}>IiMVUrKGxYujGZWb zLanz`MzcgG7IDuLahiX|7e$b)I}hh9p%{<(HOiH54&kp~Ytv~>ArTCn#S8~^$oQ)X zh^?`%yGTMs6NUtL_ntBL;MAmDP#8v#36b}%i_U$y`ln#i)B;*>S*Pvjco$ClL? z%=q~elnuXpj0WVh4c6?B5^b?x@W;C;BYJ#|yQV(-^BV8xS@qdyP_7}XGtF%KKWAjn zLectNCDB|O$s?N`pgU^fn(!runKLO{ZL*IDdN#goZ=z)9FDy|a4b+7tIf&rq{hz40 z&UP~#62@?Yv#|LPJJk&HQ3e)?F*x^tH_b5TT8Z=h%QKll3XntrekU{W1ucz%R_!vl zu6JTwtI@B2wku%k4*@aLHLf+aS<jd)!%M#cTQ)o{<ty6y;vrvlB!}@s{CO0_`ltZs z3fJ>dHs*_rgZ{Wh2W%`KXEPa`u}qU^8Nd`Gtzm`f-1-zBi0iySJ$H?3COIw5Sts}8 z<+Vm%m)h*yTBpLCW?Q^x1F!Vd+Cd-yYm=~2?%cW>C+BZ7&rJ<xIqNRtBg?sU36IuH zGk8uOY8JK)$4P80(iq7HrP*8qcI&NRs5o4XL)iMFv+i5c$~Hy3oMB$wp_-Th?yNKL zAangr28eU(Pbpw+wfW(1ey17vQuDUsxUj8DIfV^QQ0G0jGyEy5^P3)CLis=cawvai z-5gx4GVHJ%DF#_>{WkI2`jH<!Izhz8W}oAaF^s~#^M*_X2XtOm#D*kvo)l8G*-}>+ z<t5PsS#I^dD)cT0YpM^@RaIwOUV(>b9w~ZgNut<T7H`U!4Nfz|w82YY^r-kX#J6>( zRG;4bHiKMr_Jpiv$aIiF9yPwvac%awnv<K8gmQS^5Q443>2~cp8C&!2=C}j(2#tMi zjAaHm5bPpSUwa%RYp-#*{ngfz;(tXArj2S*S=&8{L(57D#>Sy>ye}&aBu|6{WXYoR zJy=+9jhe&f&&Pd^I=}K3&D!?hXM~&KKNL|-rI@I}J}9IBm%CT4Pr(h2lA`RU!W}#z zTt1O71J@X3uEEEm16dpYC#BMwiUd{3p3PQWl4fnzvSl_Q9@M}hNeE;-!hE}nWGGc1 zPd%s4GDneKLvjGcS1HB`9XaviNE~IJ5)rQKQ@w;(FbQa{p*Dyv{NvkHXAi;5a-v(C z`r^gH3Wfzd%G^(xROzgOnu~kNc%v|Y{{$u`D4$wu6mDT|WDAsPz{x$PmVRmi?cZF+ z-U3yHJ4XL3ya%Jx{3B1Os@RU`W_KkhwTO`EP<`_mS~KR8U+7dTIE{Ja&Tt#Gon$nl zE(dWJp-%nLFGR6dIAy<_TXIXDnE(n>ay2-K8OIy5nAx_qmLyOgtQ6Fj%*-=qe@HKi z0nCq$syuW4!}7)5RiQ;?m+>J6id0FQbux>KbU4=#b?)3Fg%G{}A@pSk=NYO@J@Gx( z+{gD5$inzGt&2vIBM=9%&Ys$We)D#=;$X>?T(d~*H3&8|nSsg$L4-o()4BCDnT9d8 zE_0<UD}u4Lw;fd;UFHK1Sw-$AMSfUDn)r(v5hd^Sk`)Y2*Ymsk6l$eaD9LZJB+_ZC z?#wseq9VdWMx##Wq_ehmu!z%RL@#$oFo~*F_DyBDl?uh~G*>`&P_=OS)^ylwt2<5* zvwCk}v{^^0RD(Mo4Ce-R%T811{Z?J%>mVhkZSqsZUab`AH#ms$5NI#mLjx`}s<cDr zd(bT?x#j~c4Ean`t;tA{$e7DliznxUyYchy8+U-d7c;x*N+iTJseQy>ob@d<%w|L( zocFxQ+iwIN$`Lbg(^wA>sk1CDaCHq1dn;88aoAtv)vqavty0V_rw}n1A$&%RTW^fp zY)}2T(vF=bG5SC~B*4=@Q8ksK&3H(1Umvsi=+-mqUO_!8b(bJ>RT_kck`^w4=oz2- zwmQq2dD6<s{fq(TOjQ^`MAUW8j=)Q)pKZQtBiUBnNhi3h<-*+j`^bGNgVvX9{sEGR zNO&hvNz2S>)<X=Yal0`ZAdBD?=G#SKJjZ;G*RVweNW@0_IHN=HbIvdd$%?KtCDDXl zS-puTv{HE}Vwupja?ML6W68l~ZcsT0fl8=k*}`^H<U@)jw_TZWQdA3@6ACGl0(xdK zv6O82hzlWrpNr9j5G_^2VwJ3Rizru3uw+-GLsw+ulN!^ZTID%+Zm>hOs(rtPvK;BG z{Y=ms-NO?H{RW<b%v>f<@R!l@1ap~PGv8k0k3-q__{PCC@7C5Fh^ikPxV*RPmYM_6 z0kfvSzBw?k$ERj&%~qlI8?ow$vto~Q!31rW=wT=8P}xDGS$oy?u<(xFOYiHeWgsP# zT)aFG=O0)ID^^KfcN36{h|5_lk9ol<i^Xs#!VJ1=)5TyRo4{4=Mm$HcD9|-JJ&<fh zkv<f^_enN#g)O(Tku&Sh7?;YX7>2Erhw1%VG`GJQ^J0PAl8jr?Yx*E!U4=K2it(Ud zQ6rhrtZtLI1dW*3;fTHQ-7(GY#w6b|7=sK8vsi6UF!k;QP1I`7T{{)D%r}j9f6JY_ z`axh=-H>^}`P?qy;<rl2GrJD5de^xKlln23Oy<F+EPK<&BrJD#Zc35s&LNx|Ji}&J zXm_K>er7j3=la1cXR(2P^}~G5U@)^Y9R^W~(Yf&ei6pNG>XS)n>Z@{y@SU?&+x_PP zwi4TIm{g4?h9h`GI^_u<CDQ?3teJ-(%{L@AWgch0dr;Ksu;h1GD-v@Vd?KD%8=f^m z;~-ZoK9U+x<NkT(4r1pAmLrJ72_nawwuDKdgr0<*Fp4!2$;P1$QjoiH>ccL{tvDS( zC7i=<#ERSNqK5joFl%3Dof%|KBvEU5qQ@ea%d`kN0xVuIHgfZRyPgfKsk;4%Cssd! zRZy@kcG~O{Xfb=dB)TDUpTCpV$~J|+y5e-hioLf6Tpsh<?=bFK?P5~WABz$q<20L1 zgK^Njk^zL6F8vdO>o_n_hSP(E;qsV|s#j?^8BAB(5Hf@{N#z(eFM>tMXu;~1uk&K# zE;Rzpm%)M=;(^<h1j!5clYZyCd5BydPFZnUI5nru$8oe_LALrZ21JRzsDzD_MOjK( zk00E|rj4;t{uou#?P7|O!p$-N?LHWDp|9zbIyggai<?WN4itPete-Y-G=orT;ji9@ zLZ=ymGJHhw=e8|l=poY$b}_LL$-0_PXX|5f%|!A;LiZHb1)@|=P1CS_a;kCA%$JSh zxHn`U3rtF09;IJZvp#yJae2*p+iYVjBMKEb-&RqNfxq_i50rAjaJMzrB+u3l!Dye9 ziMZoyHmr2-3XD;W@iY-=yLLglF9DNcS7U9=rn>O${@GT2SY*Q<WH6{6fu7s|*TK2< zT3P#Nn0GR%^BYE+f1!axn_2WK8jB`q6;Wudt(Y3NX71&$7WkD1)-24lgPvS-^RHD$ z_24>}7pOi8US|%YNHQuI9Dx}gPKACg9BY2xSRbtn$9iuY9oSBsmKgV3c(wEn=%-nK zD|%o2NhvE{vveJc2sn-K3I^M)_Ob0-oNJyT-AUD_7&*4H{_58PGyIvmsB7>#GLE9O zM_%Yt+6~?L-bud7E~=~mV~m!R6?=_4{MCo0O}Rex{k}23X2mR8`5ssCbIoY$sMFI9 zV=R9en4=k(1bGJ`JxbOSr0X_SY1>&{IxnuM;$(R1rZhlZsNjrRzXB)?&li~var z?B}%klDLWDf^4)nO#Q>nX4L#{frSueKHj{6e&Bw?L>`d{`ZHFsWS3ZmQoc`R>p!Zt z)MWNo*@Q0+(@KUAHQ#)n2!1ZmKjktmg>5tXOlEwvo@l;@bE{CFH1qfBRZ%~VD0^FK zYxkW_5R7B$+uR~XI@m1DA|0`t2h;L9#E9HeM)1wN?ybHta2K0&yD%+>v34#tOPGE6 z`4T2CtnhJRUgKcr&fU(Poo6zxgN->hy>T#X%%RSme-YWd)|AY6<Q>vM0lNYNQ&yn% zUR-P#5K5nU)Yx-dWQHOQ5Jo1y$g%9Mk}!8IeeMr47nESfX>;2=StXRpPm!JqVOg!O zss1JtXWbeChf1w%MT>HGxYweE6iHzp10k|K23P|lvUm(HB!wrCOfHOAC+sN2t35LB zOh)u5<f*#!IgOW4DXvp=1(w6XCDf~{2e47@U+w>B9syRTR=6tT`Fqj2nANt5guo2m zFRo1DZ{oTuaTy*M?|e>p@X=?|N4fNYq|h*m3`rtjb3S)K(tr~W*Ak!p*pjtM&|QE` z1g;w|3YQ_Trwmq5RfH^6ge+BrELDUoRfH^6gsiVr1gXj)W9({XO@BJWxitVf8QE40 zLOB<V*u~}OEb%~M+|m&GzUoKm-f$<4BQ9%Yue(_y!71{a^buyY_Xq#|XDDPs%>2Ws z#?1K7`D%?yj@5<1AMJ1LLKc%*@PGU7yMNKNXMh&qIPd`w1JXJYm<B8WRsu!9-9SC? zFz__+B5(jW4s-yHF5&^nKrT=M+zs3V+z<Q!*a;j0jsd5DGl2bbjG6(Xfr&seun_n< zPy*Z!JPqsx{seRYgCIwZ1g-=!fTchQPzP)SegOOo_$_c4I0bY7age!&1CxR40S|CH zPzG!S?gbtLegW(T4g>E39l%IX`-wm@a3j$7_kLoU_KWm1ZQ4y~+M(s#*}g5UJIHUI zPSYM7*7F_qSY1$D>MeBZ<?cJYy4$<HSa+`~FZ8-sSC+4FS5%g-@>W$%;b7krZdIkX zK=(%axhGU<{MY7`8>NNrvT{ksyGmSfD<~6()x~9nZqEk2sJu*h8hXL)rCx%Nv^H*R zh4Ps~G%44(vEA{?E4*bY)KyihDvK-hDHR(epUO-M>aj|vX=}79ZIxE8Rcc=TP0<Rq zQvT7GTA603_bVh>ZDN^GT57!tV<JYH(52a8w3uj@Ju@@2pZumLX&x2Wo$Og2>(H)C zO3L#<8gjb@-_RT@i&pZ}wDlG1`8fyy(bwVN;ozTqYEO+#*R)Fkeo@gjd%u`iNB_71 z@dF1rU4t(gk}&k*OA?0-A2D*&=rQiGmyR1h;j+soUUB85$yZIeI_a8gr%szb<GSRO znW?j8U;nkV^c&`6WX_$JHUGw&7Gy76<XOBVXDJptm*;=|=37?WdfUo^+gBBOSKm=o zTykgWnzHhWyDF=6W9_>28}9zb#_CO*6`47+OuE!lUR<VoD=E`WTBf!{Tgcx9+EndY zS}cRN1**Im-riy7mR8NJ^m;X(IbJ=tpwv+B^CI5UOH0dFN#shSOfO#Jb$cr-%PZZQ zHjvI;x?oXGj^!esTF(51^CCXAj78b$^B4BGESZrsb=ttV^fGrrMMY`xssg>3AyZUP z<z7?3uq?n`*S%{hbQ!Xx<pm7gBCmUnJDhiE@$Hobl^fi})VZ?KyGk$JFeT1Y>Mf}9 zGO)|^f>p#MMnvkDSGlW<ii+||e7pr~+^Z@4n(|67Y4Ey6m0*f0Jmr`2O&u6_l{>ws z7zSx)=geOaF>~~y;wpDRRh4(m?WG&sg+^s@*&XgOl3FXppd!U(#d>i;Y4P1E`M9ML zo;e~F_7c;5yKx8K?hWNeWn@{WxaaF`g03mA(%q%ScX~-(s#EE$GD>xK`D*v7g3?mS zjFyrzUA3xwO@*4`6R%!XT6u+gwNbW8wW*rn1wDl-tI{itRXUaDzw*o|EzK?{E>m@v zdS5H`R@1wz+_<C2T~$%Aij{)k41fZrb3}thw%0X%+N-<nUaRw#EVbHOFQU-pWvjeX zzIuB|K2o+M$zu*FN%?v*C=B^un=JlDnOb!iIXxlVMc#r6tF)wZ?R8&L$92UK5mmqS z#G7%!cvX7gm&BVc@hS{P+uGtv-6$yS=^*Jzm4TFtIdOruzpcDXmhGz<II?=Hg|)j} z*Q7|io_eeGlzC89PInc0*A}nx_Jj?!k#~Is^M*}9TBc`as&>9cwU0rLp)hM0cEx%T zdqSa%f;;<$zi_*RA{7?s1r%YR)#VY>Qce0w?_GwsN(v*Rd`W15p#xdT))X_L7<AI# zGTe<aqe>cZUBTaR%G35qstwOO?!9I7T6x(TZ<$UVB&=$~^M);`yu*-yRjR=yteQ`& zS;TaiuobdCcdtZ}ge-4fHG(xQyLeS)c~$vp-JM&kYB^`pr0(`uU@dwqPg)%FVak*# z+AQ|&J1SYt$_iMKjj}t-%GZ@$PalSwFjLm(v2k&1q7rPTTO#x0<g^R2zWR;gT^RfF zdm!SyiFdUb;*JiC?svpDyWh7(yu<A4cIU1@_xpDu-eYQN?y0G*VMDgvQ*+OjnuLD+ z*patx-AaLyl4?9P^_oMQczLoXuZI1WP1)nACwuqAn)(`IX>7|yMMVxr?D~p|brlu8 z_G7&NzyG<lzW*kIA6ftU`ke1O3ry+D{?%z;{MS2tt=97|O8aX6B2(C+_56#5xcycB zh2y*bzwdwT3;pj#!{h(q5fD||{SSfXuk;J|pggxk_56#D`fC5e@y|D=|6^`{Z3akA z3H%G^C|^DAE)ntm5B&Ou|7x}E3FXpy-mSN&D47H`wOf33TkrX1eM6)F-llKex9!{a zf9Jd3d*J&IKJ@TEJo1k}_~E15AKUTx6Hor=sUQE3pFI83pZ(J_KmWxqfA#Fn=bnGz z*S~r3rQiN;SM%;Ydw<{3x^Mr1mk<8o&?|?Jyn6JtKfeCPu{Ym(`}jZq>75fN-+k}Y zzx?@qv+Z94r~mDP58FTb_m4Y1Idiu2)4zPy#pTGq`9O5x1J74F5dCM@|35qbzq$SY z+JW@K{^~&bpI!f~teI=p%&Zd9gjUFJvOAlfTV6Ks)3UR#E-bv77k-{>O-lzj6LXGJ zM`vwe`P%OHMVywzImcVUk<<#1Zrov1>6&(<QL56o5nNf)O0TFa7MetMLFK9<o^!po zR~j5t#qY*~GWAM6lD<Z|lBPylk`7QtybY3u#Fw}dN6RVDjmkniB)!UF^|rLgsH_UP z<#`LsyrGY!pwZ%-U0$YqbBxflK$o~0@if9~gp)8D{u+n;5RD~|qiOlN99<oH#C=(n zw{p?#C7cuH_Z*Ui;(_0Sf+{_oGv-=I4i!d)a<jgzWVCE(N(Fa#Zzx}%t}V;STr&0A zDH#hOKaeL`QvwP?c_<b&wAzO%Q*#=CcAz<E6&i;&qN!*xX*hm!7A;(~Z0UGy3TIyV z4%3sS+^&+reNCZqzlFRuaH?3dq`X`*;Fo1R{+IsNT$HXIhC^v1_TlT;X^TN)A3A?h zkaeNtX&N+m^$dT%0qstH;qQHY{9hc`+y7vM|Bol6X)git3&+1V!hhEEG%XE?^zWPh zdoz3cAC8DG@qV7#+dndY@lTy?`OAAO@8NRv&1cv3R=5lKfBdxz`;SUb(^3HWT`2xl z^LqRDE$3%9_V({vzB?Cwx&Kc+J#~9A;{8~k_9|b}6Yd)k?|t)|p5Hsa$aLQRdYbkj zAir>ZBmJ+sIZe9;i1gppryTXS_V$nL*F@;USBGfC;q?2K?~0NO$CrF(miG4V8~^$Z zz5OHem-q{7zuf=oExrBw_UHKT_4e<Z{!8Ega{r~<d;9k-|I1JG_U}6{zx^Z2U*q?O zCwuz5Z#fqHtamzn{fl<@_U~KI0SD5wrJs^X=r>3MojVc!>izt0p32|GQ&|!<&s*lL zgt#=vqLj_iD@!xiLc4)ag`Y0mhdDx04|5>O?0E&n`rPu$94I-ZUTbI6zNgJmypm8b zw#R?6K}3&8G^?PjuoMj96G=6@ywE81&V^XJ5Sk64-_kOLVn3%6QZdB99CllX;qZc@ z7kCTSdcWZQm!4Ftg!43Ql0B!?3odbKG&x8?(hCbA7K8uvi;85TR7l)8<!jbZq6Nie zWZy1jwbFsHBXz%C(#X*ZEk}505=Y9rbVG$#n`QYHK*g*Oq##}U9hg(8msadkf$Qu` z!_>R(7W^M7e*=<zSs3Zivh2&sic|{~X0Bfal11&wPBAgY*eTrwy<d->UzOp7hJJ^) z(nEEn>)w|f1UFHnFHL(gIt%)yVs2=UsdtN!af>R6N2;LxK6<|NfDkslh4af`eF+6m z)0!jQ!9K$7ITAO0jz`lHq%{_0X3P5tN(1MlxKNE5FdyxD`_j@X0$BW%S@IR)qI^x> zyE!eh<x3T@LwX~k^goMeuceCoIv?ET`}REAT8$y?O!NZihau7+qv_X_ImC15+au{^ zg*g?)WmY%e6eSsE_E0u+bm3l9rE9w+&o6pt3oZ~NPph-%6&HHv6cto1EzcH8@eLbv zueSUA=`dO!SN&kk8ci#(=UOyz)dKmp#fG<XgU4H`xH7N_RC$>_CDPVQi&xzl8mB*r zXq(Ugqj7T7_*7`$Qn*y<Rchq&raf$1qL(f!TL+S>{aBS?iP!3mTf-#?^-i5iIkYIy zvkydkGkwAIZ-|;(YE%_T+BX=hS9>d&X@8DhFekg9!fHo)VvMc3EtZyt8%Q%FL(vv# z)_jt-m-$7!IlWy7(<b>ZP|O!=%4zS*IFa1D*?m7zHOeWzo6==yb4tsryrBtvuQggi z>ruM)a71ku8G41G%jkWeSExKKMrK~bDzG86%1Nf!ErdI}rlO$I+g;n--Y%5-n3OSM z9OV{N77Jr0UArlB$->M9oCgX^IV_dgmcUk!bT#ddR-D2`tF7<Lq%A_7EAtph04cpH zgwBAy-GGlqoBj9i|LzvpB?|HQ$<v}xh05y+JtH0nS_#&3!JqgG{P*v_Ti~m<z`{SL z{pRPxewXpD<I>dFDt#B-`T)nMV2ubY{4f4woL&rs$D}RvZs(Z@^aBP0$f0Qcfmk3O zaD<-XCf`y7@e`h0*iX`xxbj3Rhsr~yi?|I2E((F<Jr)r6>41EvhrZ{8zFFW^oFyUm zoY0eHTBV=QQ}SjxR_Uza=>}MEkw-%21CX*xJ)}G}fRwp5^xVQz{C$A<*8x%<xd3<t z@Pp9zcAiqc#{tRjM}UNT4v;z>0>u9fK>QPF6ltGuoAKJcHblus#4r3Eeullm-+iBb z{ri6ZweT1652y2A@9DbW&#J5Yg1`S7ZE<0ygjK%_6UF~))L&|G!66XZ$uBqr-2Zjj zfSUY2J`{?Ef`>)h9gnkNt=zI<%h*uoJo%3Gvi%9`S^L8iUGkQ;sYX4YB7F0Xw|2NK z?=SqVMfO#GX`$z{Uom`oDEv;szw+3r$A)YF@|gM9%~oO&f4kG)v|Ysz-BF9*y7eu$ zcH3JeZ(SP^(t52udhAappr>84$%<L}Zx-!tPAFt}4gW&KztLga@bq3O{H@<o&c0<8 zd)47zQ6Nog|1eFf_$W=QADON_Nd6LDp3>KX=g3d?)=o1`;TQ*b%AWlwPua^IJY^Ce ze?Lv_#ZU7T9HXA+5T3X26r5%}&tW{f{+y-_=ed{X2%h)y6kMT@=V+c8Jjd`n@h@qb zo99zJ$MSsURGP91=Hj`YZ;j^$9_{a?X?OEH!BYm?ah^e*2YDWXzWY^x;iK><NmuF= zT9h<tpA!21!H?6l?*iL^dx3hO4yXav0~J6Ka0}o8vVd7YGB6ED0wx0!f$@MF7zrc- z34jZT2kb!Sztbmx2}t-8JdXi~fxW<sz%#((z@xw;z&2nbPyzI}_w>2+=@jadL7(4y z#b1Zbp`VPADB?+6d4_+|PVRo+k#0QiPsT~)ucpF^-~N%s&+_Cfjr9Hxzk4$Nw)lss zmkZ@sGN!|sN4^W6LqL8q7E^(*12QhY4?GLJ27C+*reTtRg@9a?3CEd<Up}x7cmVhn sa1{7=KrVY;4P*nQ!2j#Nzb3L0-REZu{lfJw?Z8eMa0{>$=sSM?C)~1m4*&oF literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__init__.py b/env/lib/python3.7/site-packages/setuptools/command/__init__.py new file mode 100644 index 0000000..fe619e2 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/__init__.py @@ -0,0 +1,18 @@ +__all__ = [ + 'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop', + 'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts', + 'sdist', 'setopt', 'test', 'install_egg_info', 'install_scripts', + 'register', 'bdist_wininst', 'upload_docs', 'upload', 'build_clib', + 'dist_info', +] + +from distutils.command.bdist import bdist +import sys + +from setuptools.command import install_scripts + +if 'egg' not in bdist.format_commands: + bdist.format_command['egg'] = ('bdist_egg', "Python .egg file") + bdist.format_commands.append('egg') + +del bdist, sys diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae8e27706439cc44abfce30db6b9d2ab339dedea GIT binary patch literal 700 zcmY*WO>Yx15cTe6Kay;kw9tkSkb0_=Lz7F76+&=F2yQNtwcT+R7w_8GPD}b{fFpm& zS5Eu|PR!<mf>&$5dGdQR<9Rh0^aw8c_3XpDkdU8kuwP>YFY&kcxB-CxLWrOPF(i;e z23_buA95JL0SsXThj0Xs;4vJ-Nj0Vf#_&W2bx6aY#S<CP2+yaoQ^zz$Zpy=(<Wp)4 zJVTVi^pdp9w+yD=gMeIxR}oC!li7107g7|~cdtQM$9Prkq0u$Mm5{*r7w5Ar)N7vt zzvWVCpYy`5nP{vlr1TkTF<2^}?y3F`Fe$EmVw5W!r<pBoxzf)1*tR)oV!6ZEcO19Q zkM^3scEdemOCwrcW_X1{Zv0?d^_^(iJG8&jQWd~JmDVTQ!1uO=mskVsZklY1{DtpM zW`U144sT|G86rU=%sLAVj*Hxn-mcw8)tt_eJ6#INXI-B%hP^UI$F0-K32Eo0s_UYG z`Nqi{qtr)sZRrvAwbD+hhdbLO!=*BH;n+@S>B0YmPYSJh13!qFpxb8q{d(bQz0g9R z@1EnlysMfU_xWP+kmp~xb6+qVig1k0adg>btzaeji?%^~f?FQsK@Yzq%7ZM-!xrb^ EADG(RvH$=8 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/alias.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..088f91ddb1e8e516a354b29692755eac0655c962 GIT binary patch literal 2368 zcmZuz&2HQ_5GJXgm3P;%o4RrA1cA^buGMz!0QI4Vwn!5<?WIl&7YHD@5M+_NmaU&P z$xUoweaWV8(0h|(-=GiDlde7G6@2Opwca>CT+E0Zk<{>;Z-)C|e!fkhg@3K>Rda;= zhl7h|L+3t-`UMmxoMt4aA*I-78OyEEGJPwvb0>6iH+1t>*aDl)ofjnZek9!Gtrvv1 zggddqIqvZ}u(x@8mjs>Huqz2@y|kSwJ<@5W9uIX|7C%T?O0ZjbJPfS5BY3K#q%8XB zpzf4rO0*v<QFj_+)K4>!P}~g~1F=9Jf~c=So!sPfoBY0XM#pqaj$G+#GA0wcOOD+q z(0fT=fgaE!OKx4f853}jRa?J~N-g}j@MAd`<)YAjzm$F!Ya#t%ELB<z{QXm39c1EU zLk+W3uLpsBPCq@TpPkdab9y^qwJpU^){c1%Lksq*Y4SIb3*g=P{Y{+@H;3u4mljIL zS=LLQ4T?j3ytS!>9u0L_X6kY`Df2uo_-34?vDz4()-82#jDC7};w~t{+SH?6dIhxn z2*wE-FB$@LA4L5GN|2Cp5;9Ihi?h(?R_JhhK!tnQS|%aH?a<@SfI{DEVtF}=yaUnf z@GgKgUpvO3>Z@(hPYVDIP${KOM%vd0vG&vAX?Y}+U&1@UFfXO>r$<rMJ^ucpa=PS$ zD}DoFxKiZhQ&Ce{U2nSn`ltZV0{9|0fcVId;gB<KAV+50ScQRx=#R-OL+LSz7zZXq z7RTt*oxqk3%&D)YMXFQSt`bp0KULch#Ab6Ks;xxUH_>d=BCL|1fVu^uTu_9zsY|Qt zP0Zfk@53H`4h!FSI3|Zou4xON_Jnfe>zZ~ro6zSFLh#tyd5s6G9{oI0+E+u7r2SK0 zoWzOFP7R7P7O&3$@{2eZf&c746#mHYxz}sJ4BY1UixAGY4sS56txOd18hlS8p#mzG zv5%C#1i}goZ-Xf0CW5d;8Lh50Fuc3(3<Rt@Es%#G>R(WBWC#?euP7ujz@WA@uyq1q zgQtbhlbhov$r)H|ZI9WQPS}J|a=iWo>eVjM4z2{?oFgXx#Qq*VWAJokpOZ7|_#a#Y z<>C3eJDAlLcgO4+lntzSyQH{-JMh*DIb+;=+0ve#GZu%FKiCSHF!0sVZLoDXg`KUG zrs#WjVl_Jib31j*03lSh@UTg0|9d1Y8hUTH>WV1_knU4nUk6w!f2VAQzR4e8X<0yp z8Wr5ssk>4lA<n4}>DlE_Wo5b#g|;l}g@MphGDkd3w25Tx3}ssAx(h`vk9B0clb9z> z$nC>2EhHw8sVWlVRC`!`kwkTi%hO1X3dkG7g&R2WD$Z$56a5`})E3PC0w$<6P=t1w z3l+;VG_e_0FBg6uU8FYaQWvV)Dy!xi^1#ZSpj&%Ugx`*$x*bJ%$wwLXyHRvJinHmP zRuu6v0dt27mB`fGAmQrNC%jn{)OHnJWQS^a-yJC-X9>Ts4|Q0?#f8D-w?ux+yQtm} z-}Fogz_X($R303{rnY5Mk9C>nc%H!~!R*0?V9sh&2m`#WR>&SZV`tWwX}EqT6sUWP zgQfV=Sb+LqxyNm=tQw1BEDyK~7LT`(vOsd6`7+_&G8tRTSSf&d?jS4o<E&cj^_pI< zxlH}q#&cI!dOdv3tWH)YaaNORzSp~m__si?o8T!VKNh*bu5E-|V&H36l_Qx5c?SlU z&@sUHV0#2&fPuKf&%F=^cNV_i2|D#6a@PDa*bw-qK$%(--gt8{Zio}Oi;E4Fo^0S{ zpbS03l}j_GaozwERBuCC6JX<WLu8DP`RFA_XJM?pZyI8KhsmVy?@|{cxMX?l#jXDV Dbj?ma literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_egg.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1215c27a433a644b13f823d118af2b692803fa63 GIT binary patch literal 14156 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_rpm.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb9732e53077878795e538338648592606ee5caf GIT binary patch literal 1747 zcma)6L2uhO6ecNIR#azgH*Cea0plfYeUOv2-K7YEZY!|UvZ1{R8wgpX9i_CSkW|yS z@~H*d9rp|79QT)W-7ftLIqi|MlWf_5(ct4V`S{-B_r9lZHa8;#Bl+#lPk;6h`osQN z4<D4rF!enU9C0ks3=@RWj3gdL-yu%8_XcrKc!%V*mk^Ghp`rgCtkHgE<$4fM9>dfW zgg^=A$XX{}=OOXA&wFoB(&GVm=(ihVo@>KYHA^QLp@_ox;e}8t=YpC8LAjWuwKVkH zj*i7a`XVnCH6`VxGn$lAmdAN9eH1wlUykV0x}ah@WqC0Ho05t`*Q#?_q%%R&f>Vg2 z^Rl2R98{{TgpwyTOJ!Ee)CfLuzV46c*YY?$(NuxUyLq8aD&<{TYluhV*e+7UD_^mA zX@n}k;v}A>MLHE6qB}?MGI(n`mck~cX<pE$KYnlbjLOHgflPE4@&TkTDw$^R{8S&% z<J=t3y5Nv*Rzj|D(?YXOzo=(pIHD84WGoECw~p5_vvO9YCLiZAHz%F{43Kuit{%*9 zVd~o;8nlG!pJI#*J|s)8L00DoYDM<ja1H3tZ?6Fw41B{QdFz)dpDJ7X)`R^aZhbA} z<aeY(*gJc&ZD!SWl~?f!y*N9b7Ki5O;kFj0u1r}<eOX=k-99h+s5(&rxVjEgTecz+ zk@@DuIYd2wl{K_B_GMavXwV^A;#0K14PF8pIXNW@V!T6t*|RTPc-(97E%Xa8ydkjS zx9BaN5XaT9@t&a9VAFWZ;2mJYgIj3f^S-^Y=)rEk@tfW$!Km>7r*Qua$1P^_8(YBL zytt^-d4d)wo8(6}!5t7&Nb%=;E<M+Nrv%CXE$3Ef7`whh5S;u<j(i9b%)fY6)+!S_ zkLcDbOXx+s^=d_k#mJ;;KKvJhx`1*4TRHoi=}lJ!z!;e2*iGkOUD^6SOrHl^?%w=P zx6-({l-||oK$O1fm_8&e8SS*b1jIlO?0WyfYJKQ<q&5JmvuIaB$5>YHeQxn{U`F%! zf(vYxJ{L?^B4d+WiqWntp{eyADC?W=E%WEM*A=>w86Af0;BsfS*QUa(QBwoBt>7by zI?iAJN5r<5L$khY1AtQ~GYnK8Y}@_{^dy4M-Aac>fjpC_vt*EIa`Q?y?)5{WEc?|B zD=ZS~V-R-gPe33X;Q{<Y9Fjp4k`F)|;Q6Qj3CsR4XhX&<cNl9U#%3k2rPT+F9o4B^ zo%9*wWyYB6KNqtrhVAT&vN#}Y(`ifWaKk5I;P!@o@|gt^zHd^GR*gM6&#LXOww!T? W>4j&f*|)agZkOJkEu5?Qhu&Z1U+R7U literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/bdist_wininst.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4639f7843f6aa49143a92413b354ddcffb87ceff GIT binary patch literal 938 zcmZuvOK;Oa5Z;HASb3mQaYSGtgz%v;MH~PjRDlGXaw!tXLRvXqlREXQyK6;6?uq^n z+9Q8yublV`oS1Rk(x8qt<In4Pd^59eCX*on34c8La>@w#g&&vV05|~EkHJVHX-0C& z2qifSIVJCjWRjl|$rHY0-+9O+JtV&K8@$OZMtdn7zyYYf2PPpQl?1#8Z9EORbY$<0 zgpTY(ylW?OnQ9|eX^|G%C<-w#W<WtssBb~F2c{uQa!woCunTs|8!G8>U)`0g;Q|!$ z@%3`(b#ho&RhHyQVLX*UdXq+3x=ut~=6O^|&y?P(RL5SV%DRwOVMoSPFN0uSFZ8tf zW{%2YTB=2mYF#H!pFH1xapmbVJ3!J=mf2AUM3&BHKDT4+N~QDKq-A06+(bZOYrbP0 zon&9_prd7XH@-sG^X^Dn9_R8WQ6mWW^C2*K6;x@p*OlChSBqk4PM!riF?D6iGSk;# zmnGO5G_<Drkgf-++gs7=Qx~2-T|e0Nyoq~^dqTmt3)-&eApl7mBFK8j&?P(P4Y{C{ ze8LOG@cc6%T+{61JKqUMBGp3G1+0Eyol>O>1=o^T4re}91Hf(18#BhwTVQrTH5Mhn zmeC!yzWpELx|l&ca`SuE6{3jpL<l<+A}?i~As!2HQb*b5Pdkb>_qBRBZPgY<Qn)OQ v#-+niOA{Knk6VTnXL{OAdAh|!A<NcTO%Syy{~1hf-B%k<uaU0CQoH;wI(g>w literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_clib.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ab27e9e86cac9847b709f008661d7988239f47dc GIT binary patch literal 2417 zcma)8&5ztP6nC6VCX@Nt?FR*+f_#DLRP3y%I8~@B&<Y`;f>fcRXseKkJ+s*+acVoe zJFCov?X^<>19myVzmzLn_!l_w?9A6z9O_Y==a={K^Lx+F^L4-PBN)MNpB}urhR|Pn zu^J8#58;vD!$c9aQj}R3St!GSZD|fpovanK3~i@w)(+Z+c2Y0v1RV=~i)f3wuMl;a zeT2{L08{HJ8nyoci|EP7s&70>q$*XC%BM_~#bY730Jfd-8N6=h?1YK1h!Sy<NEXfn zFN;{~t_B9;Aw2Q}m>3EyinNcwrkL8VP~cDp{IzO-QYI-4<20E>$DrgB7(W~{Ari`n zI%I^hX;h|)Yy`=K9Y)6qF9lJYP;SJgJWcsYlF#n@#>VGk@?BP>EMvJM5fLR#G#QCG zQ9wx*WyRhkl8l0fg5{Lu@tnxHR4g+F0Egsc81t-1Qg&xF1W!!nLj|^S!T@4pX>6qL zjmcM(l8g&RUa+~;$Ta$413Ss591J9}N_Y+!?yp>syM#}ULVzI29+3r$lj(eeC}EOJ zxgacx549kR6<H#pjbk0JD?=S7lE_0|rW67NTi<vkSyU7dB47f>HH0hbCy6>V$R)%# zW@HMR&!Y@-!9gvBsvvy&|ElXa0_rjONrH0-R8}a6s}kC;-pVZHlPG-$3u}?PB%Y?x zOajhLh}Kw0L}_BenvzBgkQR~DDOj7hvPGSjWe`OZ#8{WB9=q^#;Q0m~Sy>3Zu})QG zJ%ac1qXWFa3%jx};K*HC3#W1@df~}?%BmcNl|9AhSUyk=#TCAV&aGc9g)8SABvtFe zrFMlcv4xDjquS@_5-(by+X5QPW6*1@^k!(`RxR-3Ds1H1AlF{|_<dXU^ykWXgr5Jn z@G5U+Ejm@_!mHYs7I*>+mAACug9U$W;qPq=M#DE6?gi*;>g6BLP=${Cqi*HEyGPrv z@uI8xm0NYs@eIw-6u+?FSmMC!$AftE3<cVYzM;V4Vqk0x8XHxw>Q|bxL%Xlt#g6&5 zTXic8)HTEJy>`I2_Y9gCw1@tay4{qaJewvt8A6v3k%00V5?<(>lRFJ-PKKYz;pj6m zT*?ngRzj)50Vo8MrU&G3JeRyp@w`>#^6WixV0E!-i%{^|<Gl7(r}XUL9f7PAHb|}< zMLs2JUO<Cr5ZpIMYgi-bu0AhSQL2z8qIR<=7F^c7B#+aQGR>5=+Z>2dOXy-1`l=9J zn1TU2RU!%t4*gBcWZj}{QqD%Wk?VuV=z49>n5z9mCOJsuF{>SYtm_u^`IHHL6od^^ z?dYymJGy_=E*OR;S-a3d^xIn<pkTLYOW~?f$W>2=Mp_7cSJmy6um%uZiv^1m3&FWc z;!sDp1^m%&?MRkR>&`mMfd^!$yHBvZCp04Ag0yIBQ@!n$6Lg!_Vw!2~HgOF+DPqG3 z{3bTK)dsul6k4rfG;GkzO$<d(TW&A;e<E=k*8e`<S6Q)NB*mVITAJ>~C$s!Wz5HTd z>I+hFp2}?!wwy&d-QQeW<6>U#G|Tl4-v`_B7nqQB-SVwl7Pc_<ED!fu16VgJ#~E0I zhIV|*1^#-iY3#x`-@Xao^iQuGEv>n(Ug`DOhg(420`UayVJ|ds4#V0H!;I51WkC1B z@MRgLIs>q3hau&07>bVpuL;Z6^pWQ2JnF<qopx{F;3l(vaGS3FPK=j<8E^2I`q05L z(zU}yGOKqt8t`X;3uy|o?yT9SMuQuh=#L?@q5jKaif#*<PN2~EYVXTtYY(8aBk93( J-RkL|{U0rsr{4eo literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_ext.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7eab2088c763a3923c7cbb82a7c9b76323c0e3a1 GIT binary patch literal 9671 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 Z^vzn(Ecx=E8b6qKfMfAj%saL&{XaspfZ_lE literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/build_py.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..553beba217e8aa9c1d6053a1908a923584a06b64 GIT binary patch literal 8547 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/develop.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..865d5122ff50e80c9d4670634e8aa2812d9803f9 GIT binary patch literal 6388 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 M8<x5DEA5T{1Bz{(q5uE@ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/dist_info.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b78b8df205865f1c63869fe1cc27c0ede8e3d85f GIT binary patch literal 1343 zcmZuw%Z}SN6y-y<WZ7<m7C|O`09rNGVmv_6MNp(cnhB6iF`Mp$0)$4SJu+lbA!!6r zJgX$%QO`1ek?-KPtNcP&y_X()GHGd$yt<}%&bjyK>2#VB7{y;d{P}?s@;5&0M+CtW znD!wok`zQz$r@Tv*m=WNyx<gbQ4_5O#ekCML=NQeEs;aT-|%86*&ig2`)BE?QKeH^ znaSEZQMYpqkx`Y?=2iNe&7_*wt&&;YX6`~|FE5m8GTW)Dp4V0BYTc$Efde_qsgF<f zYE`xpLf+^_h57wp5IlitXRs&&Oi95cEx2S0T11k|=q)J*JC?vNmI*w^as)h6KRU4M zzpwU;XP7*`O*!ZNNG%q}=cQG@daC;04{EYXx2~+)x?N;5Jag;KTG{MJ5L>Pr_e<t< zm+5&>Z1vhyDsx7uyrMuJ2kxlo6sE;CNwOgVR$xo96bS$bBmr?`RWpB2OakZrd3NGf z-APw>0B>E{G{@D;MZ0t_em=3vtvjc6V?Pb6T}@986_|Ce{8u2u)n!xnO6U%|VDBOo z<V0xy-Ob_u9=s(2g#;1ksB8LxXiiNGsSxj$5j^@k;D%eUN08maescr+`LP2i;^4&r zw1r?pw&2t&dPz5ANjFr$+_EbuG3<P|FC$6ZK(aS<Oy05kMDly&lDXkFmeDqGqh-1s zZ`c*waz)`iym0_G@(tfkHgp-me+<3{?9T9P*BfkpKRWoJPjB4RPlLtKCl6j<KJer7 zpetBEpZdEC<-}f}6xaPRL(pQzuy}6Pt(k<VQLW(^MTqBzb8S|o^GsVGb)~!Tad~br zD9|uJAx<9c3Xc~Q(?dlC_}EM#_gP2Gmyr7wro96Tp(#zm?}#3;l=e3l%z)Kdp7=zF zwp=M8d@96B%XNeCM2Hvbvbp|eES0TH9gO8CYpcxOWd_Y2WCq|*$e_Codc<Ihk$w0u z5*G1cl<<Uyd>;E)2&pR}%-3+ne}M|uu5RqC(nc9{@a}UD$xyxU=Kn$Y<k3#SW5l#b LAz}%e&<Xz+)WKXg literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/easy_install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4cb12d1bb55b95f042557968654caa687df5753b GIT binary patch literal 64799 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 X?RaghKgT__a+&M><w|AW$e#ZPQO4j& literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/egg_info.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dc35e0f2900258618f021360c2237eb0d33bb206 GIT binary patch literal 21620 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f833fb19b3b14c6b0f21625a74e2675eae877084 GIT binary patch literal 3975 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 AEC2ui literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_egg_info.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8da6f6ac0249b2b3083c3e07d9ad09928d6e979a GIT binary patch literal 2376 zcmZ`*Uys{F5Z|>O$N6^+rR~wGpj3#`AT<HOQ&p;}SAi;|d!Q0XR*~iN?&X|w>~z<@ z_M+=kE5Qq&03?z}zS6$(#8>DOzuCmsYp*!k+1c^z&g}eV#(B`|wHco9ubWT)2pIc^ z7WLBrb00%L0TE2_jLmq+XHMvFT05B=x|rR}n>E6Qm3iR((6@XeYtDi&*yy&x*7r>K zqWOx6ru3(6*?8%N9pOA?!{A?7U_-~aSurtzNL5soX|_A$rnythW^pdSw)1!<^*m0b z#%im|!5&7jN)FN^na~OK<AAx3p&x)q7IMKtM{sz{Lr*vp9yWw4yjLvrMML<Qo1!TK z%z<c$Hs+S-h%V-~=)u1&(@%3<##t80$s|hi{bDhCw3ZCwd@zFaHc1C?T_$CrjtBdN z8k7feKu*RJIdm7@%^A0$^sV7yvHeE7EC!pmgR)3C+@^<Sy2}oRCZGg6VG$^N;uM`u z?G{eL($g~A|C^}}RA2uvE@$)cJe|Wc>-+8G*(9HqPrn&!SyuD1C^CJPP1cbf*JsvO z9nFu;#WYXLG|tk6jEZ@g7P<bAoFeZSUwnFQ&w2gRTe;ZcW7u2$1m=V-kzK-BA+Nx5 z;jZ`#UOG$4E_TAF9!6v3Exi>J-Zp#TVC^Fk%`%v_mhBTZ?VMmYB;5%`sAnV8*nJb9 zEZrMAss&?~n4rGgqIC)$V7`pVL{%>2ews^B-_%^5Kn#(+zlb)0GQIiXBvMirl|oLM z?!#1<D&0fs7Wvu&Wo+0XTSro9h}8wSVEpwK;}qI>^SC@P-n2;bwQGJEE7&v5qAKTA zsfVs2=tEzoQ8E)I*o(EKgDuQ!(xp@TwTHFeS0L3FK^XV(YjclZ#2kPwZk$8x-QA~n zQ5H5aEM9+tS>v_hoRxeEln{S!#nm0VYOGiKPU%mZ#A5`)`5oBix2#5MqrZo9+K_Z; zy${rB-exP8vS1qMvg|H<Yh9Zcg!7j01X;L1@_pyZMtj*`p;#>H{;rKNs-Y>=aipqz z(fU!&ila223~aO({heZdOv}$Sstt7bf$2c823Aqv)HaA|q#C8At`hI3I!p6IMfnST zI#Wial2UzaU(4sfUz?_UE|aR1#;<a#PY9U4%yp$?bXxKzNZ^Itei;fODs0_h&UQJA z{JS{2aP<bZ=u03BuwLhv_!hqgXuE*;BWH1`KC9015w^UACt+&wq(Ve2>yDzXVLjyU zwcDX8*d*l$YIX5nKWFWX;;B{Y6dndePY*zTWxyO&|0+POv)|a1W1zBM0)LC7yPMed zve`tRBinPn1M~c*;1Ag^pP&_>d7${Y9th{e*~VoKedW^uPyL_mu}d6klhs{%lw?>@ zig7eiZ+GY{8Y6v_j~Cv~Pmjm1`S?BQ(J*abqe}fOEe~vnj33YEG8c+GGz}s5s>#qb zu2zY0g)Y&G57YTufwVQ+gm{M1{TkaeNtoB>S5T5&Ah`JATqNrp8Qsl_B+m4`(dGbj z1%ggd?%4E1d!sg?z9d2)fZ8}&Q8z)p!q5Z(bGn_y)&I4%JM5SsiYO1G$h4zqR){Ji zz8ghPt2o=dX-1JK5{NrO>O`gXvtYWFma6VRst0T8I+4$b+#*80oXKhORaqyg$<Q5i zA0*(O<GH>YxIriA1+JpE!>(xwR2ls{&^GqA8g0P>qtnltqH8M3m~i`zbhP=eVE<gK l!)I%=^=MssQduMK^UVZz*HO4fm1B|X^T6o>w=NId{{RsSVaWgh literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_lib.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9be6bd26d4952b5cbbef5a5612c188d8be727d1 GIT binary patch literal 4052 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%0D*F@kYQ^>qd3xn#JL#QT*uvT z-9g_S4mSHgGv5KZ=4yTlQ*<wdKN{w*m&v_Nf*pL+LVdJ|zoQicXlF5Kc54i7B)F<f VhV4FR^xj3gnA{rws}1Q*>%YaL6jA^H literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/install_scripts.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb0d5137059d21d282ee98939da6ff8ff7d851bc GIT binary patch literal 2255 zcmZuy&2Ah;5bo~z-PzsPaefIwEI|ocL~Iebflw5pL?B@y<q$LiwZ_x!^-Sh3-Mu(o z&2qqzxbX_CkMIaQN?+l^E93%Iv%8KljMcT>)#d8ys_(0QFdRk%zWA3r-~QAi<PTh| zKNlwVVd!r_2qI`fN*Ys&b5^j@VT6*>jlGq|kNs{Zhy(a_im>d(y)ufUvLE*;c}#>W zyq83H(#zdrCw2vULdO1I;GK-Ab&7hjJ9g~gVWy4B_NFGQD?9i)F$Z5slZeD5c2ib* zsw5YglBucHQHuY({v4RxhoRpGAxTUHiJ73WBbabr5;(96AofHg0ujEX5O5Dd=-Z8~ z(k3Yiu2YpYM$bNZSdXe&l}RyLszxh|4@ONf)uW_38p+9oXVrc^I#fy1NVT%mDTU+l z!(WW)a~S$62t#tZU@bYpB+`~}M-Vul?LHd2)~!`GQ9hX2t*pvSmK51c^18u1XzNuq zmks2})w0<Cm8d>gzWQ><l+8|)HFsC>-AxZCRc@YtyrZR=Hm0r%eRi7GWtmiB=iG(2 zn<Ev1!vPG9g(q}CXSdE<{Wq@D%VIbljPA0pU?L#>h?ou~Yz|j$$pT7&mv2e#=AOD| z{5)8M%Y;<^1oXTIdy#s8i2?gQ+RvF8v@9Q*3n*c195axcFfJaubEmU&z|J*WEf$#^ zJ9DqodZ6_|>kD55pbc7@Uz&$)pnek}*wFkktUPlizxs@+-&=1&K^rcvoe<E6`E{Hv z-e}QJ@5L?HxzRdpZ}H{{IbjdUcNgXn#Cx-ieuip4|MMwu0}9&PRako)t|4NFd(*5C zYk1j6zL4qEBzuK~EdhY%hmczUVch4L=4x8OYVv3nHAm*4uC~E`{FZ(DbxpTdh1`~j zJ^~na@U_88YX|>Q_rV`O-NNHe`4y}XuL1~oi9QFcZCFpuepX1Wpe+!4Wg-pV&#DfS zV(m*Iy5sJadx@3`fun|K-|4EPlyM((@V!(T*&KkI#26J1o^(Wesxl*0eCcUciTY5V zRa!?MX|;jQ+&u}2*;-wI>qe$LEfTG5w6E%tH;GEhIK&VWHPLY|(fmLrLMl5r#1mF| zANLh@JIiDi`!eHcDXfdxi2Xf{tGKJn%Adb?xYR*CR>iS?=T2Ft`&T@yqv28@chofy zn=te}5QJ{Ah=%k6^Qq5Vm@~Rb2k<+fIDG2DpHCylXCdrdrL#-tDTl?NCha&09`OQ5 zv&S&>k05|%3~4s^N;dZ?G0wsjP7B>7_f8yGuPBxS*iRS`faJYJ)CL_5{bPhV$@}^T zpjdDW)HK635N_*SBgbss1E>S(I@{i2;{-t7daw@^xeoi##e9H!F#E78By`2mYhaHM zJ|k0)%z<3D#?fix?g%nw)=Lk{TG(MaRZ3QdPs>C<o89<g325NJ=(b+BVDNQYTY8xN z4eZ(-Z>o!Me{~1NdngzP>taie`|C8qftJ<Ux(&P|*3IjzQrFSW$DUmY8whoTd{dZJ zXu_bhURP#_t*EseM@!W7mrUV^Y8$3?WguQ~4B^W-$R_YyNbx!v>l?s_G++QXvULAE zQr?F1K7!G`41{g6%?=xY6hsW*Bc!vN>uao7x_uVTyJM<ugM)EkL*9kOxs5o7fTo3n z`GE81)1<(FVHI#L>Xh@Y&v!Ug7{Zybu!XA*#rO&#?=`*&A$3{khVORWVLY%sqzt^y zh3+yQzjL}iZA$0DR$J&9oi5u9zR&6=2s><^O}LV}o~jgj4fc~|7r|=$UuZV`ba}te Ru)}Jk!+>r<u0nR%`3H@^Z~_1T literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/py36compat.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a9a5240ce53c12bd04410cf39e5584c5ee393706 GIT binary patch literal 4588 zcmb_gU2ogg8Rj7=ijrl;PMvgUi;d0F#!6!)Sch%R3a?#0hF#Ps(f|R33>?iv*;FW! zK8H$eLE45n*!BZ<IbibTe#`#Bx!u+NKreQ+=RKq(%gJgCsEqS{-gDm1=RNc<*Vmf{ ze!ahc_<a19Vf>2*^Ph#zXDE`R;s$4l(WBN(*pT%YqrR1xL#t=$zMa^^TCb-2wZs|L zdv#{~%HR&KzcP6J)a<!YBdQH*+&wkLZ?V!?u5k91(P{o0HyL{!rtE_x+eh09v-D*o z3O^5uLyT*Z$Fe}j>BmVCiI529zXik3F%ua*#*LoIS<m7ow_X`NJF0P;*IpT?tml+$ z_3GT^4XnAm$=A>}c#E&2ZSpq1f_9B>@J+NWewDw4cAam5(QE3eX2cIT_j%M0MoA&Z z-!wh^zKD-^;?&DU_A=&idf@dl@pT~hPM8fLMZ6y;adASkUVoH^MVzI9o(Uu-M=AH> zR3Ai=j*2*uUY2@ao)m{@KJNas+tjNMGcU~wFXD0G6^D@*W;_BV`myxFB#_dJj>9O& zYUYh{9u(2)efkvK84vR$8b)am(aqlC)~@&KR2EUd?|2zZAmaJ?ktav{`i8DPBV?5U zs5Ma@pvX^AO^lgwW-w}5)tXgnRjpmMwW@Wf)y`lBpWv|1IroAj(IQrg_F(!*l2|fI z`du0&P}P0S3|YYQcDyH#K7aVdBM(Y0d)?x=SlJ+>Vw89Dla<LLlEq!BZeLs>9`cch z=7tz%d_-K3;$Xp2clu0Eh9b^aFC*%b>pY9KruR?0JP2O|2aylc1m5=kC{DPapLA9j zS`tF|xVnZ2e0^MLfVs@CZ-#kGZshAbA9ykwi4Zc7_8<T@=Yc4^tPjsAqEtdI_@3|{ zV8^})L>$R;%z34^!5c`E)ji%e&mx)LD!ec#!b6ZA!h<3q-(Sl0ED$(1?t9yBGE#?b zoEygrpz&cWCF1DkUIaHp7@)skBT6K^9$e;S94*D%>(tfTEAi>eB1kzRQL5{!3v+6< zwK|{cpi|#lon5M5ZLY3BZ5NLSedtcAYpWY8qY%)M5C6juR}e1$d33iJ=6CZr2Y`Ut zB-shSK1c_}(U0$HjTBjy$n#x5$`CT$%}+l5NeM6TTh%&`N>?cu+o+7T%a(uRAG{7= z-Sc#dsJ1~$MMw30bP8j@X6D2=V{(HcRgWziPnqu96L!X)n^SXYO{~J0)h6Z{d*J{# z&GA1Mrh5>`Xh)Kp74gdmu2&qw@5mL?5O8)Fg)d5^Blq6j-SytUupdgD8GKDBw|yNJ zzQ1&~r(zT>uKYhw>5lR|65E~SX^#W=+v2##9Y>j&R5tOhoRSAs5B8;=sL33-uIdzC zJQf`rNlUMYYtW)<U@i)aOq?i}f;kO_k#>W!+MqpGE((ZAsWW!7#cZ?1HrV*a<$77z zvIhD(init7(3uzmDr{gLm{WHAmkE1l{N@i+v#=&+VIxha6IhY6seQaXv9RV%VfoUc z;vP4rHmIFhoh;0ZFO8#n&y0yJ|B5{>x41oPOsq5ZHhhB_M_UWZKb@!2^Dc*%T(9;$ z!_xxZ;_N+sI=(ZHS`DB&=jkkY-;;;gDB<2=0Pg_;6K;*oJKp%cRf=05$XiRYPP11p zVdpE=qFg89eI(f|RcmEX`eX;yi~%`xP8g{g;4O*7yHHnYDKe;X0ysy?m5tn<DtiE2 z@6-eZTCXu@Kq|AJ_Ur(UgPwDc6@FY?u&^L&e1al9R0eCaCjM;vm2HbTrp+9-VK!OY z9N&JEt<Oj865|#&r`RRCYn%TJ9nN@Z?c3VgH(+g}fCmh$!k(C??3Cix7}RDC*$#GV zSN5>>#_KB?a@;6^I_w{G>Vhs21UCXNNkciYB)1myA`qUQ(P@QuY^^5cE?~Egc)?>X zRW+T}F6zhy@g9n#jsXyBva4*|xl|YP^B1ZhWz!j274)iwLqZ({ToeQ|JWj+-^sE^m zY=$QZiGO^5!Uhgp|K4+(AZ=<-YsWVxHO#y-b@c9f;SL(J=ERyfXF3p$cAptXcPh1+ zd&*s8_ce9xASwV;^ynK$+^-;9ya#sF#$f<J!!yIL-WOVN;zPYgbY;pelfP;%Gm&^7 zTb9ZfKg19wA$JtFiQ39v9H_b!p%2(mjglYTonwy_@6c{aL`wt`4Gf>6$QCNYZdy&Y zVQ;|#<6D>Nzf7MC?UR2j9Py7BKzI6KD1LV=s6Q~F(>{`jHDMZj9u~C;JEgSZ4C*tN z(ux>kC+Qk}4JlQkIliOe>E_f1jSU*RqOn2qq@qC|G*4igt;#lRud`OFzD=q>r_e4K z6yHasEP#ZtXt;20@c|7zsz~uw;43>WqM@oots2aKgeArL7gb95P0lB;qcSM4S<`e` zi?uCsZR(9bx>UJKRu>AUNLys;Z44F)hEvb*B~&^3ihFCMg^N}$fe`IDrADrhMlfFZ z;zu}g>5yUv!;V?{7~#rAIoB{ZLXi$CLj&6Q=B0As!tX|)X6fT0-d`&c=@(h~nibz7 z5xsOSN<=X*MmaCh<zY}h0lyoe)=Q!0@5jngYh<Zv?%QOdZ?cOrtz+)@7i8ML)JoN5 zd!4p&eVsCWUp4*8RnTww{?RB%C=M{H`##S?-xr&>Nwtt4i#Qxc_@w1Juj(`?2%0tE z2nrEF{v$}`f_OZ~w}vQs9|`g-LMXX~%B|a`d%d;kUUMCH!`*aiZcXpdr-#_F_|cc@ zXDAxgmj5ZB7pkV%>sVqJ>*5zw(a!&Q{hzTYDe_#_X_g2<Bh_AhNYh8W1`xHmoSfr6 z1#Iu#<@3HvNm8U;86S6t`0$oxUL{FY9d<^h6mMcixu2FfW0!=}FMdK2{FyDQJ!zT$ E1>nZC{Qv*} literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/register.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0fa395404e45f73078b4882024887897d11cb989 GIT binary patch literal 745 zcmZ8fJ#Q2-5cSvIEtiXgC@3O|tq>=XTZ&W>LO_a$=88}RElAdC?JT?U+RoamD5rGf ze~^^?CAU=k1uDjScTt2T&peMk^Pb24xW7L`Fp8fqzda`i{f>*>U;y63bVpzW5?G-Q z7Z^uO6zM2I7<H^jFgito3U-SGlS#{d(1Ho_87-1Okck#JP-W^>6&Je!WSinI07z6| zfeIpN%i5$!1Qz5L6%#?B2n%U1>&AK6S9qHqeH4BI)4c(+KDa@5An_jLdEAmadV?Z9 z2eGgNa(vQG?g>U;AOcnCDx|Wmd804P`s?|Jv(=~7>2Y?pWomStH7*m<_OdFy6tA<v z$;@9h8m!3%t4t}fMuRNyufBV4-Ep4VYuhYMU*|R-&*qE8H0<?*=9THXQj5S$-_$(? z&4EHZq@~to(3R|CO9G2hpkvHQb@2=Jdl3A4lKal)wy}qiuvF@>x~g^SFOPC3{b0Q@ z$~}f#vV7OLrM>Q_P$`A!=3o#eWQLy-27Wz%I0k}NAUNe*m!0H1%sB6i7*xb_&M${j zZFc$z6xm#3%DFHV=Oe=?_>qZZ<FN#Qi(e|mDH$V+Nq8dQT?gMNH{QNDcvvsDS6J?} dh3Pgj=5FX?bN=HB>D!Iqckz#mgme6i{sTFZw}=1$ literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/rotate.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6892cd9d5927e2bdf271ce0af10219ae3835548e GIT binary patch literal 2494 zcmZ`*OLH7G5SBELoqgEZIL?a-sVRuDm&EH7MRA}^DiBkgFi@!?u$9!XUTN23&&!gQ z*i*X~9I7~Q;TN!b<ieQ~zk-vlocIel(XI9R5y(tQ>S;->ethblPZkzx1fI^X?>yB3 zA%Ek?{BePJ2u*zl9VeV7B&8ink!A@?osMH^Cvj7+<5}8G{EiRvZc^z~VDyq8t#+z* z&QEG-y;G;;Gr}u8ctLm|>c>u}!QIECRs9D}AuVbey*&F~NF5bjy$jz?k`G{5-innT z>Nrtf6gtkcPo>P|HqNW~5QfU5JWab9@1dCa;{fpxn)(nrK{}L^4&$`raMp3T!(HwT zoQ^jjptR2`F9;|d@G6V}ukkvJRo(#Q7K|@*-PNLeV@o7Li!e{PkRb=1WV{1v<(Vqq z<FB2&7w!vD#MvO+4m0swC>{3WM5vZi`e|49c0V#SEpLIzTF6X=Iu9*7T$AEp7)!xh zu(XQjt@BvIYF@4YA$mHON8$5bAw{Tn#YK(6t`xA%!?R(_ez}$n(;d(|@6W`eLKken zgK>3_g2V8^kwJR|O<jYIlM#t#J$Msn#tC?cZnqrcS)EOQA|uewxF`#P<0_H#e<Sh| z2zdGNhE9u(A}-eBOzCcttoNP|vORt9{)Q5ISm-=Y)OoTui|ocM1nuI;EX7%@<8Bg{ zBFZfs)D2Y7hmKGm-ty+j>i@31U>ksbX4_9djL05XwjanPO*uWLKTzO+eZaW`9EO~u zrgo5f4092CLb6*f(e8dteo4Vul)yR%*L_Pe_6^Y<%GCZ|<(SDs#M=vd$|T_alx`6# z1vrx`UWqBgi-MP7yZq|&A%H{`q8Im%!aM`W$uP|!%xl&k>q-<|36SKi6R4bmXHB#R z?QpeS#>Fb`T5XHLV6|1=xghck3Kog;$d@<Q*D-2gis$c$u$zT(ro}+WQ^z47JZO)h zS;r5+glEk$)nr5`bP8tu!Vch8+km&2#0|#7yHd26VeR{d7ItpdHDUT?Z8HJbfNjNt zyC@g;_@umh632d=U5IykGs%11L_GjvzV9WyXS^LmADr2M{kCh>WF2YDXL12L<A6b? z_H{QI3Y$huEmjtbSx-nb%rsEfY!K<ALMYI@NMdcS0z9K(#s%mi_#AjGDi={QV*AV- z(|lFoH(}m7i_jWn)OTt$fU!vz@nttydHpq}p86f(jm=)hzkmSXKwh3=PG;OmXiCRG zAO3*=-6GF^A2Xnwi93aie4UKgbpjl!y*+<Yftg^$rU2xz!#(Z;FdYQs*cmyK>J*?1 zV+}`LpEP(yFN^@#u*1O_*uBWfkL)HHJBM4i^V#N8Hg?CJT^)=(1T(C<q<*&NHGxCr zpZfA-2`NerfIqo1r=O66+fU};Hvs@PinD$$G5=r!86^3Rq3@o$;sOM3!6FO6WrW}! zoq&;3I--4c9)^x#xiT)66%!1EPIa6L0Lm5EZD{|M0LrVt{s7t>h__FoBZt}lVXwTl z!fj4pQzsV^lk18q>$YOdK3dDB4*R2%j3z^nZ^3CA=hLuNFUq>9kZ<9Nx1lrcULI!_ z(2!1ZsZB)+sFO-ata8RhcR{ff*$m?qE{`HO%XqQERP3u=te#NFQZ0or{xD18Y`^8t z&>NzR%1H__o=pjcYPkaZS3F}J5W4|<g_{t~4c4GbbQy3Q(10yjL^mJ_H(;i$o%wCM zRWm_k4T~aEi=s5=!$bhxh@yjGH$ju(s}e;#?*UQgLiHeNV0|@>A=o;<b>`9zlnK$z z<_vimbdk5Q!>FCp*<MUcF|q<3rUkVGT|iytGG?!$%K|T0vhz^u7cmz0SEG&nEPL77 zYnd~DH_sLc{1s8N{9@yEAH;VqpB1yVIK;9(OD(lCzQoIHPyIi2O|Uuh&jY*!3X=>t L6kc>PxZL>{#fp~5 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/saveopts.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..4467d4be8f9bfaa58c6d3fe4ae9c27e85e284995 GIT binary patch literal 889 zcmYjP&2AGh5cbb*vZSes3P>RJuo4wg4oP}IaH$ZY2yPKl50zF$)^_a#hy9D~Ep4<p zwNJnc&>nduUpes#oEUF55KA*V_RN0s&1b*c-R&V*(T^AB-w8s$+-9>p2;PF}LvS2% zoT3azI3p3k=p*8U(_6%;AU8Ck+&e`B|2I^k0kJ!ROT&^PpURotDM}-YoL$6PB(7ky zpy9f~0R#d?n4^er3}7VkI6&T_$mc!)cWj{JO94Q7`TP{3Fe$Pu&iOEvxd_({bZCk& z4yQ5|%h#?v)KyugQt<5pElgF8lIbigR9KiVLIIZJ+5DK`mRuLU&Q8E|39d$Sw89dt z$knGB&+&Wo`NN9Vl;f{Ng^T^GS2eyPHND4o^d3R>@SLnXFn`sleNLe2sP5F{&a0_J z_oViY(c<U~E%wil@c|uj;JY^zgV-=LohWw$%YHj*=tdm`w$G(DN?ue>RJ+$^S*wBF zn+ely7?+8$zBD4!wg-cAF^#L#C?~uPoKSh33ESoBnyD%ubgidFI<=l_0g?-2WIofD zCK<OBI#{YzV(Dd^{zU2#p!_)*o2(p{vK-1>n>bB}$+uZPH;b3!Mrl(NsooA-zT?e( zj>>CGq4@(q)BE5M?qHAfNq`ACzyW?rmi>RlP&jd~ficING23G-D|nT<xX;+4iqkgJ zWsDaI9Pe<U6D6BRsGdNBhWVCz?9QCl&U6P{01Q0RoJ|H^^z8pAqn7^&jzEw`N<}vS XTcA!I<&bS~yk_{uy)Esue@OoV?eFuT literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/sdist.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8af135834d515f6d55ac5e0339b7a42f7a2592ce GIT binary patch literal 6185 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/setopt.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..428a0f4e1b579a17cdb16118955483be850a2f5f GIT binary patch literal 4487 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 DfK0wE literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/test.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..35725bc3eabc1b6b5b73b3d189337dc93add6006 GIT binary patch literal 8082 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 AiU0rr literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/upload.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..635fbd8b60bed1cba47319708c1f0e68280b5b7c GIT binary patch literal 5168 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/command/__pycache__/upload_docs.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..605733915a8dc961ce6ecc89130b2ea1ab61f119 GIT binary patch literal 6098 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 ZY5t6~SMkF#DAXWiocV*cNOaS+{|xw`fCvBp literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/command/alias.py b/env/lib/python3.7/site-packages/setuptools/command/alias.py new file mode 100644 index 0000000..4532b1c --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/alias.py @@ -0,0 +1,80 @@ +from distutils.errors import DistutilsOptionError + +from setuptools.extern.six.moves import map + +from setuptools.command.setopt import edit_config, option_base, config_file + + +def shquote(arg): + """Quote an argument for later parsing by shlex.split()""" + for c in '"', "'", "\\", "#": + if c in arg: + return repr(arg) + if arg.split() != [arg]: + return repr(arg) + return arg + + +class alias(option_base): + """Define a shortcut that invokes one or more commands""" + + description = "define a shortcut to invoke one or more commands" + command_consumes_arguments = True + + user_options = [ + ('remove', 'r', 'remove (unset) the alias'), + ] + option_base.user_options + + boolean_options = option_base.boolean_options + ['remove'] + + def initialize_options(self): + option_base.initialize_options(self) + self.args = None + self.remove = None + + def finalize_options(self): + option_base.finalize_options(self) + if self.remove and len(self.args) != 1: + raise DistutilsOptionError( + "Must specify exactly one argument (the alias name) when " + "using --remove" + ) + + def run(self): + aliases = self.distribution.get_option_dict('aliases') + + if not self.args: + print("Command Aliases") + print("---------------") + for alias in aliases: + print("setup.py alias", format_alias(alias, aliases)) + return + + elif len(self.args) == 1: + alias, = self.args + if self.remove: + command = None + elif alias in aliases: + print("setup.py alias", format_alias(alias, aliases)) + return + else: + print("No alias definition found for %r" % alias) + return + else: + alias = self.args[0] + command = ' '.join(map(shquote, self.args[1:])) + + edit_config(self.filename, {'aliases': {alias: command}}, self.dry_run) + + +def format_alias(name, aliases): + source, command = aliases[name] + if source == config_file('global'): + source = '--global-config ' + elif source == config_file('user'): + source = '--user-config ' + elif source == config_file('local'): + source = '' + else: + source = '--filename=%r' % source + return source + name + ' ' + command diff --git a/env/lib/python3.7/site-packages/setuptools/command/bdist_egg.py b/env/lib/python3.7/site-packages/setuptools/command/bdist_egg.py new file mode 100644 index 0000000..9f8df91 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/bdist_egg.py @@ -0,0 +1,502 @@ +"""setuptools.command.bdist_egg + +Build .egg distributions""" + +from distutils.errors import DistutilsSetupError +from distutils.dir_util import remove_tree, mkpath +from distutils import log +from types import CodeType +import sys +import os +import re +import textwrap +import marshal + +from setuptools.extern import six + +from pkg_resources import get_build_platform, Distribution, ensure_directory +from pkg_resources import EntryPoint +from setuptools.extension import Library +from setuptools import Command + +try: + # Python 2.7 or >=3.2 + from sysconfig import get_path, get_python_version + + def _get_purelib(): + return get_path("purelib") +except ImportError: + from distutils.sysconfig import get_python_lib, get_python_version + + def _get_purelib(): + return get_python_lib(False) + + +def strip_module(filename): + if '.' in filename: + filename = os.path.splitext(filename)[0] + if filename.endswith('module'): + filename = filename[:-6] + return filename + + +def sorted_walk(dir): + """Do os.walk in a reproducible way, + independent of indeterministic filesystem readdir order + """ + for base, dirs, files in os.walk(dir): + dirs.sort() + files.sort() + yield base, dirs, files + + +def write_stub(resource, pyfile): + _stub_template = textwrap.dedent(""" + def __bootstrap__(): + global __bootstrap__, __loader__, __file__ + import sys, pkg_resources, imp + __file__ = pkg_resources.resource_filename(__name__, %r) + __loader__ = None; del __bootstrap__, __loader__ + imp.load_dynamic(__name__,__file__) + __bootstrap__() + """).lstrip() + with open(pyfile, 'w') as f: + f.write(_stub_template % resource) + + +class bdist_egg(Command): + description = "create an \"egg\" distribution" + + user_options = [ + ('bdist-dir=', 'b', + "temporary directory for creating the distribution"), + ('plat-name=', 'p', "platform name to embed in generated filenames " + "(default: %s)" % get_build_platform()), + ('exclude-source-files', None, + "remove all .py files from the generated egg"), + ('keep-temp', 'k', + "keep the pseudo-installation tree around after " + + "creating the distribution archive"), + ('dist-dir=', 'd', + "directory to put final built distributions in"), + ('skip-build', None, + "skip rebuilding everything (for testing/debugging)"), + ] + + boolean_options = [ + 'keep-temp', 'skip-build', 'exclude-source-files' + ] + + def initialize_options(self): + self.bdist_dir = None + self.plat_name = None + self.keep_temp = 0 + self.dist_dir = None + self.skip_build = 0 + self.egg_output = None + self.exclude_source_files = None + + def finalize_options(self): + ei_cmd = self.ei_cmd = self.get_finalized_command("egg_info") + self.egg_info = ei_cmd.egg_info + + if self.bdist_dir is None: + bdist_base = self.get_finalized_command('bdist').bdist_base + self.bdist_dir = os.path.join(bdist_base, 'egg') + + if self.plat_name is None: + self.plat_name = get_build_platform() + + self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) + + if self.egg_output is None: + + # Compute filename of the output egg + basename = Distribution( + None, None, ei_cmd.egg_name, ei_cmd.egg_version, + get_python_version(), + self.distribution.has_ext_modules() and self.plat_name + ).egg_name() + + self.egg_output = os.path.join(self.dist_dir, basename + '.egg') + + def do_install_data(self): + # Hack for packages that install data to install's --install-lib + self.get_finalized_command('install').install_lib = self.bdist_dir + + site_packages = os.path.normcase(os.path.realpath(_get_purelib())) + old, self.distribution.data_files = self.distribution.data_files, [] + + for item in old: + if isinstance(item, tuple) and len(item) == 2: + if os.path.isabs(item[0]): + realpath = os.path.realpath(item[0]) + normalized = os.path.normcase(realpath) + if normalized == site_packages or normalized.startswith( + site_packages + os.sep + ): + item = realpath[len(site_packages) + 1:], item[1] + # XXX else: raise ??? + self.distribution.data_files.append(item) + + try: + log.info("installing package data to %s", self.bdist_dir) + self.call_command('install_data', force=0, root=None) + finally: + self.distribution.data_files = old + + def get_outputs(self): + return [self.egg_output] + + def call_command(self, cmdname, **kw): + """Invoke reinitialized command `cmdname` with keyword args""" + for dirname in INSTALL_DIRECTORY_ATTRS: + kw.setdefault(dirname, self.bdist_dir) + kw.setdefault('skip_build', self.skip_build) + kw.setdefault('dry_run', self.dry_run) + cmd = self.reinitialize_command(cmdname, **kw) + self.run_command(cmdname) + return cmd + + def run(self): + # Generate metadata first + self.run_command("egg_info") + # We run install_lib before install_data, because some data hacks + # pull their data path from the install_lib command. + log.info("installing library code to %s", self.bdist_dir) + instcmd = self.get_finalized_command('install') + old_root = instcmd.root + instcmd.root = None + if self.distribution.has_c_libraries() and not self.skip_build: + self.run_command('build_clib') + cmd = self.call_command('install_lib', warn_dir=0) + instcmd.root = old_root + + all_outputs, ext_outputs = self.get_ext_outputs() + self.stubs = [] + to_compile = [] + for (p, ext_name) in enumerate(ext_outputs): + filename, ext = os.path.splitext(ext_name) + pyfile = os.path.join(self.bdist_dir, strip_module(filename) + + '.py') + self.stubs.append(pyfile) + log.info("creating stub loader for %s", ext_name) + if not self.dry_run: + write_stub(os.path.basename(ext_name), pyfile) + to_compile.append(pyfile) + ext_outputs[p] = ext_name.replace(os.sep, '/') + + if to_compile: + cmd.byte_compile(to_compile) + if self.distribution.data_files: + self.do_install_data() + + # Make the EGG-INFO directory + archive_root = self.bdist_dir + egg_info = os.path.join(archive_root, 'EGG-INFO') + self.mkpath(egg_info) + if self.distribution.scripts: + script_dir = os.path.join(egg_info, 'scripts') + log.info("installing scripts to %s", script_dir) + self.call_command('install_scripts', install_dir=script_dir, + no_ep=1) + + self.copy_metadata_to(egg_info) + native_libs = os.path.join(egg_info, "native_libs.txt") + if all_outputs: + log.info("writing %s", native_libs) + if not self.dry_run: + ensure_directory(native_libs) + libs_file = open(native_libs, 'wt') + libs_file.write('\n'.join(all_outputs)) + libs_file.write('\n') + libs_file.close() + elif os.path.isfile(native_libs): + log.info("removing %s", native_libs) + if not self.dry_run: + os.unlink(native_libs) + + write_safety_flag( + os.path.join(archive_root, 'EGG-INFO'), self.zip_safe() + ) + + if os.path.exists(os.path.join(self.egg_info, 'depends.txt')): + log.warn( + "WARNING: 'depends.txt' will not be used by setuptools 0.6!\n" + "Use the install_requires/extras_require setup() args instead." + ) + + if self.exclude_source_files: + self.zap_pyfiles() + + # Make the archive + make_zipfile(self.egg_output, archive_root, verbose=self.verbose, + dry_run=self.dry_run, mode=self.gen_header()) + if not self.keep_temp: + remove_tree(self.bdist_dir, dry_run=self.dry_run) + + # Add to 'Distribution.dist_files' so that the "upload" command works + getattr(self.distribution, 'dist_files', []).append( + ('bdist_egg', get_python_version(), self.egg_output)) + + def zap_pyfiles(self): + log.info("Removing .py files from temporary directory") + for base, dirs, files in walk_egg(self.bdist_dir): + for name in files: + path = os.path.join(base, name) + + if name.endswith('.py'): + log.debug("Deleting %s", path) + os.unlink(path) + + if base.endswith('__pycache__'): + path_old = path + + pattern = r'(?P<name>.+)\.(?P<magic>[^.]+)\.pyc' + m = re.match(pattern, name) + path_new = os.path.join( + base, os.pardir, m.group('name') + '.pyc') + log.info( + "Renaming file from [%s] to [%s]" + % (path_old, path_new)) + try: + os.remove(path_new) + except OSError: + pass + os.rename(path_old, path_new) + + def zip_safe(self): + safe = getattr(self.distribution, 'zip_safe', None) + if safe is not None: + return safe + log.warn("zip_safe flag not set; analyzing archive contents...") + return analyze_egg(self.bdist_dir, self.stubs) + + def gen_header(self): + epm = EntryPoint.parse_map(self.distribution.entry_points or '') + ep = epm.get('setuptools.installation', {}).get('eggsecutable') + if ep is None: + return 'w' # not an eggsecutable, do it the usual way. + + if not ep.attrs or ep.extras: + raise DistutilsSetupError( + "eggsecutable entry point (%r) cannot have 'extras' " + "or refer to a module" % (ep,) + ) + + pyver = sys.version[:3] + pkg = ep.module_name + full = '.'.join(ep.attrs) + base = ep.attrs[0] + basename = os.path.basename(self.egg_output) + + header = ( + "#!/bin/sh\n" + 'if [ `basename $0` = "%(basename)s" ]\n' + 'then exec python%(pyver)s -c "' + "import sys, os; sys.path.insert(0, os.path.abspath('$0')); " + "from %(pkg)s import %(base)s; sys.exit(%(full)s())" + '" "$@"\n' + 'else\n' + ' echo $0 is not the correct name for this egg file.\n' + ' echo Please rename it back to %(basename)s and try again.\n' + ' exec false\n' + 'fi\n' + ) % locals() + + if not self.dry_run: + mkpath(os.path.dirname(self.egg_output), dry_run=self.dry_run) + f = open(self.egg_output, 'w') + f.write(header) + f.close() + return 'a' + + def copy_metadata_to(self, target_dir): + "Copy metadata (egg info) to the target_dir" + # normalize the path (so that a forward-slash in egg_info will + # match using startswith below) + norm_egg_info = os.path.normpath(self.egg_info) + prefix = os.path.join(norm_egg_info, '') + for path in self.ei_cmd.filelist.files: + if path.startswith(prefix): + target = os.path.join(target_dir, path[len(prefix):]) + ensure_directory(target) + self.copy_file(path, target) + + def get_ext_outputs(self): + """Get a list of relative paths to C extensions in the output distro""" + + all_outputs = [] + ext_outputs = [] + + paths = {self.bdist_dir: ''} + for base, dirs, files in sorted_walk(self.bdist_dir): + for filename in files: + if os.path.splitext(filename)[1].lower() in NATIVE_EXTENSIONS: + all_outputs.append(paths[base] + filename) + for filename in dirs: + paths[os.path.join(base, filename)] = (paths[base] + + filename + '/') + + if self.distribution.has_ext_modules(): + build_cmd = self.get_finalized_command('build_ext') + for ext in build_cmd.extensions: + if isinstance(ext, Library): + continue + fullname = build_cmd.get_ext_fullname(ext.name) + filename = build_cmd.get_ext_filename(fullname) + if not os.path.basename(filename).startswith('dl-'): + if os.path.exists(os.path.join(self.bdist_dir, filename)): + ext_outputs.append(filename) + + return all_outputs, ext_outputs + + +NATIVE_EXTENSIONS = dict.fromkeys('.dll .so .dylib .pyd'.split()) + + +def walk_egg(egg_dir): + """Walk an unpacked egg's contents, skipping the metadata directory""" + walker = sorted_walk(egg_dir) + base, dirs, files = next(walker) + if 'EGG-INFO' in dirs: + dirs.remove('EGG-INFO') + yield base, dirs, files + for bdf in walker: + yield bdf + + +def analyze_egg(egg_dir, stubs): + # check for existing flag in EGG-INFO + for flag, fn in safety_flags.items(): + if os.path.exists(os.path.join(egg_dir, 'EGG-INFO', fn)): + return flag + if not can_scan(): + return False + safe = True + for base, dirs, files in walk_egg(egg_dir): + for name in files: + if name.endswith('.py') or name.endswith('.pyw'): + continue + elif name.endswith('.pyc') or name.endswith('.pyo'): + # always scan, even if we already know we're not safe + safe = scan_module(egg_dir, base, name, stubs) and safe + return safe + + +def write_safety_flag(egg_dir, safe): + # Write or remove zip safety flag file(s) + for flag, fn in safety_flags.items(): + fn = os.path.join(egg_dir, fn) + if os.path.exists(fn): + if safe is None or bool(safe) != flag: + os.unlink(fn) + elif safe is not None and bool(safe) == flag: + f = open(fn, 'wt') + f.write('\n') + f.close() + + +safety_flags = { + True: 'zip-safe', + False: 'not-zip-safe', +} + + +def scan_module(egg_dir, base, name, stubs): + """Check whether module possibly uses unsafe-for-zipfile stuff""" + + filename = os.path.join(base, name) + if filename[:-1] in stubs: + return True # Extension module + pkg = base[len(egg_dir) + 1:].replace(os.sep, '.') + module = pkg + (pkg and '.' or '') + os.path.splitext(name)[0] + if six.PY2: + skip = 8 # skip magic & date + elif sys.version_info < (3, 7): + skip = 12 # skip magic & date & file size + else: + skip = 16 # skip magic & reserved? & date & file size + f = open(filename, 'rb') + f.read(skip) + code = marshal.load(f) + f.close() + safe = True + symbols = dict.fromkeys(iter_symbols(code)) + for bad in ['__file__', '__path__']: + if bad in symbols: + log.warn("%s: module references %s", module, bad) + safe = False + if 'inspect' in symbols: + for bad in [ + 'getsource', 'getabsfile', 'getsourcefile', 'getfile' + 'getsourcelines', 'findsource', 'getcomments', 'getframeinfo', + 'getinnerframes', 'getouterframes', 'stack', 'trace' + ]: + if bad in symbols: + log.warn("%s: module MAY be using inspect.%s", module, bad) + safe = False + return safe + + +def iter_symbols(code): + """Yield names and strings used by `code` and its nested code objects""" + for name in code.co_names: + yield name + for const in code.co_consts: + if isinstance(const, six.string_types): + yield const + elif isinstance(const, CodeType): + for name in iter_symbols(const): + yield name + + +def can_scan(): + if not sys.platform.startswith('java') and sys.platform != 'cli': + # CPython, PyPy, etc. + return True + log.warn("Unable to analyze compiled code on this platform.") + log.warn("Please ask the author to include a 'zip_safe'" + " setting (either True or False) in the package's setup.py") + + +# Attribute names of options for commands that might need to be convinced to +# install to the egg build directory + +INSTALL_DIRECTORY_ATTRS = [ + 'install_lib', 'install_dir', 'install_data', 'install_base' +] + + +def make_zipfile(zip_filename, base_dir, verbose=0, dry_run=0, compress=True, + mode='w'): + """Create a zip file from all the files under 'base_dir'. The output + zip file will be named 'base_dir' + ".zip". Uses either the "zipfile" + Python module (if available) or the InfoZIP "zip" utility (if installed + and found on the default search path). If neither tool is available, + raises DistutilsExecError. Returns the name of the output zip file. + """ + import zipfile + + mkpath(os.path.dirname(zip_filename), dry_run=dry_run) + log.info("creating '%s' and adding '%s' to it", zip_filename, base_dir) + + def visit(z, dirname, names): + for name in names: + path = os.path.normpath(os.path.join(dirname, name)) + if os.path.isfile(path): + p = path[len(base_dir) + 1:] + if not dry_run: + z.write(path, p) + log.debug("adding '%s'", p) + + compression = zipfile.ZIP_DEFLATED if compress else zipfile.ZIP_STORED + if not dry_run: + z = zipfile.ZipFile(zip_filename, mode, compression=compression) + for dirname, dirs, files in sorted_walk(base_dir): + visit(z, dirname, files) + z.close() + else: + for dirname, dirs, files in sorted_walk(base_dir): + visit(None, dirname, files) + return zip_filename diff --git a/env/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py b/env/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py new file mode 100644 index 0000000..7073092 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/bdist_rpm.py @@ -0,0 +1,43 @@ +import distutils.command.bdist_rpm as orig + + +class bdist_rpm(orig.bdist_rpm): + """ + Override the default bdist_rpm behavior to do the following: + + 1. Run egg_info to ensure the name and version are properly calculated. + 2. Always run 'install' using --single-version-externally-managed to + disable eggs in RPM distributions. + 3. Replace dash with underscore in the version numbers for better RPM + compatibility. + """ + + def run(self): + # ensure distro name is up-to-date + self.run_command('egg_info') + + orig.bdist_rpm.run(self) + + def _make_spec_file(self): + version = self.distribution.get_version() + rpmversion = version.replace('-', '_') + spec = orig.bdist_rpm._make_spec_file(self) + line23 = '%define version ' + version + line24 = '%define version ' + rpmversion + spec = [ + line.replace( + "Source0: %{name}-%{version}.tar", + "Source0: %{name}-%{unmangled_version}.tar" + ).replace( + "setup.py install ", + "setup.py install --single-version-externally-managed " + ).replace( + "%setup", + "%setup -n %{name}-%{unmangled_version}" + ).replace(line23, line24) + for line in spec + ] + insert_loc = spec.index(line24) + 1 + unmangled_version = "%define unmangled_version " + version + spec.insert(insert_loc, unmangled_version) + return spec diff --git a/env/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py b/env/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py new file mode 100644 index 0000000..073de97 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/bdist_wininst.py @@ -0,0 +1,21 @@ +import distutils.command.bdist_wininst as orig + + +class bdist_wininst(orig.bdist_wininst): + def reinitialize_command(self, command, reinit_subcommands=0): + """ + Supplement reinitialize_command to work around + http://bugs.python.org/issue20819 + """ + cmd = self.distribution.reinitialize_command( + command, reinit_subcommands) + if command in ('install', 'install_lib'): + cmd.install_lib = None + return cmd + + def run(self): + self._is_running = True + try: + orig.bdist_wininst.run(self) + finally: + self._is_running = False diff --git a/env/lib/python3.7/site-packages/setuptools/command/build_clib.py b/env/lib/python3.7/site-packages/setuptools/command/build_clib.py new file mode 100644 index 0000000..09caff6 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/build_clib.py @@ -0,0 +1,98 @@ +import distutils.command.build_clib as orig +from distutils.errors import DistutilsSetupError +from distutils import log +from setuptools.dep_util import newer_pairwise_group + + +class build_clib(orig.build_clib): + """ + Override the default build_clib behaviour to do the following: + + 1. Implement a rudimentary timestamp-based dependency system + so 'compile()' doesn't run every time. + 2. Add more keys to the 'build_info' dictionary: + * obj_deps - specify dependencies for each object compiled. + this should be a dictionary mapping a key + with the source filename to a list of + dependencies. Use an empty string for global + dependencies. + * cflags - specify a list of additional flags to pass to + the compiler. + """ + + def build_libraries(self, libraries): + for (lib_name, build_info) in libraries: + sources = build_info.get('sources') + if sources is None or not isinstance(sources, (list, tuple)): + raise DistutilsSetupError( + "in 'libraries' option (library '%s'), " + "'sources' must be present and must be " + "a list of source filenames" % lib_name) + sources = list(sources) + + log.info("building '%s' library", lib_name) + + # Make sure everything is the correct type. + # obj_deps should be a dictionary of keys as sources + # and a list/tuple of files that are its dependencies. + obj_deps = build_info.get('obj_deps', dict()) + if not isinstance(obj_deps, dict): + raise DistutilsSetupError( + "in 'libraries' option (library '%s'), " + "'obj_deps' must be a dictionary of " + "type 'source: list'" % lib_name) + dependencies = [] + + # Get the global dependencies that are specified by the '' key. + # These will go into every source's dependency list. + global_deps = obj_deps.get('', list()) + if not isinstance(global_deps, (list, tuple)): + raise DistutilsSetupError( + "in 'libraries' option (library '%s'), " + "'obj_deps' must be a dictionary of " + "type 'source: list'" % lib_name) + + # Build the list to be used by newer_pairwise_group + # each source will be auto-added to its dependencies. + for source in sources: + src_deps = [source] + src_deps.extend(global_deps) + extra_deps = obj_deps.get(source, list()) + if not isinstance(extra_deps, (list, tuple)): + raise DistutilsSetupError( + "in 'libraries' option (library '%s'), " + "'obj_deps' must be a dictionary of " + "type 'source: list'" % lib_name) + src_deps.extend(extra_deps) + dependencies.append(src_deps) + + expected_objects = self.compiler.object_filenames( + sources, + output_dir=self.build_temp + ) + + if newer_pairwise_group(dependencies, expected_objects) != ([], []): + # First, compile the source code to object files in the library + # directory. (This should probably change to putting object + # files in a temporary build directory.) + macros = build_info.get('macros') + include_dirs = build_info.get('include_dirs') + cflags = build_info.get('cflags') + objects = self.compiler.compile( + sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=include_dirs, + extra_postargs=cflags, + debug=self.debug + ) + + # Now "link" the object files together into a static library. + # (On Unix at least, this isn't really linking -- it just + # builds an archive. Whatever.) + self.compiler.create_static_lib( + expected_objects, + lib_name, + output_dir=self.build_clib, + debug=self.debug + ) diff --git a/env/lib/python3.7/site-packages/setuptools/command/build_ext.py b/env/lib/python3.7/site-packages/setuptools/command/build_ext.py new file mode 100644 index 0000000..60a8a32 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/build_ext.py @@ -0,0 +1,321 @@ +import os +import sys +import itertools +import imp +from distutils.command.build_ext import build_ext as _du_build_ext +from distutils.file_util import copy_file +from distutils.ccompiler import new_compiler +from distutils.sysconfig import customize_compiler, get_config_var +from distutils.errors import DistutilsError +from distutils import log + +from setuptools.extension import Library +from setuptools.extern import six + +try: + # Attempt to use Cython for building extensions, if available + from Cython.Distutils.build_ext import build_ext as _build_ext + # Additionally, assert that the compiler module will load + # also. Ref #1229. + __import__('Cython.Compiler.Main') +except ImportError: + _build_ext = _du_build_ext + +# make sure _config_vars is initialized +get_config_var("LDSHARED") +from distutils.sysconfig import _config_vars as _CONFIG_VARS + + +def _customize_compiler_for_shlib(compiler): + if sys.platform == "darwin": + # building .dylib requires additional compiler flags on OSX; here we + # temporarily substitute the pyconfig.h variables so that distutils' + # 'customize_compiler' uses them before we build the shared libraries. + tmp = _CONFIG_VARS.copy() + try: + # XXX Help! I don't have any idea whether these are right... + _CONFIG_VARS['LDSHARED'] = ( + "gcc -Wl,-x -dynamiclib -undefined dynamic_lookup") + _CONFIG_VARS['CCSHARED'] = " -dynamiclib" + _CONFIG_VARS['SO'] = ".dylib" + customize_compiler(compiler) + finally: + _CONFIG_VARS.clear() + _CONFIG_VARS.update(tmp) + else: + customize_compiler(compiler) + + +have_rtld = False +use_stubs = False +libtype = 'shared' + +if sys.platform == "darwin": + use_stubs = True +elif os.name != 'nt': + try: + import dl + use_stubs = have_rtld = hasattr(dl, 'RTLD_NOW') + except ImportError: + pass + +if_dl = lambda s: s if have_rtld else '' + + +def get_abi3_suffix(): + """Return the file extension for an abi3-compliant Extension()""" + for suffix, _, _ in (s for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION): + if '.abi3' in suffix: # Unix + return suffix + elif suffix == '.pyd': # Windows + return suffix + + +class build_ext(_build_ext): + def run(self): + """Build extensions in build directory, then copy if --inplace""" + old_inplace, self.inplace = self.inplace, 0 + _build_ext.run(self) + self.inplace = old_inplace + if old_inplace: + self.copy_extensions_to_source() + + def copy_extensions_to_source(self): + build_py = self.get_finalized_command('build_py') + for ext in self.extensions: + fullname = self.get_ext_fullname(ext.name) + filename = self.get_ext_filename(fullname) + modpath = fullname.split('.') + package = '.'.join(modpath[:-1]) + package_dir = build_py.get_package_dir(package) + dest_filename = os.path.join(package_dir, + os.path.basename(filename)) + src_filename = os.path.join(self.build_lib, filename) + + # Always copy, even if source is older than destination, to ensure + # that the right extensions for the current Python/platform are + # used. + copy_file( + src_filename, dest_filename, verbose=self.verbose, + dry_run=self.dry_run + ) + if ext._needs_stub: + self.write_stub(package_dir or os.curdir, ext, True) + + def get_ext_filename(self, fullname): + filename = _build_ext.get_ext_filename(self, fullname) + if fullname in self.ext_map: + ext = self.ext_map[fullname] + use_abi3 = ( + six.PY3 + and getattr(ext, 'py_limited_api') + and get_abi3_suffix() + ) + if use_abi3: + so_ext = get_config_var('EXT_SUFFIX') + filename = filename[:-len(so_ext)] + filename = filename + get_abi3_suffix() + if isinstance(ext, Library): + fn, ext = os.path.splitext(filename) + return self.shlib_compiler.library_filename(fn, libtype) + elif use_stubs and ext._links_to_dynamic: + d, fn = os.path.split(filename) + return os.path.join(d, 'dl-' + fn) + return filename + + def initialize_options(self): + _build_ext.initialize_options(self) + self.shlib_compiler = None + self.shlibs = [] + self.ext_map = {} + + def finalize_options(self): + _build_ext.finalize_options(self) + self.extensions = self.extensions or [] + self.check_extensions_list(self.extensions) + self.shlibs = [ext for ext in self.extensions + if isinstance(ext, Library)] + if self.shlibs: + self.setup_shlib_compiler() + for ext in self.extensions: + ext._full_name = self.get_ext_fullname(ext.name) + for ext in self.extensions: + fullname = ext._full_name + self.ext_map[fullname] = ext + + # distutils 3.1 will also ask for module names + # XXX what to do with conflicts? + self.ext_map[fullname.split('.')[-1]] = ext + + ltd = self.shlibs and self.links_to_dynamic(ext) or False + ns = ltd and use_stubs and not isinstance(ext, Library) + ext._links_to_dynamic = ltd + ext._needs_stub = ns + filename = ext._file_name = self.get_ext_filename(fullname) + libdir = os.path.dirname(os.path.join(self.build_lib, filename)) + if ltd and libdir not in ext.library_dirs: + ext.library_dirs.append(libdir) + if ltd and use_stubs and os.curdir not in ext.runtime_library_dirs: + ext.runtime_library_dirs.append(os.curdir) + + def setup_shlib_compiler(self): + compiler = self.shlib_compiler = new_compiler( + compiler=self.compiler, dry_run=self.dry_run, force=self.force + ) + _customize_compiler_for_shlib(compiler) + + if self.include_dirs is not None: + compiler.set_include_dirs(self.include_dirs) + if self.define is not None: + # 'define' option is a list of (name,value) tuples + for (name, value) in self.define: + compiler.define_macro(name, value) + if self.undef is not None: + for macro in self.undef: + compiler.undefine_macro(macro) + if self.libraries is not None: + compiler.set_libraries(self.libraries) + if self.library_dirs is not None: + compiler.set_library_dirs(self.library_dirs) + if self.rpath is not None: + compiler.set_runtime_library_dirs(self.rpath) + if self.link_objects is not None: + compiler.set_link_objects(self.link_objects) + + # hack so distutils' build_extension() builds a library instead + compiler.link_shared_object = link_shared_object.__get__(compiler) + + def get_export_symbols(self, ext): + if isinstance(ext, Library): + return ext.export_symbols + return _build_ext.get_export_symbols(self, ext) + + def build_extension(self, ext): + ext._convert_pyx_sources_to_lang() + _compiler = self.compiler + try: + if isinstance(ext, Library): + self.compiler = self.shlib_compiler + _build_ext.build_extension(self, ext) + if ext._needs_stub: + cmd = self.get_finalized_command('build_py').build_lib + self.write_stub(cmd, ext) + finally: + self.compiler = _compiler + + def links_to_dynamic(self, ext): + """Return true if 'ext' links to a dynamic lib in the same package""" + # XXX this should check to ensure the lib is actually being built + # XXX as dynamic, and not just using a locally-found version or a + # XXX static-compiled version + libnames = dict.fromkeys([lib._full_name for lib in self.shlibs]) + pkg = '.'.join(ext._full_name.split('.')[:-1] + ['']) + return any(pkg + libname in libnames for libname in ext.libraries) + + def get_outputs(self): + return _build_ext.get_outputs(self) + self.__get_stubs_outputs() + + def __get_stubs_outputs(self): + # assemble the base name for each extension that needs a stub + ns_ext_bases = ( + os.path.join(self.build_lib, *ext._full_name.split('.')) + for ext in self.extensions + if ext._needs_stub + ) + # pair each base with the extension + pairs = itertools.product(ns_ext_bases, self.__get_output_extensions()) + return list(base + fnext for base, fnext in pairs) + + def __get_output_extensions(self): + yield '.py' + yield '.pyc' + if self.get_finalized_command('build_py').optimize: + yield '.pyo' + + def write_stub(self, output_dir, ext, compile=False): + log.info("writing stub loader for %s to %s", ext._full_name, + output_dir) + stub_file = (os.path.join(output_dir, *ext._full_name.split('.')) + + '.py') + if compile and os.path.exists(stub_file): + raise DistutilsError(stub_file + " already exists! Please delete.") + if not self.dry_run: + f = open(stub_file, 'w') + f.write( + '\n'.join([ + "def __bootstrap__():", + " global __bootstrap__, __file__, __loader__", + " import sys, os, pkg_resources, imp" + if_dl(", dl"), + " __file__ = pkg_resources.resource_filename" + "(__name__,%r)" + % os.path.basename(ext._file_name), + " del __bootstrap__", + " if '__loader__' in globals():", + " del __loader__", + if_dl(" old_flags = sys.getdlopenflags()"), + " old_dir = os.getcwd()", + " try:", + " os.chdir(os.path.dirname(__file__))", + if_dl(" sys.setdlopenflags(dl.RTLD_NOW)"), + " imp.load_dynamic(__name__,__file__)", + " finally:", + if_dl(" sys.setdlopenflags(old_flags)"), + " os.chdir(old_dir)", + "__bootstrap__()", + "" # terminal \n + ]) + ) + f.close() + if compile: + from distutils.util import byte_compile + + byte_compile([stub_file], optimize=0, + force=True, dry_run=self.dry_run) + optimize = self.get_finalized_command('install_lib').optimize + if optimize > 0: + byte_compile([stub_file], optimize=optimize, + force=True, dry_run=self.dry_run) + if os.path.exists(stub_file) and not self.dry_run: + os.unlink(stub_file) + + +if use_stubs or os.name == 'nt': + # Build shared libraries + # + def link_shared_object( + self, objects, output_libname, output_dir=None, libraries=None, + library_dirs=None, runtime_library_dirs=None, export_symbols=None, + debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, + target_lang=None): + self.link( + self.SHARED_LIBRARY, objects, output_libname, + output_dir, libraries, library_dirs, runtime_library_dirs, + export_symbols, debug, extra_preargs, extra_postargs, + build_temp, target_lang + ) +else: + # Build static libraries everywhere else + libtype = 'static' + + def link_shared_object( + self, objects, output_libname, output_dir=None, libraries=None, + library_dirs=None, runtime_library_dirs=None, export_symbols=None, + debug=0, extra_preargs=None, extra_postargs=None, build_temp=None, + target_lang=None): + # XXX we need to either disallow these attrs on Library instances, + # or warn/abort here if set, or something... + # libraries=None, library_dirs=None, runtime_library_dirs=None, + # export_symbols=None, extra_preargs=None, extra_postargs=None, + # build_temp=None + + assert output_dir is None # distutils build_ext doesn't pass this + output_dir, filename = os.path.split(output_libname) + basename, ext = os.path.splitext(filename) + if self.library_filename("x").startswith('lib'): + # strip 'lib' prefix; this is kludgy if some platform uses + # a different prefix + basename = basename[3:] + + self.create_static_lib( + objects, basename, output_dir, debug, target_lang + ) diff --git a/env/lib/python3.7/site-packages/setuptools/command/build_py.py b/env/lib/python3.7/site-packages/setuptools/command/build_py.py new file mode 100644 index 0000000..b0314fd --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/build_py.py @@ -0,0 +1,270 @@ +from glob import glob +from distutils.util import convert_path +import distutils.command.build_py as orig +import os +import fnmatch +import textwrap +import io +import distutils.errors +import itertools + +from setuptools.extern import six +from setuptools.extern.six.moves import map, filter, filterfalse + +try: + from setuptools.lib2to3_ex import Mixin2to3 +except ImportError: + + class Mixin2to3: + def run_2to3(self, files, doctests=True): + "do nothing" + + +class build_py(orig.build_py, Mixin2to3): + """Enhanced 'build_py' command that includes data files with packages + + The data files are specified via a 'package_data' argument to 'setup()'. + See 'setuptools.dist.Distribution' for more details. + + Also, this version of the 'build_py' command allows you to specify both + 'py_modules' and 'packages' in the same setup operation. + """ + + def finalize_options(self): + orig.build_py.finalize_options(self) + self.package_data = self.distribution.package_data + self.exclude_package_data = (self.distribution.exclude_package_data or + {}) + if 'data_files' in self.__dict__: + del self.__dict__['data_files'] + self.__updated_files = [] + self.__doctests_2to3 = [] + + def run(self): + """Build modules, packages, and copy data files to build directory""" + if not self.py_modules and not self.packages: + return + + if self.py_modules: + self.build_modules() + + if self.packages: + self.build_packages() + self.build_package_data() + + self.run_2to3(self.__updated_files, False) + self.run_2to3(self.__updated_files, True) + self.run_2to3(self.__doctests_2to3, True) + + # Only compile actual .py files, using our base class' idea of what our + # output files are. + self.byte_compile(orig.build_py.get_outputs(self, include_bytecode=0)) + + def __getattr__(self, attr): + "lazily compute data files" + if attr == 'data_files': + self.data_files = self._get_data_files() + return self.data_files + return orig.build_py.__getattr__(self, attr) + + def build_module(self, module, module_file, package): + if six.PY2 and isinstance(package, six.string_types): + # avoid errors on Python 2 when unicode is passed (#190) + package = package.split('.') + outfile, copied = orig.build_py.build_module(self, module, module_file, + package) + if copied: + self.__updated_files.append(outfile) + return outfile, copied + + def _get_data_files(self): + """Generate list of '(package,src_dir,build_dir,filenames)' tuples""" + self.analyze_manifest() + return list(map(self._get_pkg_data_files, self.packages or ())) + + def _get_pkg_data_files(self, package): + # Locate package source directory + src_dir = self.get_package_dir(package) + + # Compute package build directory + build_dir = os.path.join(*([self.build_lib] + package.split('.'))) + + # Strip directory from globbed filenames + filenames = [ + os.path.relpath(file, src_dir) + for file in self.find_data_files(package, src_dir) + ] + return package, src_dir, build_dir, filenames + + def find_data_files(self, package, src_dir): + """Return filenames for package's data files in 'src_dir'""" + patterns = self._get_platform_patterns( + self.package_data, + package, + src_dir, + ) + globs_expanded = map(glob, patterns) + # flatten the expanded globs into an iterable of matches + globs_matches = itertools.chain.from_iterable(globs_expanded) + glob_files = filter(os.path.isfile, globs_matches) + files = itertools.chain( + self.manifest_files.get(package, []), + glob_files, + ) + return self.exclude_data_files(package, src_dir, files) + + def build_package_data(self): + """Copy data files into build directory""" + for package, src_dir, build_dir, filenames in self.data_files: + for filename in filenames: + target = os.path.join(build_dir, filename) + self.mkpath(os.path.dirname(target)) + srcfile = os.path.join(src_dir, filename) + outf, copied = self.copy_file(srcfile, target) + srcfile = os.path.abspath(srcfile) + if (copied and + srcfile in self.distribution.convert_2to3_doctests): + self.__doctests_2to3.append(outf) + + def analyze_manifest(self): + self.manifest_files = mf = {} + if not self.distribution.include_package_data: + return + src_dirs = {} + for package in self.packages or (): + # Locate package source directory + src_dirs[assert_relative(self.get_package_dir(package))] = package + + self.run_command('egg_info') + ei_cmd = self.get_finalized_command('egg_info') + for path in ei_cmd.filelist.files: + d, f = os.path.split(assert_relative(path)) + prev = None + oldf = f + while d and d != prev and d not in src_dirs: + prev = d + d, df = os.path.split(d) + f = os.path.join(df, f) + if d in src_dirs: + if path.endswith('.py') and f == oldf: + continue # it's a module, not data + mf.setdefault(src_dirs[d], []).append(path) + + def get_data_files(self): + pass # Lazily compute data files in _get_data_files() function. + + def check_package(self, package, package_dir): + """Check namespace packages' __init__ for declare_namespace""" + try: + return self.packages_checked[package] + except KeyError: + pass + + init_py = orig.build_py.check_package(self, package, package_dir) + self.packages_checked[package] = init_py + + if not init_py or not self.distribution.namespace_packages: + return init_py + + for pkg in self.distribution.namespace_packages: + if pkg == package or pkg.startswith(package + '.'): + break + else: + return init_py + + with io.open(init_py, 'rb') as f: + contents = f.read() + if b'declare_namespace' not in contents: + raise distutils.errors.DistutilsError( + "Namespace package problem: %s is a namespace package, but " + "its\n__init__.py does not call declare_namespace()! Please " + 'fix it.\n(See the setuptools manual under ' + '"Namespace Packages" for details.)\n"' % (package,) + ) + return init_py + + def initialize_options(self): + self.packages_checked = {} + orig.build_py.initialize_options(self) + + def get_package_dir(self, package): + res = orig.build_py.get_package_dir(self, package) + if self.distribution.src_root is not None: + return os.path.join(self.distribution.src_root, res) + return res + + def exclude_data_files(self, package, src_dir, files): + """Filter filenames for package's data files in 'src_dir'""" + files = list(files) + patterns = self._get_platform_patterns( + self.exclude_package_data, + package, + src_dir, + ) + match_groups = ( + fnmatch.filter(files, pattern) + for pattern in patterns + ) + # flatten the groups of matches into an iterable of matches + matches = itertools.chain.from_iterable(match_groups) + bad = set(matches) + keepers = ( + fn + for fn in files + if fn not in bad + ) + # ditch dupes + return list(_unique_everseen(keepers)) + + @staticmethod + def _get_platform_patterns(spec, package, src_dir): + """ + yield platform-specific path patterns (suitable for glob + or fn_match) from a glob-based spec (such as + self.package_data or self.exclude_package_data) + matching package in src_dir. + """ + raw_patterns = itertools.chain( + spec.get('', []), + spec.get(package, []), + ) + return ( + # Each pattern has to be converted to a platform-specific path + os.path.join(src_dir, convert_path(pattern)) + for pattern in raw_patterns + ) + + +# from Python docs +def _unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + +def assert_relative(path): + if not os.path.isabs(path): + return path + from distutils.errors import DistutilsSetupError + + msg = textwrap.dedent(""" + Error: setup script specifies an absolute path: + + %s + + setup() arguments must *always* be /-separated paths relative to the + setup.py directory, *never* absolute paths. + """).lstrip() % path + raise DistutilsSetupError(msg) diff --git a/env/lib/python3.7/site-packages/setuptools/command/develop.py b/env/lib/python3.7/site-packages/setuptools/command/develop.py new file mode 100644 index 0000000..fdc9fc4 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/develop.py @@ -0,0 +1,218 @@ +from distutils.util import convert_path +from distutils import log +from distutils.errors import DistutilsError, DistutilsOptionError +import os +import glob +import io + +from setuptools.extern import six + +from pkg_resources import Distribution, PathMetadata, normalize_path +from setuptools.command.easy_install import easy_install +from setuptools import namespaces +import setuptools + +__metaclass__ = type + + +class develop(namespaces.DevelopInstaller, easy_install): + """Set up package for development""" + + description = "install package in 'development mode'" + + user_options = easy_install.user_options + [ + ("uninstall", "u", "Uninstall this source package"), + ("egg-path=", None, "Set the path to be used in the .egg-link file"), + ] + + boolean_options = easy_install.boolean_options + ['uninstall'] + + command_consumes_arguments = False # override base + + def run(self): + if self.uninstall: + self.multi_version = True + self.uninstall_link() + self.uninstall_namespaces() + else: + self.install_for_development() + self.warn_deprecated_options() + + def initialize_options(self): + self.uninstall = None + self.egg_path = None + easy_install.initialize_options(self) + self.setup_path = None + self.always_copy_from = '.' # always copy eggs installed in curdir + + def finalize_options(self): + ei = self.get_finalized_command("egg_info") + if ei.broken_egg_info: + template = "Please rename %r to %r before using 'develop'" + args = ei.egg_info, ei.broken_egg_info + raise DistutilsError(template % args) + self.args = [ei.egg_name] + + easy_install.finalize_options(self) + self.expand_basedirs() + self.expand_dirs() + # pick up setup-dir .egg files only: no .egg-info + self.package_index.scan(glob.glob('*.egg')) + + egg_link_fn = ei.egg_name + '.egg-link' + self.egg_link = os.path.join(self.install_dir, egg_link_fn) + self.egg_base = ei.egg_base + if self.egg_path is None: + self.egg_path = os.path.abspath(ei.egg_base) + + target = normalize_path(self.egg_base) + egg_path = normalize_path(os.path.join(self.install_dir, + self.egg_path)) + if egg_path != target: + raise DistutilsOptionError( + "--egg-path must be a relative path from the install" + " directory to " + target + ) + + # Make a distribution for the package's source + self.dist = Distribution( + target, + PathMetadata(target, os.path.abspath(ei.egg_info)), + project_name=ei.egg_name + ) + + self.setup_path = self._resolve_setup_path( + self.egg_base, + self.install_dir, + self.egg_path, + ) + + @staticmethod + def _resolve_setup_path(egg_base, install_dir, egg_path): + """ + Generate a path from egg_base back to '.' where the + setup script resides and ensure that path points to the + setup path from $install_dir/$egg_path. + """ + path_to_setup = egg_base.replace(os.sep, '/').rstrip('/') + if path_to_setup != os.curdir: + path_to_setup = '../' * (path_to_setup.count('/') + 1) + resolved = normalize_path( + os.path.join(install_dir, egg_path, path_to_setup) + ) + if resolved != normalize_path(os.curdir): + raise DistutilsOptionError( + "Can't get a consistent path to setup script from" + " installation directory", resolved, normalize_path(os.curdir)) + return path_to_setup + + def install_for_development(self): + if six.PY3 and getattr(self.distribution, 'use_2to3', False): + # If we run 2to3 we can not do this inplace: + + # Ensure metadata is up-to-date + self.reinitialize_command('build_py', inplace=0) + self.run_command('build_py') + bpy_cmd = self.get_finalized_command("build_py") + build_path = normalize_path(bpy_cmd.build_lib) + + # Build extensions + self.reinitialize_command('egg_info', egg_base=build_path) + self.run_command('egg_info') + + self.reinitialize_command('build_ext', inplace=0) + self.run_command('build_ext') + + # Fixup egg-link and easy-install.pth + ei_cmd = self.get_finalized_command("egg_info") + self.egg_path = build_path + self.dist.location = build_path + # XXX + self.dist._provider = PathMetadata(build_path, ei_cmd.egg_info) + else: + # Without 2to3 inplace works fine: + self.run_command('egg_info') + + # Build extensions in-place + self.reinitialize_command('build_ext', inplace=1) + self.run_command('build_ext') + + self.install_site_py() # ensure that target dir is site-safe + if setuptools.bootstrap_install_from: + self.easy_install(setuptools.bootstrap_install_from) + setuptools.bootstrap_install_from = None + + self.install_namespaces() + + # create an .egg-link in the installation dir, pointing to our egg + log.info("Creating %s (link to %s)", self.egg_link, self.egg_base) + if not self.dry_run: + with open(self.egg_link, "w") as f: + f.write(self.egg_path + "\n" + self.setup_path) + # postprocess the installed distro, fixing up .pth, installing scripts, + # and handling requirements + self.process_distribution(None, self.dist, not self.no_deps) + + def uninstall_link(self): + if os.path.exists(self.egg_link): + log.info("Removing %s (link to %s)", self.egg_link, self.egg_base) + egg_link_file = open(self.egg_link) + contents = [line.rstrip() for line in egg_link_file] + egg_link_file.close() + if contents not in ([self.egg_path], + [self.egg_path, self.setup_path]): + log.warn("Link points to %s: uninstall aborted", contents) + return + if not self.dry_run: + os.unlink(self.egg_link) + if not self.dry_run: + self.update_pth(self.dist) # remove any .pth link to us + if self.distribution.scripts: + # XXX should also check for entry point scripts! + log.warn("Note: you must uninstall or replace scripts manually!") + + def install_egg_scripts(self, dist): + if dist is not self.dist: + # Installing a dependency, so fall back to normal behavior + return easy_install.install_egg_scripts(self, dist) + + # create wrapper scripts in the script dir, pointing to dist.scripts + + # new-style... + self.install_wrapper_scripts(dist) + + # ...and old-style + for script_name in self.distribution.scripts or []: + script_path = os.path.abspath(convert_path(script_name)) + script_name = os.path.basename(script_path) + with io.open(script_path) as strm: + script_text = strm.read() + self.install_script(dist, script_name, script_text, script_path) + + def install_wrapper_scripts(self, dist): + dist = VersionlessRequirement(dist) + return easy_install.install_wrapper_scripts(self, dist) + + +class VersionlessRequirement: + """ + Adapt a pkg_resources.Distribution to simply return the project + name as the 'requirement' so that scripts will work across + multiple versions. + + >>> dist = Distribution(project_name='foo', version='1.0') + >>> str(dist.as_requirement()) + 'foo==1.0' + >>> adapted_dist = VersionlessRequirement(dist) + >>> str(adapted_dist.as_requirement()) + 'foo' + """ + + def __init__(self, dist): + self.__dist = dist + + def __getattr__(self, name): + return getattr(self.__dist, name) + + def as_requirement(self): + return self.project_name diff --git a/env/lib/python3.7/site-packages/setuptools/command/dist_info.py b/env/lib/python3.7/site-packages/setuptools/command/dist_info.py new file mode 100644 index 0000000..c45258f --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/dist_info.py @@ -0,0 +1,36 @@ +""" +Create a dist_info directory +As defined in the wheel specification +""" + +import os + +from distutils.core import Command +from distutils import log + + +class dist_info(Command): + + description = 'create a .dist-info directory' + + user_options = [ + ('egg-base=', 'e', "directory containing .egg-info directories" + " (default: top of the source tree)"), + ] + + def initialize_options(self): + self.egg_base = None + + def finalize_options(self): + pass + + def run(self): + egg_info = self.get_finalized_command('egg_info') + egg_info.egg_base = self.egg_base + egg_info.finalize_options() + egg_info.run() + dist_info_dir = egg_info.egg_info[:-len('.egg-info')] + '.dist-info' + log.info("creating '{}'".format(os.path.abspath(dist_info_dir))) + + bdist_wheel = self.get_finalized_command('bdist_wheel') + bdist_wheel.egg2dist(egg_info.egg_info, dist_info_dir) diff --git a/env/lib/python3.7/site-packages/setuptools/command/easy_install.py b/env/lib/python3.7/site-packages/setuptools/command/easy_install.py new file mode 100644 index 0000000..06c9827 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/easy_install.py @@ -0,0 +1,2342 @@ +#!/usr/bin/env python +""" +Easy Install +------------ + +A tool for doing automatic download/extract/build of distutils-based Python +packages. For detailed documentation, see the accompanying EasyInstall.txt +file, or visit the `EasyInstall home page`__. + +__ https://setuptools.readthedocs.io/en/latest/easy_install.html + +""" + +from glob import glob +from distutils.util import get_platform +from distutils.util import convert_path, subst_vars +from distutils.errors import ( + DistutilsArgError, DistutilsOptionError, + DistutilsError, DistutilsPlatformError, +) +from distutils.command.install import INSTALL_SCHEMES, SCHEME_KEYS +from distutils import log, dir_util +from distutils.command.build_scripts import first_line_re +from distutils.spawn import find_executable +import sys +import os +import zipimport +import shutil +import tempfile +import zipfile +import re +import stat +import random +import textwrap +import warnings +import site +import struct +import contextlib +import subprocess +import shlex +import io + + +from sysconfig import get_config_vars, get_path + +from setuptools import SetuptoolsDeprecationWarning + +from setuptools.extern import six +from setuptools.extern.six.moves import configparser, map + +from setuptools import Command +from setuptools.sandbox import run_setup +from setuptools.py27compat import rmtree_safe +from setuptools.command import setopt +from setuptools.archive_util import unpack_archive +from setuptools.package_index import ( + PackageIndex, parse_requirement_arg, URL_SCHEME, +) +from setuptools.command import bdist_egg, egg_info +from setuptools.wheel import Wheel +from pkg_resources import ( + yield_lines, normalize_path, resource_string, ensure_directory, + get_distribution, find_distributions, Environment, Requirement, + Distribution, PathMetadata, EggMetadata, WorkingSet, DistributionNotFound, + VersionConflict, DEVELOP_DIST, +) +import pkg_resources.py31compat + +__metaclass__ = type + +# Turn on PEP440Warnings +warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) + +__all__ = [ + 'samefile', 'easy_install', 'PthDistributions', 'extract_wininst_cfg', + 'main', 'get_exe_prefixes', +] + + +def is_64bit(): + return struct.calcsize("P") == 8 + + +def samefile(p1, p2): + """ + Determine if two paths reference the same file. + + Augments os.path.samefile to work on Windows and + suppresses errors if the path doesn't exist. + """ + both_exist = os.path.exists(p1) and os.path.exists(p2) + use_samefile = hasattr(os.path, 'samefile') and both_exist + if use_samefile: + return os.path.samefile(p1, p2) + norm_p1 = os.path.normpath(os.path.normcase(p1)) + norm_p2 = os.path.normpath(os.path.normcase(p2)) + return norm_p1 == norm_p2 + + +if six.PY2: + + def _to_bytes(s): + return s + + def isascii(s): + try: + six.text_type(s, 'ascii') + return True + except UnicodeError: + return False +else: + + def _to_bytes(s): + return s.encode('utf8') + + def isascii(s): + try: + s.encode('ascii') + return True + except UnicodeError: + return False + + +_one_liner = lambda text: textwrap.dedent(text).strip().replace('\n', '; ') + + +class easy_install(Command): + """Manage a download/build/install process""" + description = "Find/get/install Python packages" + command_consumes_arguments = True + + user_options = [ + ('prefix=', None, "installation prefix"), + ("zip-ok", "z", "install package as a zipfile"), + ("multi-version", "m", "make apps have to require() a version"), + ("upgrade", "U", "force upgrade (searches PyPI for latest versions)"), + ("install-dir=", "d", "install package to DIR"), + ("script-dir=", "s", "install scripts to DIR"), + ("exclude-scripts", "x", "Don't install scripts"), + ("always-copy", "a", "Copy all needed packages to install dir"), + ("index-url=", "i", "base URL of Python Package Index"), + ("find-links=", "f", "additional URL(s) to search for packages"), + ("build-directory=", "b", + "download/extract/build in DIR; keep the results"), + ('optimize=', 'O', + "also compile with optimization: -O1 for \"python -O\", " + "-O2 for \"python -OO\", and -O0 to disable [default: -O0]"), + ('record=', None, + "filename in which to record list of installed files"), + ('always-unzip', 'Z', "don't install as a zipfile, no matter what"), + ('site-dirs=', 'S', "list of directories where .pth files work"), + ('editable', 'e', "Install specified packages in editable form"), + ('no-deps', 'N', "don't install dependencies"), + ('allow-hosts=', 'H', "pattern(s) that hostnames must match"), + ('local-snapshots-ok', 'l', + "allow building eggs from local checkouts"), + ('version', None, "print version information and exit"), + ('no-find-links', None, + "Don't load find-links defined in packages being installed") + ] + boolean_options = [ + 'zip-ok', 'multi-version', 'exclude-scripts', 'upgrade', 'always-copy', + 'editable', + 'no-deps', 'local-snapshots-ok', 'version' + ] + + if site.ENABLE_USER_SITE: + help_msg = "install in user site-package '%s'" % site.USER_SITE + user_options.append(('user', None, help_msg)) + boolean_options.append('user') + + negative_opt = {'always-unzip': 'zip-ok'} + create_index = PackageIndex + + def initialize_options(self): + # the --user option seems to be an opt-in one, + # so the default should be False. + self.user = 0 + self.zip_ok = self.local_snapshots_ok = None + self.install_dir = self.script_dir = self.exclude_scripts = None + self.index_url = None + self.find_links = None + self.build_directory = None + self.args = None + self.optimize = self.record = None + self.upgrade = self.always_copy = self.multi_version = None + self.editable = self.no_deps = self.allow_hosts = None + self.root = self.prefix = self.no_report = None + self.version = None + self.install_purelib = None # for pure module distributions + self.install_platlib = None # non-pure (dists w/ extensions) + self.install_headers = None # for C/C++ headers + self.install_lib = None # set to either purelib or platlib + self.install_scripts = None + self.install_data = None + self.install_base = None + self.install_platbase = None + if site.ENABLE_USER_SITE: + self.install_userbase = site.USER_BASE + self.install_usersite = site.USER_SITE + else: + self.install_userbase = None + self.install_usersite = None + self.no_find_links = None + + # Options not specifiable via command line + self.package_index = None + self.pth_file = self.always_copy_from = None + self.site_dirs = None + self.installed_projects = {} + self.sitepy_installed = False + # Always read easy_install options, even if we are subclassed, or have + # an independent instance created. This ensures that defaults will + # always come from the standard configuration file(s)' "easy_install" + # section, even if this is a "develop" or "install" command, or some + # other embedding. + self._dry_run = None + self.verbose = self.distribution.verbose + self.distribution._set_command_options( + self, self.distribution.get_option_dict('easy_install') + ) + + def delete_blockers(self, blockers): + extant_blockers = ( + filename for filename in blockers + if os.path.exists(filename) or os.path.islink(filename) + ) + list(map(self._delete_path, extant_blockers)) + + def _delete_path(self, path): + log.info("Deleting %s", path) + if self.dry_run: + return + + is_tree = os.path.isdir(path) and not os.path.islink(path) + remover = rmtree if is_tree else os.unlink + remover(path) + + @staticmethod + def _render_version(): + """ + Render the Setuptools version and installation details, then exit. + """ + ver = sys.version[:3] + dist = get_distribution('setuptools') + tmpl = 'setuptools {dist.version} from {dist.location} (Python {ver})' + print(tmpl.format(**locals())) + raise SystemExit() + + def finalize_options(self): + self.version and self._render_version() + + py_version = sys.version.split()[0] + prefix, exec_prefix = get_config_vars('prefix', 'exec_prefix') + + self.config_vars = { + 'dist_name': self.distribution.get_name(), + 'dist_version': self.distribution.get_version(), + 'dist_fullname': self.distribution.get_fullname(), + 'py_version': py_version, + 'py_version_short': py_version[0:3], + 'py_version_nodot': py_version[0] + py_version[2], + 'sys_prefix': prefix, + 'prefix': prefix, + 'sys_exec_prefix': exec_prefix, + 'exec_prefix': exec_prefix, + # Only python 3.2+ has abiflags + 'abiflags': getattr(sys, 'abiflags', ''), + } + + if site.ENABLE_USER_SITE: + self.config_vars['userbase'] = self.install_userbase + self.config_vars['usersite'] = self.install_usersite + + self._fix_install_dir_for_user_site() + + self.expand_basedirs() + self.expand_dirs() + + self._expand( + 'install_dir', 'script_dir', 'build_directory', + 'site_dirs', + ) + # If a non-default installation directory was specified, default the + # script directory to match it. + if self.script_dir is None: + self.script_dir = self.install_dir + + if self.no_find_links is None: + self.no_find_links = False + + # Let install_dir get set by install_lib command, which in turn + # gets its info from the install command, and takes into account + # --prefix and --home and all that other crud. + self.set_undefined_options( + 'install_lib', ('install_dir', 'install_dir') + ) + # Likewise, set default script_dir from 'install_scripts.install_dir' + self.set_undefined_options( + 'install_scripts', ('install_dir', 'script_dir') + ) + + if self.user and self.install_purelib: + self.install_dir = self.install_purelib + self.script_dir = self.install_scripts + # default --record from the install command + self.set_undefined_options('install', ('record', 'record')) + # Should this be moved to the if statement below? It's not used + # elsewhere + normpath = map(normalize_path, sys.path) + self.all_site_dirs = get_site_dirs() + if self.site_dirs is not None: + site_dirs = [ + os.path.expanduser(s.strip()) for s in + self.site_dirs.split(',') + ] + for d in site_dirs: + if not os.path.isdir(d): + log.warn("%s (in --site-dirs) does not exist", d) + elif normalize_path(d) not in normpath: + raise DistutilsOptionError( + d + " (in --site-dirs) is not on sys.path" + ) + else: + self.all_site_dirs.append(normalize_path(d)) + if not self.editable: + self.check_site_dir() + self.index_url = self.index_url or "https://pypi.org/simple/" + self.shadow_path = self.all_site_dirs[:] + for path_item in self.install_dir, normalize_path(self.script_dir): + if path_item not in self.shadow_path: + self.shadow_path.insert(0, path_item) + + if self.allow_hosts is not None: + hosts = [s.strip() for s in self.allow_hosts.split(',')] + else: + hosts = ['*'] + if self.package_index is None: + self.package_index = self.create_index( + self.index_url, search_path=self.shadow_path, hosts=hosts, + ) + self.local_index = Environment(self.shadow_path + sys.path) + + if self.find_links is not None: + if isinstance(self.find_links, six.string_types): + self.find_links = self.find_links.split() + else: + self.find_links = [] + if self.local_snapshots_ok: + self.package_index.scan_egg_links(self.shadow_path + sys.path) + if not self.no_find_links: + self.package_index.add_find_links(self.find_links) + self.set_undefined_options('install_lib', ('optimize', 'optimize')) + if not isinstance(self.optimize, int): + try: + self.optimize = int(self.optimize) + if not (0 <= self.optimize <= 2): + raise ValueError + except ValueError: + raise DistutilsOptionError("--optimize must be 0, 1, or 2") + + if self.editable and not self.build_directory: + raise DistutilsArgError( + "Must specify a build directory (-b) when using --editable" + ) + if not self.args: + raise DistutilsArgError( + "No urls, filenames, or requirements specified (see --help)") + + self.outputs = [] + + def _fix_install_dir_for_user_site(self): + """ + Fix the install_dir if "--user" was used. + """ + if not self.user or not site.ENABLE_USER_SITE: + return + + self.create_home_path() + if self.install_userbase is None: + msg = "User base directory is not specified" + raise DistutilsPlatformError(msg) + self.install_base = self.install_platbase = self.install_userbase + scheme_name = os.name.replace('posix', 'unix') + '_user' + self.select_scheme(scheme_name) + + def _expand_attrs(self, attrs): + for attr in attrs: + val = getattr(self, attr) + if val is not None: + if os.name == 'posix' or os.name == 'nt': + val = os.path.expanduser(val) + val = subst_vars(val, self.config_vars) + setattr(self, attr, val) + + def expand_basedirs(self): + """Calls `os.path.expanduser` on install_base, install_platbase and + root.""" + self._expand_attrs(['install_base', 'install_platbase', 'root']) + + def expand_dirs(self): + """Calls `os.path.expanduser` on install dirs.""" + dirs = [ + 'install_purelib', + 'install_platlib', + 'install_lib', + 'install_headers', + 'install_scripts', + 'install_data', + ] + self._expand_attrs(dirs) + + def run(self): + if self.verbose != self.distribution.verbose: + log.set_verbosity(self.verbose) + try: + for spec in self.args: + self.easy_install(spec, not self.no_deps) + if self.record: + outputs = self.outputs + if self.root: # strip any package prefix + root_len = len(self.root) + for counter in range(len(outputs)): + outputs[counter] = outputs[counter][root_len:] + from distutils import file_util + + self.execute( + file_util.write_file, (self.record, outputs), + "writing list of installed files to '%s'" % + self.record + ) + self.warn_deprecated_options() + finally: + log.set_verbosity(self.distribution.verbose) + + def pseudo_tempname(self): + """Return a pseudo-tempname base in the install directory. + This code is intentionally naive; if a malicious party can write to + the target directory you're already in deep doodoo. + """ + try: + pid = os.getpid() + except Exception: + pid = random.randint(0, sys.maxsize) + return os.path.join(self.install_dir, "test-easy-install-%s" % pid) + + def warn_deprecated_options(self): + pass + + def check_site_dir(self): + """Verify that self.install_dir is .pth-capable dir, if needed""" + + instdir = normalize_path(self.install_dir) + pth_file = os.path.join(instdir, 'easy-install.pth') + + # Is it a configured, PYTHONPATH, implicit, or explicit site dir? + is_site_dir = instdir in self.all_site_dirs + + if not is_site_dir and not self.multi_version: + # No? Then directly test whether it does .pth file processing + is_site_dir = self.check_pth_processing() + else: + # make sure we can write to target dir + testfile = self.pseudo_tempname() + '.write-test' + test_exists = os.path.exists(testfile) + try: + if test_exists: + os.unlink(testfile) + open(testfile, 'w').close() + os.unlink(testfile) + except (OSError, IOError): + self.cant_write_to_target() + + if not is_site_dir and not self.multi_version: + # Can't install non-multi to non-site dir + raise DistutilsError(self.no_default_version_msg()) + + if is_site_dir: + if self.pth_file is None: + self.pth_file = PthDistributions(pth_file, self.all_site_dirs) + else: + self.pth_file = None + + if instdir not in map(normalize_path, _pythonpath()): + # only PYTHONPATH dirs need a site.py, so pretend it's there + self.sitepy_installed = True + elif self.multi_version and not os.path.exists(pth_file): + self.sitepy_installed = True # don't need site.py in this case + self.pth_file = None # and don't create a .pth file + self.install_dir = instdir + + __cant_write_msg = textwrap.dedent(""" + can't create or remove files in install directory + + The following error occurred while trying to add or remove files in the + installation directory: + + %s + + The installation directory you specified (via --install-dir, --prefix, or + the distutils default setting) was: + + %s + """).lstrip() + + __not_exists_id = textwrap.dedent(""" + This directory does not currently exist. Please create it and try again, or + choose a different installation directory (using the -d or --install-dir + option). + """).lstrip() + + __access_msg = textwrap.dedent(""" + Perhaps your account does not have write access to this directory? If the + installation directory is a system-owned directory, you may need to sign in + as the administrator or "root" account. If you do not have administrative + access to this machine, you may wish to choose a different installation + directory, preferably one that is listed in your PYTHONPATH environment + variable. + + For information on other options, you may wish to consult the + documentation at: + + https://setuptools.readthedocs.io/en/latest/easy_install.html + + Please make the appropriate changes for your system and try again. + """).lstrip() + + def cant_write_to_target(self): + msg = self.__cant_write_msg % (sys.exc_info()[1], self.install_dir,) + + if not os.path.exists(self.install_dir): + msg += '\n' + self.__not_exists_id + else: + msg += '\n' + self.__access_msg + raise DistutilsError(msg) + + def check_pth_processing(self): + """Empirically verify whether .pth files are supported in inst. dir""" + instdir = self.install_dir + log.info("Checking .pth file support in %s", instdir) + pth_file = self.pseudo_tempname() + ".pth" + ok_file = pth_file + '.ok' + ok_exists = os.path.exists(ok_file) + tmpl = _one_liner(""" + import os + f = open({ok_file!r}, 'w') + f.write('OK') + f.close() + """) + '\n' + try: + if ok_exists: + os.unlink(ok_file) + dirname = os.path.dirname(ok_file) + pkg_resources.py31compat.makedirs(dirname, exist_ok=True) + f = open(pth_file, 'w') + except (OSError, IOError): + self.cant_write_to_target() + else: + try: + f.write(tmpl.format(**locals())) + f.close() + f = None + executable = sys.executable + if os.name == 'nt': + dirname, basename = os.path.split(executable) + alt = os.path.join(dirname, 'pythonw.exe') + use_alt = ( + basename.lower() == 'python.exe' and + os.path.exists(alt) + ) + if use_alt: + # use pythonw.exe to avoid opening a console window + executable = alt + + from distutils.spawn import spawn + + spawn([executable, '-E', '-c', 'pass'], 0) + + if os.path.exists(ok_file): + log.info( + "TEST PASSED: %s appears to support .pth files", + instdir + ) + return True + finally: + if f: + f.close() + if os.path.exists(ok_file): + os.unlink(ok_file) + if os.path.exists(pth_file): + os.unlink(pth_file) + if not self.multi_version: + log.warn("TEST FAILED: %s does NOT support .pth files", instdir) + return False + + def install_egg_scripts(self, dist): + """Write all the scripts for `dist`, unless scripts are excluded""" + if not self.exclude_scripts and dist.metadata_isdir('scripts'): + for script_name in dist.metadata_listdir('scripts'): + if dist.metadata_isdir('scripts/' + script_name): + # The "script" is a directory, likely a Python 3 + # __pycache__ directory, so skip it. + continue + self.install_script( + dist, script_name, + dist.get_metadata('scripts/' + script_name) + ) + self.install_wrapper_scripts(dist) + + def add_output(self, path): + if os.path.isdir(path): + for base, dirs, files in os.walk(path): + for filename in files: + self.outputs.append(os.path.join(base, filename)) + else: + self.outputs.append(path) + + def not_editable(self, spec): + if self.editable: + raise DistutilsArgError( + "Invalid argument %r: you can't use filenames or URLs " + "with --editable (except via the --find-links option)." + % (spec,) + ) + + def check_editable(self, spec): + if not self.editable: + return + + if os.path.exists(os.path.join(self.build_directory, spec.key)): + raise DistutilsArgError( + "%r already exists in %s; can't do a checkout there" % + (spec.key, self.build_directory) + ) + + @contextlib.contextmanager + def _tmpdir(self): + tmpdir = tempfile.mkdtemp(prefix=u"easy_install-") + try: + # cast to str as workaround for #709 and #710 and #712 + yield str(tmpdir) + finally: + os.path.exists(tmpdir) and rmtree(rmtree_safe(tmpdir)) + + def easy_install(self, spec, deps=False): + if not self.editable: + self.install_site_py() + + with self._tmpdir() as tmpdir: + if not isinstance(spec, Requirement): + if URL_SCHEME(spec): + # It's a url, download it to tmpdir and process + self.not_editable(spec) + dl = self.package_index.download(spec, tmpdir) + return self.install_item(None, dl, tmpdir, deps, True) + + elif os.path.exists(spec): + # Existing file or directory, just process it directly + self.not_editable(spec) + return self.install_item(None, spec, tmpdir, deps, True) + else: + spec = parse_requirement_arg(spec) + + self.check_editable(spec) + dist = self.package_index.fetch_distribution( + spec, tmpdir, self.upgrade, self.editable, + not self.always_copy, self.local_index + ) + if dist is None: + msg = "Could not find suitable distribution for %r" % spec + if self.always_copy: + msg += " (--always-copy skips system and development eggs)" + raise DistutilsError(msg) + elif dist.precedence == DEVELOP_DIST: + # .egg-info dists don't need installing, just process deps + self.process_distribution(spec, dist, deps, "Using") + return dist + else: + return self.install_item(spec, dist.location, tmpdir, deps) + + def install_item(self, spec, download, tmpdir, deps, install_needed=False): + + # Installation is also needed if file in tmpdir or is not an egg + install_needed = install_needed or self.always_copy + install_needed = install_needed or os.path.dirname(download) == tmpdir + install_needed = install_needed or not download.endswith('.egg') + install_needed = install_needed or ( + self.always_copy_from is not None and + os.path.dirname(normalize_path(download)) == + normalize_path(self.always_copy_from) + ) + + if spec and not install_needed: + # at this point, we know it's a local .egg, we just don't know if + # it's already installed. + for dist in self.local_index[spec.project_name]: + if dist.location == download: + break + else: + install_needed = True # it's not in the local index + + log.info("Processing %s", os.path.basename(download)) + + if install_needed: + dists = self.install_eggs(spec, download, tmpdir) + for dist in dists: + self.process_distribution(spec, dist, deps) + else: + dists = [self.egg_distribution(download)] + self.process_distribution(spec, dists[0], deps, "Using") + + if spec is not None: + for dist in dists: + if dist in spec: + return dist + + def select_scheme(self, name): + """Sets the install directories by applying the install schemes.""" + # it's the caller's problem if they supply a bad name! + scheme = INSTALL_SCHEMES[name] + for key in SCHEME_KEYS: + attrname = 'install_' + key + if getattr(self, attrname) is None: + setattr(self, attrname, scheme[key]) + + def process_distribution(self, requirement, dist, deps=True, *info): + self.update_pth(dist) + self.package_index.add(dist) + if dist in self.local_index[dist.key]: + self.local_index.remove(dist) + self.local_index.add(dist) + self.install_egg_scripts(dist) + self.installed_projects[dist.key] = dist + log.info(self.installation_report(requirement, dist, *info)) + if (dist.has_metadata('dependency_links.txt') and + not self.no_find_links): + self.package_index.add_find_links( + dist.get_metadata_lines('dependency_links.txt') + ) + if not deps and not self.always_copy: + return + elif requirement is not None and dist.key != requirement.key: + log.warn("Skipping dependencies for %s", dist) + return # XXX this is not the distribution we were looking for + elif requirement is None or dist not in requirement: + # if we wound up with a different version, resolve what we've got + distreq = dist.as_requirement() + requirement = Requirement(str(distreq)) + log.info("Processing dependencies for %s", requirement) + try: + distros = WorkingSet([]).resolve( + [requirement], self.local_index, self.easy_install + ) + except DistributionNotFound as e: + raise DistutilsError(str(e)) + except VersionConflict as e: + raise DistutilsError(e.report()) + if self.always_copy or self.always_copy_from: + # Force all the relevant distros to be copied or activated + for dist in distros: + if dist.key not in self.installed_projects: + self.easy_install(dist.as_requirement()) + log.info("Finished processing dependencies for %s", requirement) + + def should_unzip(self, dist): + if self.zip_ok is not None: + return not self.zip_ok + if dist.has_metadata('not-zip-safe'): + return True + if not dist.has_metadata('zip-safe'): + return True + return False + + def maybe_move(self, spec, dist_filename, setup_base): + dst = os.path.join(self.build_directory, spec.key) + if os.path.exists(dst): + msg = ( + "%r already exists in %s; build directory %s will not be kept" + ) + log.warn(msg, spec.key, self.build_directory, setup_base) + return setup_base + if os.path.isdir(dist_filename): + setup_base = dist_filename + else: + if os.path.dirname(dist_filename) == setup_base: + os.unlink(dist_filename) # get it out of the tmp dir + contents = os.listdir(setup_base) + if len(contents) == 1: + dist_filename = os.path.join(setup_base, contents[0]) + if os.path.isdir(dist_filename): + # if the only thing there is a directory, move it instead + setup_base = dist_filename + ensure_directory(dst) + shutil.move(setup_base, dst) + return dst + + def install_wrapper_scripts(self, dist): + if self.exclude_scripts: + return + for args in ScriptWriter.best().get_args(dist): + self.write_script(*args) + + def install_script(self, dist, script_name, script_text, dev_path=None): + """Generate a legacy script wrapper and install it""" + spec = str(dist.as_requirement()) + is_script = is_python_script(script_text, script_name) + + if is_script: + body = self._load_template(dev_path) % locals() + script_text = ScriptWriter.get_header(script_text) + body + self.write_script(script_name, _to_bytes(script_text), 'b') + + @staticmethod + def _load_template(dev_path): + """ + There are a couple of template scripts in the package. This + function loads one of them and prepares it for use. + """ + # See https://github.com/pypa/setuptools/issues/134 for info + # on script file naming and downstream issues with SVR4 + name = 'script.tmpl' + if dev_path: + name = name.replace('.tmpl', ' (dev).tmpl') + + raw_bytes = resource_string('setuptools', name) + return raw_bytes.decode('utf-8') + + def write_script(self, script_name, contents, mode="t", blockers=()): + """Write an executable file to the scripts directory""" + self.delete_blockers( # clean up old .py/.pyw w/o a script + [os.path.join(self.script_dir, x) for x in blockers] + ) + log.info("Installing %s script to %s", script_name, self.script_dir) + target = os.path.join(self.script_dir, script_name) + self.add_output(target) + + if self.dry_run: + return + + mask = current_umask() + ensure_directory(target) + if os.path.exists(target): + os.unlink(target) + with open(target, "w" + mode) as f: + f.write(contents) + chmod(target, 0o777 - mask) + + def install_eggs(self, spec, dist_filename, tmpdir): + # .egg dirs or files are already built, so just return them + if dist_filename.lower().endswith('.egg'): + return [self.install_egg(dist_filename, tmpdir)] + elif dist_filename.lower().endswith('.exe'): + return [self.install_exe(dist_filename, tmpdir)] + elif dist_filename.lower().endswith('.whl'): + return [self.install_wheel(dist_filename, tmpdir)] + + # Anything else, try to extract and build + setup_base = tmpdir + if os.path.isfile(dist_filename) and not dist_filename.endswith('.py'): + unpack_archive(dist_filename, tmpdir, self.unpack_progress) + elif os.path.isdir(dist_filename): + setup_base = os.path.abspath(dist_filename) + + if (setup_base.startswith(tmpdir) # something we downloaded + and self.build_directory and spec is not None): + setup_base = self.maybe_move(spec, dist_filename, setup_base) + + # Find the setup.py file + setup_script = os.path.join(setup_base, 'setup.py') + + if not os.path.exists(setup_script): + setups = glob(os.path.join(setup_base, '*', 'setup.py')) + if not setups: + raise DistutilsError( + "Couldn't find a setup script in %s" % + os.path.abspath(dist_filename) + ) + if len(setups) > 1: + raise DistutilsError( + "Multiple setup scripts in %s" % + os.path.abspath(dist_filename) + ) + setup_script = setups[0] + + # Now run it, and return the result + if self.editable: + log.info(self.report_editable(spec, setup_script)) + return [] + else: + return self.build_and_install(setup_script, setup_base) + + def egg_distribution(self, egg_path): + if os.path.isdir(egg_path): + metadata = PathMetadata(egg_path, os.path.join(egg_path, + 'EGG-INFO')) + else: + metadata = EggMetadata(zipimport.zipimporter(egg_path)) + return Distribution.from_filename(egg_path, metadata=metadata) + + def install_egg(self, egg_path, tmpdir): + destination = os.path.join( + self.install_dir, + os.path.basename(egg_path), + ) + destination = os.path.abspath(destination) + if not self.dry_run: + ensure_directory(destination) + + dist = self.egg_distribution(egg_path) + if not samefile(egg_path, destination): + if os.path.isdir(destination) and not os.path.islink(destination): + dir_util.remove_tree(destination, dry_run=self.dry_run) + elif os.path.exists(destination): + self.execute( + os.unlink, + (destination,), + "Removing " + destination, + ) + try: + new_dist_is_zipped = False + if os.path.isdir(egg_path): + if egg_path.startswith(tmpdir): + f, m = shutil.move, "Moving" + else: + f, m = shutil.copytree, "Copying" + elif self.should_unzip(dist): + self.mkpath(destination) + f, m = self.unpack_and_compile, "Extracting" + else: + new_dist_is_zipped = True + if egg_path.startswith(tmpdir): + f, m = shutil.move, "Moving" + else: + f, m = shutil.copy2, "Copying" + self.execute( + f, + (egg_path, destination), + (m + " %s to %s") % ( + os.path.basename(egg_path), + os.path.dirname(destination) + ), + ) + update_dist_caches( + destination, + fix_zipimporter_caches=new_dist_is_zipped, + ) + except Exception: + update_dist_caches(destination, fix_zipimporter_caches=False) + raise + + self.add_output(destination) + return self.egg_distribution(destination) + + def install_exe(self, dist_filename, tmpdir): + # See if it's valid, get data + cfg = extract_wininst_cfg(dist_filename) + if cfg is None: + raise DistutilsError( + "%s is not a valid distutils Windows .exe" % dist_filename + ) + # Create a dummy distribution object until we build the real distro + dist = Distribution( + None, + project_name=cfg.get('metadata', 'name'), + version=cfg.get('metadata', 'version'), platform=get_platform(), + ) + + # Convert the .exe to an unpacked egg + egg_path = os.path.join(tmpdir, dist.egg_name() + '.egg') + dist.location = egg_path + egg_tmp = egg_path + '.tmp' + _egg_info = os.path.join(egg_tmp, 'EGG-INFO') + pkg_inf = os.path.join(_egg_info, 'PKG-INFO') + ensure_directory(pkg_inf) # make sure EGG-INFO dir exists + dist._provider = PathMetadata(egg_tmp, _egg_info) # XXX + self.exe_to_egg(dist_filename, egg_tmp) + + # Write EGG-INFO/PKG-INFO + if not os.path.exists(pkg_inf): + f = open(pkg_inf, 'w') + f.write('Metadata-Version: 1.0\n') + for k, v in cfg.items('metadata'): + if k != 'target_version': + f.write('%s: %s\n' % (k.replace('_', '-').title(), v)) + f.close() + script_dir = os.path.join(_egg_info, 'scripts') + # delete entry-point scripts to avoid duping + self.delete_blockers([ + os.path.join(script_dir, args[0]) + for args in ScriptWriter.get_args(dist) + ]) + # Build .egg file from tmpdir + bdist_egg.make_zipfile( + egg_path, egg_tmp, verbose=self.verbose, dry_run=self.dry_run, + ) + # install the .egg + return self.install_egg(egg_path, tmpdir) + + def exe_to_egg(self, dist_filename, egg_tmp): + """Extract a bdist_wininst to the directories an egg would use""" + # Check for .pth file and set up prefix translations + prefixes = get_exe_prefixes(dist_filename) + to_compile = [] + native_libs = [] + top_level = {} + + def process(src, dst): + s = src.lower() + for old, new in prefixes: + if s.startswith(old): + src = new + src[len(old):] + parts = src.split('/') + dst = os.path.join(egg_tmp, *parts) + dl = dst.lower() + if dl.endswith('.pyd') or dl.endswith('.dll'): + parts[-1] = bdist_egg.strip_module(parts[-1]) + top_level[os.path.splitext(parts[0])[0]] = 1 + native_libs.append(src) + elif dl.endswith('.py') and old != 'SCRIPTS/': + top_level[os.path.splitext(parts[0])[0]] = 1 + to_compile.append(dst) + return dst + if not src.endswith('.pth'): + log.warn("WARNING: can't process %s", src) + return None + + # extract, tracking .pyd/.dll->native_libs and .py -> to_compile + unpack_archive(dist_filename, egg_tmp, process) + stubs = [] + for res in native_libs: + if res.lower().endswith('.pyd'): # create stubs for .pyd's + parts = res.split('/') + resource = parts[-1] + parts[-1] = bdist_egg.strip_module(parts[-1]) + '.py' + pyfile = os.path.join(egg_tmp, *parts) + to_compile.append(pyfile) + stubs.append(pyfile) + bdist_egg.write_stub(resource, pyfile) + self.byte_compile(to_compile) # compile .py's + bdist_egg.write_safety_flag( + os.path.join(egg_tmp, 'EGG-INFO'), + bdist_egg.analyze_egg(egg_tmp, stubs)) # write zip-safety flag + + for name in 'top_level', 'native_libs': + if locals()[name]: + txt = os.path.join(egg_tmp, 'EGG-INFO', name + '.txt') + if not os.path.exists(txt): + f = open(txt, 'w') + f.write('\n'.join(locals()[name]) + '\n') + f.close() + + def install_wheel(self, wheel_path, tmpdir): + wheel = Wheel(wheel_path) + assert wheel.is_compatible() + destination = os.path.join(self.install_dir, wheel.egg_name()) + destination = os.path.abspath(destination) + if not self.dry_run: + ensure_directory(destination) + if os.path.isdir(destination) and not os.path.islink(destination): + dir_util.remove_tree(destination, dry_run=self.dry_run) + elif os.path.exists(destination): + self.execute( + os.unlink, + (destination,), + "Removing " + destination, + ) + try: + self.execute( + wheel.install_as_egg, + (destination,), + ("Installing %s to %s") % ( + os.path.basename(wheel_path), + os.path.dirname(destination) + ), + ) + finally: + update_dist_caches(destination, fix_zipimporter_caches=False) + self.add_output(destination) + return self.egg_distribution(destination) + + __mv_warning = textwrap.dedent(""" + Because this distribution was installed --multi-version, before you can + import modules from this package in an application, you will need to + 'import pkg_resources' and then use a 'require()' call similar to one of + these examples, in order to select the desired version: + + pkg_resources.require("%(name)s") # latest installed version + pkg_resources.require("%(name)s==%(version)s") # this exact version + pkg_resources.require("%(name)s>=%(version)s") # this version or higher + """).lstrip() + + __id_warning = textwrap.dedent(""" + Note also that the installation directory must be on sys.path at runtime for + this to work. (e.g. by being the application's script directory, by being on + PYTHONPATH, or by being added to sys.path by your code.) + """) + + def installation_report(self, req, dist, what="Installed"): + """Helpful installation message for display to package users""" + msg = "\n%(what)s %(eggloc)s%(extras)s" + if self.multi_version and not self.no_report: + msg += '\n' + self.__mv_warning + if self.install_dir not in map(normalize_path, sys.path): + msg += '\n' + self.__id_warning + + eggloc = dist.location + name = dist.project_name + version = dist.version + extras = '' # TODO: self.report_extras(req, dist) + return msg % locals() + + __editable_msg = textwrap.dedent(""" + Extracted editable version of %(spec)s to %(dirname)s + + If it uses setuptools in its setup script, you can activate it in + "development" mode by going to that directory and running:: + + %(python)s setup.py develop + + See the setuptools documentation for the "develop" command for more info. + """).lstrip() + + def report_editable(self, spec, setup_script): + dirname = os.path.dirname(setup_script) + python = sys.executable + return '\n' + self.__editable_msg % locals() + + def run_setup(self, setup_script, setup_base, args): + sys.modules.setdefault('distutils.command.bdist_egg', bdist_egg) + sys.modules.setdefault('distutils.command.egg_info', egg_info) + + args = list(args) + if self.verbose > 2: + v = 'v' * (self.verbose - 1) + args.insert(0, '-' + v) + elif self.verbose < 2: + args.insert(0, '-q') + if self.dry_run: + args.insert(0, '-n') + log.info( + "Running %s %s", setup_script[len(setup_base) + 1:], ' '.join(args) + ) + try: + run_setup(setup_script, args) + except SystemExit as v: + raise DistutilsError("Setup script exited with %s" % (v.args[0],)) + + def build_and_install(self, setup_script, setup_base): + args = ['bdist_egg', '--dist-dir'] + + dist_dir = tempfile.mkdtemp( + prefix='egg-dist-tmp-', dir=os.path.dirname(setup_script) + ) + try: + self._set_fetcher_options(os.path.dirname(setup_script)) + args.append(dist_dir) + + self.run_setup(setup_script, setup_base, args) + all_eggs = Environment([dist_dir]) + eggs = [] + for key in all_eggs: + for dist in all_eggs[key]: + eggs.append(self.install_egg(dist.location, setup_base)) + if not eggs and not self.dry_run: + log.warn("No eggs found in %s (setup script problem?)", + dist_dir) + return eggs + finally: + rmtree(dist_dir) + log.set_verbosity(self.verbose) # restore our log verbosity + + def _set_fetcher_options(self, base): + """ + When easy_install is about to run bdist_egg on a source dist, that + source dist might have 'setup_requires' directives, requiring + additional fetching. Ensure the fetcher options given to easy_install + are available to that command as well. + """ + # find the fetch options from easy_install and write them out + # to the setup.cfg file. + ei_opts = self.distribution.get_option_dict('easy_install').copy() + fetch_directives = ( + 'find_links', 'site_dirs', 'index_url', 'optimize', + 'site_dirs', 'allow_hosts', + ) + fetch_options = {} + for key, val in ei_opts.items(): + if key not in fetch_directives: + continue + fetch_options[key.replace('_', '-')] = val[1] + # create a settings dictionary suitable for `edit_config` + settings = dict(easy_install=fetch_options) + cfg_filename = os.path.join(base, 'setup.cfg') + setopt.edit_config(cfg_filename, settings) + + def update_pth(self, dist): + if self.pth_file is None: + return + + for d in self.pth_file[dist.key]: # drop old entries + if self.multi_version or d.location != dist.location: + log.info("Removing %s from easy-install.pth file", d) + self.pth_file.remove(d) + if d.location in self.shadow_path: + self.shadow_path.remove(d.location) + + if not self.multi_version: + if dist.location in self.pth_file.paths: + log.info( + "%s is already the active version in easy-install.pth", + dist, + ) + else: + log.info("Adding %s to easy-install.pth file", dist) + self.pth_file.add(dist) # add new entry + if dist.location not in self.shadow_path: + self.shadow_path.append(dist.location) + + if not self.dry_run: + + self.pth_file.save() + + if dist.key == 'setuptools': + # Ensure that setuptools itself never becomes unavailable! + # XXX should this check for latest version? + filename = os.path.join(self.install_dir, 'setuptools.pth') + if os.path.islink(filename): + os.unlink(filename) + f = open(filename, 'wt') + f.write(self.pth_file.make_relative(dist.location) + '\n') + f.close() + + def unpack_progress(self, src, dst): + # Progress filter for unpacking + log.debug("Unpacking %s to %s", src, dst) + return dst # only unpack-and-compile skips files for dry run + + def unpack_and_compile(self, egg_path, destination): + to_compile = [] + to_chmod = [] + + def pf(src, dst): + if dst.endswith('.py') and not src.startswith('EGG-INFO/'): + to_compile.append(dst) + elif dst.endswith('.dll') or dst.endswith('.so'): + to_chmod.append(dst) + self.unpack_progress(src, dst) + return not self.dry_run and dst or None + + unpack_archive(egg_path, destination, pf) + self.byte_compile(to_compile) + if not self.dry_run: + for f in to_chmod: + mode = ((os.stat(f)[stat.ST_MODE]) | 0o555) & 0o7755 + chmod(f, mode) + + def byte_compile(self, to_compile): + if sys.dont_write_bytecode: + return + + from distutils.util import byte_compile + + try: + # try to make the byte compile messages quieter + log.set_verbosity(self.verbose - 1) + + byte_compile(to_compile, optimize=0, force=1, dry_run=self.dry_run) + if self.optimize: + byte_compile( + to_compile, optimize=self.optimize, force=1, + dry_run=self.dry_run, + ) + finally: + log.set_verbosity(self.verbose) # restore original verbosity + + __no_default_msg = textwrap.dedent(""" + bad install directory or PYTHONPATH + + You are attempting to install a package to a directory that is not + on PYTHONPATH and which Python does not read ".pth" files from. The + installation directory you specified (via --install-dir, --prefix, or + the distutils default setting) was: + + %s + + and your PYTHONPATH environment variable currently contains: + + %r + + Here are some of your options for correcting the problem: + + * You can choose a different installation directory, i.e., one that is + on PYTHONPATH or supports .pth files + + * You can add the installation directory to the PYTHONPATH environment + variable. (It must then also be on PYTHONPATH whenever you run + Python and want to use the package(s) you are installing.) + + * You can set up the installation directory to support ".pth" files by + using one of the approaches described here: + + https://setuptools.readthedocs.io/en/latest/easy_install.html#custom-installation-locations + + + Please make the appropriate changes for your system and try again.""").lstrip() + + def no_default_version_msg(self): + template = self.__no_default_msg + return template % (self.install_dir, os.environ.get('PYTHONPATH', '')) + + def install_site_py(self): + """Make sure there's a site.py in the target dir, if needed""" + + if self.sitepy_installed: + return # already did it, or don't need to + + sitepy = os.path.join(self.install_dir, "site.py") + source = resource_string("setuptools", "site-patch.py") + source = source.decode('utf-8') + current = "" + + if os.path.exists(sitepy): + log.debug("Checking existing site.py in %s", self.install_dir) + with io.open(sitepy) as strm: + current = strm.read() + + if not current.startswith('def __boot():'): + raise DistutilsError( + "%s is not a setuptools-generated site.py; please" + " remove it." % sitepy + ) + + if current != source: + log.info("Creating %s", sitepy) + if not self.dry_run: + ensure_directory(sitepy) + with io.open(sitepy, 'w', encoding='utf-8') as strm: + strm.write(source) + self.byte_compile([sitepy]) + + self.sitepy_installed = True + + def create_home_path(self): + """Create directories under ~.""" + if not self.user: + return + home = convert_path(os.path.expanduser("~")) + for name, path in six.iteritems(self.config_vars): + if path.startswith(home) and not os.path.isdir(path): + self.debug_print("os.makedirs('%s', 0o700)" % path) + os.makedirs(path, 0o700) + + INSTALL_SCHEMES = dict( + posix=dict( + install_dir='$base/lib/python$py_version_short/site-packages', + script_dir='$base/bin', + ), + ) + + DEFAULT_SCHEME = dict( + install_dir='$base/Lib/site-packages', + script_dir='$base/Scripts', + ) + + def _expand(self, *attrs): + config_vars = self.get_finalized_command('install').config_vars + + if self.prefix: + # Set default install_dir/scripts from --prefix + config_vars = config_vars.copy() + config_vars['base'] = self.prefix + scheme = self.INSTALL_SCHEMES.get(os.name, self.DEFAULT_SCHEME) + for attr, val in scheme.items(): + if getattr(self, attr, None) is None: + setattr(self, attr, val) + + from distutils.util import subst_vars + + for attr in attrs: + val = getattr(self, attr) + if val is not None: + val = subst_vars(val, config_vars) + if os.name == 'posix': + val = os.path.expanduser(val) + setattr(self, attr, val) + + +def _pythonpath(): + items = os.environ.get('PYTHONPATH', '').split(os.pathsep) + return filter(None, items) + + +def get_site_dirs(): + """ + Return a list of 'site' dirs + """ + + sitedirs = [] + + # start with PYTHONPATH + sitedirs.extend(_pythonpath()) + + prefixes = [sys.prefix] + if sys.exec_prefix != sys.prefix: + prefixes.append(sys.exec_prefix) + for prefix in prefixes: + if prefix: + if sys.platform in ('os2emx', 'riscos'): + sitedirs.append(os.path.join(prefix, "Lib", "site-packages")) + elif os.sep == '/': + sitedirs.extend([ + os.path.join( + prefix, + "lib", + "python" + sys.version[:3], + "site-packages", + ), + os.path.join(prefix, "lib", "site-python"), + ]) + else: + sitedirs.extend([ + prefix, + os.path.join(prefix, "lib", "site-packages"), + ]) + if sys.platform == 'darwin': + # for framework builds *only* we add the standard Apple + # locations. Currently only per-user, but /Library and + # /Network/Library could be added too + if 'Python.framework' in prefix: + home = os.environ.get('HOME') + if home: + home_sp = os.path.join( + home, + 'Library', + 'Python', + sys.version[:3], + 'site-packages', + ) + sitedirs.append(home_sp) + lib_paths = get_path('purelib'), get_path('platlib') + for site_lib in lib_paths: + if site_lib not in sitedirs: + sitedirs.append(site_lib) + + if site.ENABLE_USER_SITE: + sitedirs.append(site.USER_SITE) + + try: + sitedirs.extend(site.getsitepackages()) + except AttributeError: + pass + + sitedirs = list(map(normalize_path, sitedirs)) + + return sitedirs + + +def expand_paths(inputs): + """Yield sys.path directories that might contain "old-style" packages""" + + seen = {} + + for dirname in inputs: + dirname = normalize_path(dirname) + if dirname in seen: + continue + + seen[dirname] = 1 + if not os.path.isdir(dirname): + continue + + files = os.listdir(dirname) + yield dirname, files + + for name in files: + if not name.endswith('.pth'): + # We only care about the .pth files + continue + if name in ('easy-install.pth', 'setuptools.pth'): + # Ignore .pth files that we control + continue + + # Read the .pth file + f = open(os.path.join(dirname, name)) + lines = list(yield_lines(f)) + f.close() + + # Yield existing non-dupe, non-import directory lines from it + for line in lines: + if not line.startswith("import"): + line = normalize_path(line.rstrip()) + if line not in seen: + seen[line] = 1 + if not os.path.isdir(line): + continue + yield line, os.listdir(line) + + +def extract_wininst_cfg(dist_filename): + """Extract configuration data from a bdist_wininst .exe + + Returns a configparser.RawConfigParser, or None + """ + f = open(dist_filename, 'rb') + try: + endrec = zipfile._EndRecData(f) + if endrec is None: + return None + + prepended = (endrec[9] - endrec[5]) - endrec[6] + if prepended < 12: # no wininst data here + return None + f.seek(prepended - 12) + + tag, cfglen, bmlen = struct.unpack("<iii", f.read(12)) + if tag not in (0x1234567A, 0x1234567B): + return None # not a valid tag + + f.seek(prepended - (12 + cfglen)) + init = {'version': '', 'target_version': ''} + cfg = configparser.RawConfigParser(init) + try: + part = f.read(cfglen) + # Read up to the first null byte. + config = part.split(b'\0', 1)[0] + # Now the config is in bytes, but for RawConfigParser, it should + # be text, so decode it. + config = config.decode(sys.getfilesystemencoding()) + cfg.readfp(six.StringIO(config)) + except configparser.Error: + return None + if not cfg.has_section('metadata') or not cfg.has_section('Setup'): + return None + return cfg + + finally: + f.close() + + +def get_exe_prefixes(exe_filename): + """Get exe->egg path translations for a given .exe file""" + + prefixes = [ + ('PURELIB/', ''), + ('PLATLIB/pywin32_system32', ''), + ('PLATLIB/', ''), + ('SCRIPTS/', 'EGG-INFO/scripts/'), + ('DATA/lib/site-packages', ''), + ] + z = zipfile.ZipFile(exe_filename) + try: + for info in z.infolist(): + name = info.filename + parts = name.split('/') + if len(parts) == 3 and parts[2] == 'PKG-INFO': + if parts[1].endswith('.egg-info'): + prefixes.insert(0, ('/'.join(parts[:2]), 'EGG-INFO/')) + break + if len(parts) != 2 or not name.endswith('.pth'): + continue + if name.endswith('-nspkg.pth'): + continue + if parts[0].upper() in ('PURELIB', 'PLATLIB'): + contents = z.read(name) + if six.PY3: + contents = contents.decode() + for pth in yield_lines(contents): + pth = pth.strip().replace('\\', '/') + if not pth.startswith('import'): + prefixes.append((('%s/%s/' % (parts[0], pth)), '')) + finally: + z.close() + prefixes = [(x.lower(), y) for x, y in prefixes] + prefixes.sort() + prefixes.reverse() + return prefixes + + +class PthDistributions(Environment): + """A .pth file with Distribution paths in it""" + + dirty = False + + def __init__(self, filename, sitedirs=()): + self.filename = filename + self.sitedirs = list(map(normalize_path, sitedirs)) + self.basedir = normalize_path(os.path.dirname(self.filename)) + self._load() + Environment.__init__(self, [], None, None) + for path in yield_lines(self.paths): + list(map(self.add, find_distributions(path, True))) + + def _load(self): + self.paths = [] + saw_import = False + seen = dict.fromkeys(self.sitedirs) + if os.path.isfile(self.filename): + f = open(self.filename, 'rt') + for line in f: + if line.startswith('import'): + saw_import = True + continue + path = line.rstrip() + self.paths.append(path) + if not path.strip() or path.strip().startswith('#'): + continue + # skip non-existent paths, in case somebody deleted a package + # manually, and duplicate paths as well + path = self.paths[-1] = normalize_path( + os.path.join(self.basedir, path) + ) + if not os.path.exists(path) or path in seen: + self.paths.pop() # skip it + self.dirty = True # we cleaned up, so we're dirty now :) + continue + seen[path] = 1 + f.close() + + if self.paths and not saw_import: + self.dirty = True # ensure anything we touch has import wrappers + while self.paths and not self.paths[-1].strip(): + self.paths.pop() + + def save(self): + """Write changed .pth file back to disk""" + if not self.dirty: + return + + rel_paths = list(map(self.make_relative, self.paths)) + if rel_paths: + log.debug("Saving %s", self.filename) + lines = self._wrap_lines(rel_paths) + data = '\n'.join(lines) + '\n' + + if os.path.islink(self.filename): + os.unlink(self.filename) + with open(self.filename, 'wt') as f: + f.write(data) + + elif os.path.exists(self.filename): + log.debug("Deleting empty %s", self.filename) + os.unlink(self.filename) + + self.dirty = False + + @staticmethod + def _wrap_lines(lines): + return lines + + def add(self, dist): + """Add `dist` to the distribution map""" + new_path = ( + dist.location not in self.paths and ( + dist.location not in self.sitedirs or + # account for '.' being in PYTHONPATH + dist.location == os.getcwd() + ) + ) + if new_path: + self.paths.append(dist.location) + self.dirty = True + Environment.add(self, dist) + + def remove(self, dist): + """Remove `dist` from the distribution map""" + while dist.location in self.paths: + self.paths.remove(dist.location) + self.dirty = True + Environment.remove(self, dist) + + def make_relative(self, path): + npath, last = os.path.split(normalize_path(path)) + baselen = len(self.basedir) + parts = [last] + sep = os.altsep == '/' and '/' or os.sep + while len(npath) >= baselen: + if npath == self.basedir: + parts.append(os.curdir) + parts.reverse() + return sep.join(parts) + npath, last = os.path.split(npath) + parts.append(last) + else: + return path + + +class RewritePthDistributions(PthDistributions): + @classmethod + def _wrap_lines(cls, lines): + yield cls.prelude + for line in lines: + yield line + yield cls.postlude + + prelude = _one_liner(""" + import sys + sys.__plen = len(sys.path) + """) + postlude = _one_liner(""" + import sys + new = sys.path[sys.__plen:] + del sys.path[sys.__plen:] + p = getattr(sys, '__egginsert', 0) + sys.path[p:p] = new + sys.__egginsert = p + len(new) + """) + + +if os.environ.get('SETUPTOOLS_SYS_PATH_TECHNIQUE', 'raw') == 'rewrite': + PthDistributions = RewritePthDistributions + + +def _first_line_re(): + """ + Return a regular expression based on first_line_re suitable for matching + strings. + """ + if isinstance(first_line_re.pattern, str): + return first_line_re + + # first_line_re in Python >=3.1.4 and >=3.2.1 is a bytes pattern. + return re.compile(first_line_re.pattern.decode()) + + +def auto_chmod(func, arg, exc): + if func in [os.unlink, os.remove] and os.name == 'nt': + chmod(arg, stat.S_IWRITE) + return func(arg) + et, ev, _ = sys.exc_info() + six.reraise(et, (ev[0], ev[1] + (" %s %s" % (func, arg)))) + + +def update_dist_caches(dist_path, fix_zipimporter_caches): + """ + Fix any globally cached `dist_path` related data + + `dist_path` should be a path of a newly installed egg distribution (zipped + or unzipped). + + sys.path_importer_cache contains finder objects that have been cached when + importing data from the original distribution. Any such finders need to be + cleared since the replacement distribution might be packaged differently, + e.g. a zipped egg distribution might get replaced with an unzipped egg + folder or vice versa. Having the old finders cached may then cause Python + to attempt loading modules from the replacement distribution using an + incorrect loader. + + zipimport.zipimporter objects are Python loaders charged with importing + data packaged inside zip archives. If stale loaders referencing the + original distribution, are left behind, they can fail to load modules from + the replacement distribution. E.g. if an old zipimport.zipimporter instance + is used to load data from a new zipped egg archive, it may cause the + operation to attempt to locate the requested data in the wrong location - + one indicated by the original distribution's zip archive directory + information. Such an operation may then fail outright, e.g. report having + read a 'bad local file header', or even worse, it may fail silently & + return invalid data. + + zipimport._zip_directory_cache contains cached zip archive directory + information for all existing zipimport.zipimporter instances and all such + instances connected to the same archive share the same cached directory + information. + + If asked, and the underlying Python implementation allows it, we can fix + all existing zipimport.zipimporter instances instead of having to track + them down and remove them one by one, by updating their shared cached zip + archive directory information. This, of course, assumes that the + replacement distribution is packaged as a zipped egg. + + If not asked to fix existing zipimport.zipimporter instances, we still do + our best to clear any remaining zipimport.zipimporter related cached data + that might somehow later get used when attempting to load data from the new + distribution and thus cause such load operations to fail. Note that when + tracking down such remaining stale data, we can not catch every conceivable + usage from here, and we clear only those that we know of and have found to + cause problems if left alive. Any remaining caches should be updated by + whomever is in charge of maintaining them, i.e. they should be ready to + handle us replacing their zip archives with new distributions at runtime. + + """ + # There are several other known sources of stale zipimport.zipimporter + # instances that we do not clear here, but might if ever given a reason to + # do so: + # * Global setuptools pkg_resources.working_set (a.k.a. 'master working + # set') may contain distributions which may in turn contain their + # zipimport.zipimporter loaders. + # * Several zipimport.zipimporter loaders held by local variables further + # up the function call stack when running the setuptools installation. + # * Already loaded modules may have their __loader__ attribute set to the + # exact loader instance used when importing them. Python 3.4 docs state + # that this information is intended mostly for introspection and so is + # not expected to cause us problems. + normalized_path = normalize_path(dist_path) + _uncache(normalized_path, sys.path_importer_cache) + if fix_zipimporter_caches: + _replace_zip_directory_cache_data(normalized_path) + else: + # Here, even though we do not want to fix existing and now stale + # zipimporter cache information, we still want to remove it. Related to + # Python's zip archive directory information cache, we clear each of + # its stale entries in two phases: + # 1. Clear the entry so attempting to access zip archive information + # via any existing stale zipimport.zipimporter instances fails. + # 2. Remove the entry from the cache so any newly constructed + # zipimport.zipimporter instances do not end up using old stale + # zip archive directory information. + # This whole stale data removal step does not seem strictly necessary, + # but has been left in because it was done before we started replacing + # the zip archive directory information cache content if possible, and + # there are no relevant unit tests that we can depend on to tell us if + # this is really needed. + _remove_and_clear_zip_directory_cache_data(normalized_path) + + +def _collect_zipimporter_cache_entries(normalized_path, cache): + """ + Return zipimporter cache entry keys related to a given normalized path. + + Alternative path spellings (e.g. those using different character case or + those using alternative path separators) related to the same path are + included. Any sub-path entries are included as well, i.e. those + corresponding to zip archives embedded in other zip archives. + + """ + result = [] + prefix_len = len(normalized_path) + for p in cache: + np = normalize_path(p) + if (np.startswith(normalized_path) and + np[prefix_len:prefix_len + 1] in (os.sep, '')): + result.append(p) + return result + + +def _update_zipimporter_cache(normalized_path, cache, updater=None): + """ + Update zipimporter cache data for a given normalized path. + + Any sub-path entries are processed as well, i.e. those corresponding to zip + archives embedded in other zip archives. + + Given updater is a callable taking a cache entry key and the original entry + (after already removing the entry from the cache), and expected to update + the entry and possibly return a new one to be inserted in its place. + Returning None indicates that the entry should not be replaced with a new + one. If no updater is given, the cache entries are simply removed without + any additional processing, the same as if the updater simply returned None. + + """ + for p in _collect_zipimporter_cache_entries(normalized_path, cache): + # N.B. pypy's custom zipimport._zip_directory_cache implementation does + # not support the complete dict interface: + # * Does not support item assignment, thus not allowing this function + # to be used only for removing existing cache entries. + # * Does not support the dict.pop() method, forcing us to use the + # get/del patterns instead. For more detailed information see the + # following links: + # https://github.com/pypa/setuptools/issues/202#issuecomment-202913420 + # http://bit.ly/2h9itJX + old_entry = cache[p] + del cache[p] + new_entry = updater and updater(p, old_entry) + if new_entry is not None: + cache[p] = new_entry + + +def _uncache(normalized_path, cache): + _update_zipimporter_cache(normalized_path, cache) + + +def _remove_and_clear_zip_directory_cache_data(normalized_path): + def clear_and_remove_cached_zip_archive_directory_data(path, old_entry): + old_entry.clear() + + _update_zipimporter_cache( + normalized_path, zipimport._zip_directory_cache, + updater=clear_and_remove_cached_zip_archive_directory_data) + + +# PyPy Python implementation does not allow directly writing to the +# zipimport._zip_directory_cache and so prevents us from attempting to correct +# its content. The best we can do there is clear the problematic cache content +# and have PyPy repopulate it as needed. The downside is that if there are any +# stale zipimport.zipimporter instances laying around, attempting to use them +# will fail due to not having its zip archive directory information available +# instead of being automatically corrected to use the new correct zip archive +# directory information. +if '__pypy__' in sys.builtin_module_names: + _replace_zip_directory_cache_data = \ + _remove_and_clear_zip_directory_cache_data +else: + + def _replace_zip_directory_cache_data(normalized_path): + def replace_cached_zip_archive_directory_data(path, old_entry): + # N.B. In theory, we could load the zip directory information just + # once for all updated path spellings, and then copy it locally and + # update its contained path strings to contain the correct + # spelling, but that seems like a way too invasive move (this cache + # structure is not officially documented anywhere and could in + # theory change with new Python releases) for no significant + # benefit. + old_entry.clear() + zipimport.zipimporter(path) + old_entry.update(zipimport._zip_directory_cache[path]) + return old_entry + + _update_zipimporter_cache( + normalized_path, zipimport._zip_directory_cache, + updater=replace_cached_zip_archive_directory_data) + + +def is_python(text, filename='<string>'): + "Is this string a valid Python script?" + try: + compile(text, filename, 'exec') + except (SyntaxError, TypeError): + return False + else: + return True + + +def is_sh(executable): + """Determine if the specified executable is a .sh (contains a #! line)""" + try: + with io.open(executable, encoding='latin-1') as fp: + magic = fp.read(2) + except (OSError, IOError): + return executable + return magic == '#!' + + +def nt_quote_arg(arg): + """Quote a command line argument according to Windows parsing rules""" + return subprocess.list2cmdline([arg]) + + +def is_python_script(script_text, filename): + """Is this text, as a whole, a Python script? (as opposed to shell/bat/etc. + """ + if filename.endswith('.py') or filename.endswith('.pyw'): + return True # extension says it's Python + if is_python(script_text, filename): + return True # it's syntactically valid Python + if script_text.startswith('#!'): + # It begins with a '#!' line, so check if 'python' is in it somewhere + return 'python' in script_text.splitlines()[0].lower() + + return False # Not any Python I can recognize + + +try: + from os import chmod as _chmod +except ImportError: + # Jython compatibility + def _chmod(*args): + pass + + +def chmod(path, mode): + log.debug("changing mode of %s to %o", path, mode) + try: + _chmod(path, mode) + except os.error as e: + log.debug("chmod failed: %s", e) + + +class CommandSpec(list): + """ + A command spec for a #! header, specified as a list of arguments akin to + those passed to Popen. + """ + + options = [] + split_args = dict() + + @classmethod + def best(cls): + """ + Choose the best CommandSpec class based on environmental conditions. + """ + return cls + + @classmethod + def _sys_executable(cls): + _default = os.path.normpath(sys.executable) + return os.environ.get('__PYVENV_LAUNCHER__', _default) + + @classmethod + def from_param(cls, param): + """ + Construct a CommandSpec from a parameter to build_scripts, which may + be None. + """ + if isinstance(param, cls): + return param + if isinstance(param, list): + return cls(param) + if param is None: + return cls.from_environment() + # otherwise, assume it's a string. + return cls.from_string(param) + + @classmethod + def from_environment(cls): + return cls([cls._sys_executable()]) + + @classmethod + def from_string(cls, string): + """ + Construct a command spec from a simple string representing a command + line parseable by shlex.split. + """ + items = shlex.split(string, **cls.split_args) + return cls(items) + + def install_options(self, script_text): + self.options = shlex.split(self._extract_options(script_text)) + cmdline = subprocess.list2cmdline(self) + if not isascii(cmdline): + self.options[:0] = ['-x'] + + @staticmethod + def _extract_options(orig_script): + """ + Extract any options from the first line of the script. + """ + first = (orig_script + '\n').splitlines()[0] + match = _first_line_re().match(first) + options = match.group(1) or '' if match else '' + return options.strip() + + def as_header(self): + return self._render(self + list(self.options)) + + @staticmethod + def _strip_quotes(item): + _QUOTES = '"\'' + for q in _QUOTES: + if item.startswith(q) and item.endswith(q): + return item[1:-1] + return item + + @staticmethod + def _render(items): + cmdline = subprocess.list2cmdline( + CommandSpec._strip_quotes(item.strip()) for item in items) + return '#!' + cmdline + '\n' + + +# For pbr compat; will be removed in a future version. +sys_executable = CommandSpec._sys_executable() + + +class WindowsCommandSpec(CommandSpec): + split_args = dict(posix=False) + + +class ScriptWriter: + """ + Encapsulates behavior around writing entry point scripts for console and + gui apps. + """ + + template = textwrap.dedent(r""" + # EASY-INSTALL-ENTRY-SCRIPT: %(spec)r,%(group)r,%(name)r + __requires__ = %(spec)r + import re + import sys + from pkg_resources import load_entry_point + + if __name__ == '__main__': + sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0]) + sys.exit( + load_entry_point(%(spec)r, %(group)r, %(name)r)() + ) + """).lstrip() + + command_spec_class = CommandSpec + + @classmethod + def get_script_args(cls, dist, executable=None, wininst=False): + # for backward compatibility + warnings.warn("Use get_args", EasyInstallDeprecationWarning) + writer = (WindowsScriptWriter if wininst else ScriptWriter).best() + header = cls.get_script_header("", executable, wininst) + return writer.get_args(dist, header) + + @classmethod + def get_script_header(cls, script_text, executable=None, wininst=False): + # for backward compatibility + warnings.warn("Use get_header", EasyInstallDeprecationWarning, stacklevel=2) + if wininst: + executable = "python.exe" + return cls.get_header(script_text, executable) + + @classmethod + def get_args(cls, dist, header=None): + """ + Yield write_script() argument tuples for a distribution's + console_scripts and gui_scripts entry points. + """ + if header is None: + header = cls.get_header() + spec = str(dist.as_requirement()) + for type_ in 'console', 'gui': + group = type_ + '_scripts' + for name, ep in dist.get_entry_map(group).items(): + cls._ensure_safe_name(name) + script_text = cls.template % locals() + args = cls._get_script_args(type_, name, header, script_text) + for res in args: + yield res + + @staticmethod + def _ensure_safe_name(name): + """ + Prevent paths in *_scripts entry point names. + """ + has_path_sep = re.search(r'[\\/]', name) + if has_path_sep: + raise ValueError("Path separators not allowed in script names") + + @classmethod + def get_writer(cls, force_windows): + # for backward compatibility + warnings.warn("Use best", EasyInstallDeprecationWarning) + return WindowsScriptWriter.best() if force_windows else cls.best() + + @classmethod + def best(cls): + """ + Select the best ScriptWriter for this environment. + """ + if sys.platform == 'win32' or (os.name == 'java' and os._name == 'nt'): + return WindowsScriptWriter.best() + else: + return cls + + @classmethod + def _get_script_args(cls, type_, name, header, script_text): + # Simply write the stub with no extension. + yield (name, header + script_text) + + @classmethod + def get_header(cls, script_text="", executable=None): + """Create a #! line, getting options (if any) from script_text""" + cmd = cls.command_spec_class.best().from_param(executable) + cmd.install_options(script_text) + return cmd.as_header() + + +class WindowsScriptWriter(ScriptWriter): + command_spec_class = WindowsCommandSpec + + @classmethod + def get_writer(cls): + # for backward compatibility + warnings.warn("Use best", EasyInstallDeprecationWarning) + return cls.best() + + @classmethod + def best(cls): + """ + Select the best ScriptWriter suitable for Windows + """ + writer_lookup = dict( + executable=WindowsExecutableLauncherWriter, + natural=cls, + ) + # for compatibility, use the executable launcher by default + launcher = os.environ.get('SETUPTOOLS_LAUNCHER', 'executable') + return writer_lookup[launcher] + + @classmethod + def _get_script_args(cls, type_, name, header, script_text): + "For Windows, add a .py extension" + ext = dict(console='.pya', gui='.pyw')[type_] + if ext not in os.environ['PATHEXT'].lower().split(';'): + msg = ( + "{ext} not listed in PATHEXT; scripts will not be " + "recognized as executables." + ).format(**locals()) + warnings.warn(msg, UserWarning) + old = ['.pya', '.py', '-script.py', '.pyc', '.pyo', '.pyw', '.exe'] + old.remove(ext) + header = cls._adjust_header(type_, header) + blockers = [name + x for x in old] + yield name + ext, header + script_text, 't', blockers + + @classmethod + def _adjust_header(cls, type_, orig_header): + """ + Make sure 'pythonw' is used for gui and and 'python' is used for + console (regardless of what sys.executable is). + """ + pattern = 'pythonw.exe' + repl = 'python.exe' + if type_ == 'gui': + pattern, repl = repl, pattern + pattern_ob = re.compile(re.escape(pattern), re.IGNORECASE) + new_header = pattern_ob.sub(string=orig_header, repl=repl) + return new_header if cls._use_header(new_header) else orig_header + + @staticmethod + def _use_header(new_header): + """ + Should _adjust_header use the replaced header? + + On non-windows systems, always use. On + Windows systems, only use the replaced header if it resolves + to an executable on the system. + """ + clean_header = new_header[2:-1].strip('"') + return sys.platform != 'win32' or find_executable(clean_header) + + +class WindowsExecutableLauncherWriter(WindowsScriptWriter): + @classmethod + def _get_script_args(cls, type_, name, header, script_text): + """ + For Windows, add a .py extension and an .exe launcher + """ + if type_ == 'gui': + launcher_type = 'gui' + ext = '-script.pyw' + old = ['.pyw'] + else: + launcher_type = 'cli' + ext = '-script.py' + old = ['.py', '.pyc', '.pyo'] + hdr = cls._adjust_header(type_, header) + blockers = [name + x for x in old] + yield (name + ext, hdr + script_text, 't', blockers) + yield ( + name + '.exe', get_win_launcher(launcher_type), + 'b' # write in binary mode + ) + if not is_64bit(): + # install a manifest for the launcher to prevent Windows + # from detecting it as an installer (which it will for + # launchers like easy_install.exe). Consider only + # adding a manifest for launchers detected as installers. + # See Distribute #143 for details. + m_name = name + '.exe.manifest' + yield (m_name, load_launcher_manifest(name), 't') + + +# for backward-compatibility +get_script_args = ScriptWriter.get_script_args +get_script_header = ScriptWriter.get_script_header + + +def get_win_launcher(type): + """ + Load the Windows launcher (executable) suitable for launching a script. + + `type` should be either 'cli' or 'gui' + + Returns the executable as a byte string. + """ + launcher_fn = '%s.exe' % type + if is_64bit(): + launcher_fn = launcher_fn.replace(".", "-64.") + else: + launcher_fn = launcher_fn.replace(".", "-32.") + return resource_string('setuptools', launcher_fn) + + +def load_launcher_manifest(name): + manifest = pkg_resources.resource_string(__name__, 'launcher manifest.xml') + if six.PY2: + return manifest % vars() + else: + return manifest.decode('utf-8') % vars() + + +def rmtree(path, ignore_errors=False, onerror=auto_chmod): + return shutil.rmtree(path, ignore_errors, onerror) + + +def current_umask(): + tmp = os.umask(0o022) + os.umask(tmp) + return tmp + + +def bootstrap(): + # This function is called when setuptools*.egg is run using /bin/sh + import setuptools + + argv0 = os.path.dirname(setuptools.__path__[0]) + sys.argv[0] = argv0 + sys.argv.append(argv0) + main() + + +def main(argv=None, **kw): + from setuptools import setup + from setuptools.dist import Distribution + + class DistributionWithoutHelpCommands(Distribution): + common_usage = "" + + def _show_help(self, *args, **kw): + with _patch_usage(): + Distribution._show_help(self, *args, **kw) + + if argv is None: + argv = sys.argv[1:] + + with _patch_usage(): + setup( + script_args=['-q', 'easy_install', '-v'] + argv, + script_name=sys.argv[0] or 'easy_install', + distclass=DistributionWithoutHelpCommands, + **kw + ) + + +@contextlib.contextmanager +def _patch_usage(): + import distutils.core + USAGE = textwrap.dedent(""" + usage: %(script)s [options] requirement_or_url ... + or: %(script)s --help + """).lstrip() + + def gen_usage(script_name): + return USAGE % dict( + script=os.path.basename(script_name), + ) + + saved = distutils.core.gen_usage + distutils.core.gen_usage = gen_usage + try: + yield + finally: + distutils.core.gen_usage = saved + +class EasyInstallDeprecationWarning(SetuptoolsDeprecationWarning): + """Class for warning about deprecations in EasyInstall in SetupTools. Not ignored by default, unlike DeprecationWarning.""" + diff --git a/env/lib/python3.7/site-packages/setuptools/command/egg_info.py b/env/lib/python3.7/site-packages/setuptools/command/egg_info.py new file mode 100644 index 0000000..d9fe3da --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/egg_info.py @@ -0,0 +1,716 @@ +"""setuptools.command.egg_info + +Create a distribution's .egg-info directory and contents""" + +from distutils.filelist import FileList as _FileList +from distutils.errors import DistutilsInternalError +from distutils.util import convert_path +from distutils import log +import distutils.errors +import distutils.filelist +import os +import re +import sys +import io +import warnings +import time +import collections + +from setuptools.extern import six +from setuptools.extern.six.moves import map + +from setuptools import Command +from setuptools.command.sdist import sdist +from setuptools.command.sdist import walk_revctrl +from setuptools.command.setopt import edit_config +from setuptools.command import bdist_egg +from pkg_resources import ( + parse_requirements, safe_name, parse_version, + safe_version, yield_lines, EntryPoint, iter_entry_points, to_filename) +import setuptools.unicode_utils as unicode_utils +from setuptools.glob import glob + +from setuptools.extern import packaging +from setuptools import SetuptoolsDeprecationWarning + +def translate_pattern(glob): + """ + Translate a file path glob like '*.txt' in to a regular expression. + This differs from fnmatch.translate which allows wildcards to match + directory separators. It also knows about '**/' which matches any number of + directories. + """ + pat = '' + + # This will split on '/' within [character classes]. This is deliberate. + chunks = glob.split(os.path.sep) + + sep = re.escape(os.sep) + valid_char = '[^%s]' % (sep,) + + for c, chunk in enumerate(chunks): + last_chunk = c == len(chunks) - 1 + + # Chunks that are a literal ** are globstars. They match anything. + if chunk == '**': + if last_chunk: + # Match anything if this is the last component + pat += '.*' + else: + # Match '(name/)*' + pat += '(?:%s+%s)*' % (valid_char, sep) + continue # Break here as the whole path component has been handled + + # Find any special characters in the remainder + i = 0 + chunk_len = len(chunk) + while i < chunk_len: + char = chunk[i] + if char == '*': + # Match any number of name characters + pat += valid_char + '*' + elif char == '?': + # Match a name character + pat += valid_char + elif char == '[': + # Character class + inner_i = i + 1 + # Skip initial !/] chars + if inner_i < chunk_len and chunk[inner_i] == '!': + inner_i = inner_i + 1 + if inner_i < chunk_len and chunk[inner_i] == ']': + inner_i = inner_i + 1 + + # Loop till the closing ] is found + while inner_i < chunk_len and chunk[inner_i] != ']': + inner_i = inner_i + 1 + + if inner_i >= chunk_len: + # Got to the end of the string without finding a closing ] + # Do not treat this as a matching group, but as a literal [ + pat += re.escape(char) + else: + # Grab the insides of the [brackets] + inner = chunk[i + 1:inner_i] + char_class = '' + + # Class negation + if inner[0] == '!': + char_class = '^' + inner = inner[1:] + + char_class += re.escape(inner) + pat += '[%s]' % (char_class,) + + # Skip to the end ] + i = inner_i + else: + pat += re.escape(char) + i += 1 + + # Join each chunk with the dir separator + if not last_chunk: + pat += sep + + pat += r'\Z' + return re.compile(pat, flags=re.MULTILINE|re.DOTALL) + + +class InfoCommon: + tag_build = None + tag_date = None + + @property + def name(self): + return safe_name(self.distribution.get_name()) + + def tagged_version(self): + version = self.distribution.get_version() + # egg_info may be called more than once for a distribution, + # in which case the version string already contains all tags. + if self.vtags and version.endswith(self.vtags): + return safe_version(version) + return safe_version(version + self.vtags) + + def tags(self): + version = '' + if self.tag_build: + version += self.tag_build + if self.tag_date: + version += time.strftime("-%Y%m%d") + return version + vtags = property(tags) + + +class egg_info(InfoCommon, Command): + description = "create a distribution's .egg-info directory" + + user_options = [ + ('egg-base=', 'e', "directory containing .egg-info directories" + " (default: top of the source tree)"), + ('tag-date', 'd', "Add date stamp (e.g. 20050528) to version number"), + ('tag-build=', 'b', "Specify explicit tag to add to version number"), + ('no-date', 'D', "Don't include date stamp [default]"), + ] + + boolean_options = ['tag-date'] + negative_opt = { + 'no-date': 'tag-date', + } + + def initialize_options(self): + self.egg_base = None + self.egg_name = None + self.egg_info = None + self.egg_version = None + self.broken_egg_info = False + + #################################### + # allow the 'tag_svn_revision' to be detected and + # set, supporting sdists built on older Setuptools. + @property + def tag_svn_revision(self): + pass + + @tag_svn_revision.setter + def tag_svn_revision(self, value): + pass + #################################### + + def save_version_info(self, filename): + """ + Materialize the value of date into the + build tag. Install build keys in a deterministic order + to avoid arbitrary reordering on subsequent builds. + """ + egg_info = collections.OrderedDict() + # follow the order these keys would have been added + # when PYTHONHASHSEED=0 + egg_info['tag_build'] = self.tags() + egg_info['tag_date'] = 0 + edit_config(filename, dict(egg_info=egg_info)) + + def finalize_options(self): + # Note: we need to capture the current value returned + # by `self.tagged_version()`, so we can later update + # `self.distribution.metadata.version` without + # repercussions. + self.egg_name = self.name + self.egg_version = self.tagged_version() + parsed_version = parse_version(self.egg_version) + + try: + is_version = isinstance(parsed_version, packaging.version.Version) + spec = ( + "%s==%s" if is_version else "%s===%s" + ) + list( + parse_requirements(spec % (self.egg_name, self.egg_version)) + ) + except ValueError: + raise distutils.errors.DistutilsOptionError( + "Invalid distribution name or version syntax: %s-%s" % + (self.egg_name, self.egg_version) + ) + + if self.egg_base is None: + dirs = self.distribution.package_dir + self.egg_base = (dirs or {}).get('', os.curdir) + + self.ensure_dirname('egg_base') + self.egg_info = to_filename(self.egg_name) + '.egg-info' + if self.egg_base != os.curdir: + self.egg_info = os.path.join(self.egg_base, self.egg_info) + if '-' in self.egg_name: + self.check_broken_egg_info() + + # Set package version for the benefit of dumber commands + # (e.g. sdist, bdist_wininst, etc.) + # + self.distribution.metadata.version = self.egg_version + + # If we bootstrapped around the lack of a PKG-INFO, as might be the + # case in a fresh checkout, make sure that any special tags get added + # to the version info + # + pd = self.distribution._patched_dist + if pd is not None and pd.key == self.egg_name.lower(): + pd._version = self.egg_version + pd._parsed_version = parse_version(self.egg_version) + self.distribution._patched_dist = None + + def write_or_delete_file(self, what, filename, data, force=False): + """Write `data` to `filename` or delete if empty + + If `data` is non-empty, this routine is the same as ``write_file()``. + If `data` is empty but not ``None``, this is the same as calling + ``delete_file(filename)`. If `data` is ``None``, then this is a no-op + unless `filename` exists, in which case a warning is issued about the + orphaned file (if `force` is false), or deleted (if `force` is true). + """ + if data: + self.write_file(what, filename, data) + elif os.path.exists(filename): + if data is None and not force: + log.warn( + "%s not set in setup(), but %s exists", what, filename + ) + return + else: + self.delete_file(filename) + + def write_file(self, what, filename, data): + """Write `data` to `filename` (if not a dry run) after announcing it + + `what` is used in a log message to identify what is being written + to the file. + """ + log.info("writing %s to %s", what, filename) + if six.PY3: + data = data.encode("utf-8") + if not self.dry_run: + f = open(filename, 'wb') + f.write(data) + f.close() + + def delete_file(self, filename): + """Delete `filename` (if not a dry run) after announcing it""" + log.info("deleting %s", filename) + if not self.dry_run: + os.unlink(filename) + + def run(self): + self.mkpath(self.egg_info) + os.utime(self.egg_info, None) + installer = self.distribution.fetch_build_egg + for ep in iter_entry_points('egg_info.writers'): + ep.require(installer=installer) + writer = ep.resolve() + writer(self, ep.name, os.path.join(self.egg_info, ep.name)) + + # Get rid of native_libs.txt if it was put there by older bdist_egg + nl = os.path.join(self.egg_info, "native_libs.txt") + if os.path.exists(nl): + self.delete_file(nl) + + self.find_sources() + + def find_sources(self): + """Generate SOURCES.txt manifest file""" + manifest_filename = os.path.join(self.egg_info, "SOURCES.txt") + mm = manifest_maker(self.distribution) + mm.manifest = manifest_filename + mm.run() + self.filelist = mm.filelist + + def check_broken_egg_info(self): + bei = self.egg_name + '.egg-info' + if self.egg_base != os.curdir: + bei = os.path.join(self.egg_base, bei) + if os.path.exists(bei): + log.warn( + "-" * 78 + '\n' + "Note: Your current .egg-info directory has a '-' in its name;" + '\nthis will not work correctly with "setup.py develop".\n\n' + 'Please rename %s to %s to correct this problem.\n' + '-' * 78, + bei, self.egg_info + ) + self.broken_egg_info = self.egg_info + self.egg_info = bei # make it work for now + + +class FileList(_FileList): + # Implementations of the various MANIFEST.in commands + + def process_template_line(self, line): + # Parse the line: split it up, make sure the right number of words + # is there, and return the relevant words. 'action' is always + # defined: it's the first word of the line. Which of the other + # three are defined depends on the action; it'll be either + # patterns, (dir and patterns), or (dir_pattern). + (action, patterns, dir, dir_pattern) = self._parse_template_line(line) + + # OK, now we know that the action is valid and we have the + # right number of words on the line for that action -- so we + # can proceed with minimal error-checking. + if action == 'include': + self.debug_print("include " + ' '.join(patterns)) + for pattern in patterns: + if not self.include(pattern): + log.warn("warning: no files found matching '%s'", pattern) + + elif action == 'exclude': + self.debug_print("exclude " + ' '.join(patterns)) + for pattern in patterns: + if not self.exclude(pattern): + log.warn(("warning: no previously-included files " + "found matching '%s'"), pattern) + + elif action == 'global-include': + self.debug_print("global-include " + ' '.join(patterns)) + for pattern in patterns: + if not self.global_include(pattern): + log.warn(("warning: no files found matching '%s' " + "anywhere in distribution"), pattern) + + elif action == 'global-exclude': + self.debug_print("global-exclude " + ' '.join(patterns)) + for pattern in patterns: + if not self.global_exclude(pattern): + log.warn(("warning: no previously-included files matching " + "'%s' found anywhere in distribution"), + pattern) + + elif action == 'recursive-include': + self.debug_print("recursive-include %s %s" % + (dir, ' '.join(patterns))) + for pattern in patterns: + if not self.recursive_include(dir, pattern): + log.warn(("warning: no files found matching '%s' " + "under directory '%s'"), + pattern, dir) + + elif action == 'recursive-exclude': + self.debug_print("recursive-exclude %s %s" % + (dir, ' '.join(patterns))) + for pattern in patterns: + if not self.recursive_exclude(dir, pattern): + log.warn(("warning: no previously-included files matching " + "'%s' found under directory '%s'"), + pattern, dir) + + elif action == 'graft': + self.debug_print("graft " + dir_pattern) + if not self.graft(dir_pattern): + log.warn("warning: no directories found matching '%s'", + dir_pattern) + + elif action == 'prune': + self.debug_print("prune " + dir_pattern) + if not self.prune(dir_pattern): + log.warn(("no previously-included directories found " + "matching '%s'"), dir_pattern) + + else: + raise DistutilsInternalError( + "this cannot happen: invalid action '%s'" % action) + + def _remove_files(self, predicate): + """ + Remove all files from the file list that match the predicate. + Return True if any matching files were removed + """ + found = False + for i in range(len(self.files) - 1, -1, -1): + if predicate(self.files[i]): + self.debug_print(" removing " + self.files[i]) + del self.files[i] + found = True + return found + + def include(self, pattern): + """Include files that match 'pattern'.""" + found = [f for f in glob(pattern) if not os.path.isdir(f)] + self.extend(found) + return bool(found) + + def exclude(self, pattern): + """Exclude files that match 'pattern'.""" + match = translate_pattern(pattern) + return self._remove_files(match.match) + + def recursive_include(self, dir, pattern): + """ + Include all files anywhere in 'dir/' that match the pattern. + """ + full_pattern = os.path.join(dir, '**', pattern) + found = [f for f in glob(full_pattern, recursive=True) + if not os.path.isdir(f)] + self.extend(found) + return bool(found) + + def recursive_exclude(self, dir, pattern): + """ + Exclude any file anywhere in 'dir/' that match the pattern. + """ + match = translate_pattern(os.path.join(dir, '**', pattern)) + return self._remove_files(match.match) + + def graft(self, dir): + """Include all files from 'dir/'.""" + found = [ + item + for match_dir in glob(dir) + for item in distutils.filelist.findall(match_dir) + ] + self.extend(found) + return bool(found) + + def prune(self, dir): + """Filter out files from 'dir/'.""" + match = translate_pattern(os.path.join(dir, '**')) + return self._remove_files(match.match) + + def global_include(self, pattern): + """ + Include all files anywhere in the current directory that match the + pattern. This is very inefficient on large file trees. + """ + if self.allfiles is None: + self.findall() + match = translate_pattern(os.path.join('**', pattern)) + found = [f for f in self.allfiles if match.match(f)] + self.extend(found) + return bool(found) + + def global_exclude(self, pattern): + """ + Exclude all files anywhere that match the pattern. + """ + match = translate_pattern(os.path.join('**', pattern)) + return self._remove_files(match.match) + + def append(self, item): + if item.endswith('\r'): # Fix older sdists built on Windows + item = item[:-1] + path = convert_path(item) + + if self._safe_path(path): + self.files.append(path) + + def extend(self, paths): + self.files.extend(filter(self._safe_path, paths)) + + def _repair(self): + """ + Replace self.files with only safe paths + + Because some owners of FileList manipulate the underlying + ``files`` attribute directly, this method must be called to + repair those paths. + """ + self.files = list(filter(self._safe_path, self.files)) + + def _safe_path(self, path): + enc_warn = "'%s' not %s encodable -- skipping" + + # To avoid accidental trans-codings errors, first to unicode + u_path = unicode_utils.filesys_decode(path) + if u_path is None: + log.warn("'%s' in unexpected encoding -- skipping" % path) + return False + + # Must ensure utf-8 encodability + utf8_path = unicode_utils.try_encode(u_path, "utf-8") + if utf8_path is None: + log.warn(enc_warn, path, 'utf-8') + return False + + try: + # accept is either way checks out + if os.path.exists(u_path) or os.path.exists(utf8_path): + return True + # this will catch any encode errors decoding u_path + except UnicodeEncodeError: + log.warn(enc_warn, path, sys.getfilesystemencoding()) + + +class manifest_maker(sdist): + template = "MANIFEST.in" + + def initialize_options(self): + self.use_defaults = 1 + self.prune = 1 + self.manifest_only = 1 + self.force_manifest = 1 + + def finalize_options(self): + pass + + def run(self): + self.filelist = FileList() + if not os.path.exists(self.manifest): + self.write_manifest() # it must exist so it'll get in the list + self.add_defaults() + if os.path.exists(self.template): + self.read_template() + self.prune_file_list() + self.filelist.sort() + self.filelist.remove_duplicates() + self.write_manifest() + + def _manifest_normalize(self, path): + path = unicode_utils.filesys_decode(path) + return path.replace(os.sep, '/') + + def write_manifest(self): + """ + Write the file list in 'self.filelist' to the manifest file + named by 'self.manifest'. + """ + self.filelist._repair() + + # Now _repairs should encodability, but not unicode + files = [self._manifest_normalize(f) for f in self.filelist.files] + msg = "writing manifest file '%s'" % self.manifest + self.execute(write_file, (self.manifest, files), msg) + + def warn(self, msg): + if not self._should_suppress_warning(msg): + sdist.warn(self, msg) + + @staticmethod + def _should_suppress_warning(msg): + """ + suppress missing-file warnings from sdist + """ + return re.match(r"standard file .*not found", msg) + + def add_defaults(self): + sdist.add_defaults(self) + self.filelist.append(self.template) + self.filelist.append(self.manifest) + rcfiles = list(walk_revctrl()) + if rcfiles: + self.filelist.extend(rcfiles) + elif os.path.exists(self.manifest): + self.read_manifest() + + if os.path.exists("setup.py"): + # setup.py should be included by default, even if it's not + # the script called to create the sdist + self.filelist.append("setup.py") + + ei_cmd = self.get_finalized_command('egg_info') + self.filelist.graft(ei_cmd.egg_info) + + def prune_file_list(self): + build = self.get_finalized_command('build') + base_dir = self.distribution.get_fullname() + self.filelist.prune(build.build_base) + self.filelist.prune(base_dir) + sep = re.escape(os.sep) + self.filelist.exclude_pattern(r'(^|' + sep + r')(RCS|CVS|\.svn)' + sep, + is_regex=1) + + +def write_file(filename, contents): + """Create a file with the specified name and write 'contents' (a + sequence of strings without line terminators) to it. + """ + contents = "\n".join(contents) + + # assuming the contents has been vetted for utf-8 encoding + contents = contents.encode("utf-8") + + with open(filename, "wb") as f: # always write POSIX-style manifest + f.write(contents) + + +def write_pkg_info(cmd, basename, filename): + log.info("writing %s", filename) + if not cmd.dry_run: + metadata = cmd.distribution.metadata + metadata.version, oldver = cmd.egg_version, metadata.version + metadata.name, oldname = cmd.egg_name, metadata.name + + try: + # write unescaped data to PKG-INFO, so older pkg_resources + # can still parse it + metadata.write_pkg_info(cmd.egg_info) + finally: + metadata.name, metadata.version = oldname, oldver + + safe = getattr(cmd.distribution, 'zip_safe', None) + + bdist_egg.write_safety_flag(cmd.egg_info, safe) + + +def warn_depends_obsolete(cmd, basename, filename): + if os.path.exists(filename): + log.warn( + "WARNING: 'depends.txt' is not used by setuptools 0.6!\n" + "Use the install_requires/extras_require setup() args instead." + ) + + +def _write_requirements(stream, reqs): + lines = yield_lines(reqs or ()) + append_cr = lambda line: line + '\n' + lines = map(append_cr, lines) + stream.writelines(lines) + + +def write_requirements(cmd, basename, filename): + dist = cmd.distribution + data = six.StringIO() + _write_requirements(data, dist.install_requires) + extras_require = dist.extras_require or {} + for extra in sorted(extras_require): + data.write('\n[{extra}]\n'.format(**vars())) + _write_requirements(data, extras_require[extra]) + cmd.write_or_delete_file("requirements", filename, data.getvalue()) + + +def write_setup_requirements(cmd, basename, filename): + data = io.StringIO() + _write_requirements(data, cmd.distribution.setup_requires) + cmd.write_or_delete_file("setup-requirements", filename, data.getvalue()) + + +def write_toplevel_names(cmd, basename, filename): + pkgs = dict.fromkeys( + [ + k.split('.', 1)[0] + for k in cmd.distribution.iter_distribution_names() + ] + ) + cmd.write_file("top-level names", filename, '\n'.join(sorted(pkgs)) + '\n') + + +def overwrite_arg(cmd, basename, filename): + write_arg(cmd, basename, filename, True) + + +def write_arg(cmd, basename, filename, force=False): + argname = os.path.splitext(basename)[0] + value = getattr(cmd.distribution, argname, None) + if value is not None: + value = '\n'.join(value) + '\n' + cmd.write_or_delete_file(argname, filename, value, force) + + +def write_entries(cmd, basename, filename): + ep = cmd.distribution.entry_points + + if isinstance(ep, six.string_types) or ep is None: + data = ep + elif ep is not None: + data = [] + for section, contents in sorted(ep.items()): + if not isinstance(contents, six.string_types): + contents = EntryPoint.parse_group(section, contents) + contents = '\n'.join(sorted(map(str, contents.values()))) + data.append('[%s]\n%s\n\n' % (section, contents)) + data = ''.join(data) + + cmd.write_or_delete_file('entry points', filename, data, True) + + +def get_pkg_info_revision(): + """ + Get a -r### off of PKG-INFO Version in case this is an sdist of + a subversion revision. + """ + warnings.warn("get_pkg_info_revision is deprecated.", EggInfoDeprecationWarning) + if os.path.exists('PKG-INFO'): + with io.open('PKG-INFO') as f: + for line in f: + match = re.match(r"Version:.*-r(\d+)\s*$", line) + if match: + return int(match.group(1)) + return 0 + + +class EggInfoDeprecationWarning(SetuptoolsDeprecationWarning): + """Class for warning about deprecations in eggInfo in setupTools. Not ignored by default, unlike DeprecationWarning.""" diff --git a/env/lib/python3.7/site-packages/setuptools/command/install.py b/env/lib/python3.7/site-packages/setuptools/command/install.py new file mode 100644 index 0000000..31a5ddb --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/install.py @@ -0,0 +1,125 @@ +from distutils.errors import DistutilsArgError +import inspect +import glob +import warnings +import platform +import distutils.command.install as orig + +import setuptools + +# Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for +# now. See https://github.com/pypa/setuptools/issues/199/ +_install = orig.install + + +class install(orig.install): + """Use easy_install to install the package, w/dependencies""" + + user_options = orig.install.user_options + [ + ('old-and-unmanageable', None, "Try not to use this!"), + ('single-version-externally-managed', None, + "used by system package builders to create 'flat' eggs"), + ] + boolean_options = orig.install.boolean_options + [ + 'old-and-unmanageable', 'single-version-externally-managed', + ] + new_commands = [ + ('install_egg_info', lambda self: True), + ('install_scripts', lambda self: True), + ] + _nc = dict(new_commands) + + def initialize_options(self): + orig.install.initialize_options(self) + self.old_and_unmanageable = None + self.single_version_externally_managed = None + + def finalize_options(self): + orig.install.finalize_options(self) + if self.root: + self.single_version_externally_managed = True + elif self.single_version_externally_managed: + if not self.root and not self.record: + raise DistutilsArgError( + "You must specify --record or --root when building system" + " packages" + ) + + def handle_extra_path(self): + if self.root or self.single_version_externally_managed: + # explicit backward-compatibility mode, allow extra_path to work + return orig.install.handle_extra_path(self) + + # Ignore extra_path when installing an egg (or being run by another + # command without --root or --single-version-externally-managed + self.path_file = None + self.extra_dirs = '' + + def run(self): + # Explicit request for old-style install? Just do it + if self.old_and_unmanageable or self.single_version_externally_managed: + return orig.install.run(self) + + if not self._called_from_setup(inspect.currentframe()): + # Run in backward-compatibility mode to support bdist_* commands. + orig.install.run(self) + else: + self.do_egg_install() + + @staticmethod + def _called_from_setup(run_frame): + """ + Attempt to detect whether run() was called from setup() or by another + command. If called by setup(), the parent caller will be the + 'run_command' method in 'distutils.dist', and *its* caller will be + the 'run_commands' method. If called any other way, the + immediate caller *might* be 'run_command', but it won't have been + called by 'run_commands'. Return True in that case or if a call stack + is unavailable. Return False otherwise. + """ + if run_frame is None: + msg = "Call stack not available. bdist_* commands may fail." + warnings.warn(msg) + if platform.python_implementation() == 'IronPython': + msg = "For best results, pass -X:Frames to enable call stack." + warnings.warn(msg) + return True + res = inspect.getouterframes(run_frame)[2] + caller, = res[:1] + info = inspect.getframeinfo(caller) + caller_module = caller.f_globals.get('__name__', '') + return ( + caller_module == 'distutils.dist' + and info.function == 'run_commands' + ) + + def do_egg_install(self): + + easy_install = self.distribution.get_command_class('easy_install') + + cmd = easy_install( + self.distribution, args="x", root=self.root, record=self.record, + ) + cmd.ensure_finalized() # finalize before bdist_egg munges install cmd + cmd.always_copy_from = '.' # make sure local-dir eggs get installed + + # pick up setup-dir .egg files only: no .egg-info + cmd.package_index.scan(glob.glob('*.egg')) + + self.run_command('bdist_egg') + args = [self.distribution.get_command_obj('bdist_egg').egg_output] + + if setuptools.bootstrap_install_from: + # Bootstrap self-installation of setuptools + args.insert(0, setuptools.bootstrap_install_from) + + cmd.args = args + cmd.run() + setuptools.bootstrap_install_from = None + + +# XXX Python 3.1 doesn't see _nc if this is inside the class +install.sub_commands = ( + [cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] + + install.new_commands +) diff --git a/env/lib/python3.7/site-packages/setuptools/command/install_egg_info.py b/env/lib/python3.7/site-packages/setuptools/command/install_egg_info.py new file mode 100644 index 0000000..edc4718 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/install_egg_info.py @@ -0,0 +1,62 @@ +from distutils import log, dir_util +import os + +from setuptools import Command +from setuptools import namespaces +from setuptools.archive_util import unpack_archive +import pkg_resources + + +class install_egg_info(namespaces.Installer, Command): + """Install an .egg-info directory for the package""" + + description = "Install an .egg-info directory for the package" + + user_options = [ + ('install-dir=', 'd', "directory to install to"), + ] + + def initialize_options(self): + self.install_dir = None + + def finalize_options(self): + self.set_undefined_options('install_lib', + ('install_dir', 'install_dir')) + ei_cmd = self.get_finalized_command("egg_info") + basename = pkg_resources.Distribution( + None, None, ei_cmd.egg_name, ei_cmd.egg_version + ).egg_name() + '.egg-info' + self.source = ei_cmd.egg_info + self.target = os.path.join(self.install_dir, basename) + self.outputs = [] + + def run(self): + self.run_command('egg_info') + if os.path.isdir(self.target) and not os.path.islink(self.target): + dir_util.remove_tree(self.target, dry_run=self.dry_run) + elif os.path.exists(self.target): + self.execute(os.unlink, (self.target,), "Removing " + self.target) + if not self.dry_run: + pkg_resources.ensure_directory(self.target) + self.execute( + self.copytree, (), "Copying %s to %s" % (self.source, self.target) + ) + self.install_namespaces() + + def get_outputs(self): + return self.outputs + + def copytree(self): + # Copy the .egg-info tree to site-packages + def skimmer(src, dst): + # filter out source-control directories; note that 'src' is always + # a '/'-separated path, regardless of platform. 'dst' is a + # platform-specific path. + for skip in '.svn/', 'CVS/': + if src.startswith(skip) or '/' + skip in src: + return None + self.outputs.append(dst) + log.debug("Copying %s to %s", src, dst) + return dst + + unpack_archive(self.source, self.target, skimmer) diff --git a/env/lib/python3.7/site-packages/setuptools/command/install_lib.py b/env/lib/python3.7/site-packages/setuptools/command/install_lib.py new file mode 100644 index 0000000..2b31c3e --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/install_lib.py @@ -0,0 +1,121 @@ +import os +import imp +from itertools import product, starmap +import distutils.command.install_lib as orig + + +class install_lib(orig.install_lib): + """Don't add compiled flags to filenames of non-Python files""" + + def run(self): + self.build() + outfiles = self.install() + if outfiles is not None: + # always compile, in case we have any extension stubs to deal with + self.byte_compile(outfiles) + + def get_exclusions(self): + """ + Return a collections.Sized collections.Container of paths to be + excluded for single_version_externally_managed installations. + """ + all_packages = ( + pkg + for ns_pkg in self._get_SVEM_NSPs() + for pkg in self._all_packages(ns_pkg) + ) + + excl_specs = product(all_packages, self._gen_exclusion_paths()) + return set(starmap(self._exclude_pkg_path, excl_specs)) + + def _exclude_pkg_path(self, pkg, exclusion_path): + """ + Given a package name and exclusion path within that package, + compute the full exclusion path. + """ + parts = pkg.split('.') + [exclusion_path] + return os.path.join(self.install_dir, *parts) + + @staticmethod + def _all_packages(pkg_name): + """ + >>> list(install_lib._all_packages('foo.bar.baz')) + ['foo.bar.baz', 'foo.bar', 'foo'] + """ + while pkg_name: + yield pkg_name + pkg_name, sep, child = pkg_name.rpartition('.') + + def _get_SVEM_NSPs(self): + """ + Get namespace packages (list) but only for + single_version_externally_managed installations and empty otherwise. + """ + # TODO: is it necessary to short-circuit here? i.e. what's the cost + # if get_finalized_command is called even when namespace_packages is + # False? + if not self.distribution.namespace_packages: + return [] + + install_cmd = self.get_finalized_command('install') + svem = install_cmd.single_version_externally_managed + + return self.distribution.namespace_packages if svem else [] + + @staticmethod + def _gen_exclusion_paths(): + """ + Generate file paths to be excluded for namespace packages (bytecode + cache files). + """ + # always exclude the package module itself + yield '__init__.py' + + yield '__init__.pyc' + yield '__init__.pyo' + + if not hasattr(imp, 'get_tag'): + return + + base = os.path.join('__pycache__', '__init__.' + imp.get_tag()) + yield base + '.pyc' + yield base + '.pyo' + yield base + '.opt-1.pyc' + yield base + '.opt-2.pyc' + + def copy_tree( + self, infile, outfile, + preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1 + ): + assert preserve_mode and preserve_times and not preserve_symlinks + exclude = self.get_exclusions() + + if not exclude: + return orig.install_lib.copy_tree(self, infile, outfile) + + # Exclude namespace package __init__.py* files from the output + + from setuptools.archive_util import unpack_directory + from distutils import log + + outfiles = [] + + def pf(src, dst): + if dst in exclude: + log.warn("Skipping installation of %s (namespace package)", + dst) + return False + + log.info("copying %s -> %s", src, os.path.dirname(dst)) + outfiles.append(dst) + return dst + + unpack_directory(infile, outfile, pf) + return outfiles + + def get_outputs(self): + outputs = orig.install_lib.get_outputs(self) + exclude = self.get_exclusions() + if exclude: + return [f for f in outputs if f not in exclude] + return outputs diff --git a/env/lib/python3.7/site-packages/setuptools/command/install_scripts.py b/env/lib/python3.7/site-packages/setuptools/command/install_scripts.py new file mode 100644 index 0000000..1623427 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/install_scripts.py @@ -0,0 +1,65 @@ +from distutils import log +import distutils.command.install_scripts as orig +import os +import sys + +from pkg_resources import Distribution, PathMetadata, ensure_directory + + +class install_scripts(orig.install_scripts): + """Do normal script install, plus any egg_info wrapper scripts""" + + def initialize_options(self): + orig.install_scripts.initialize_options(self) + self.no_ep = False + + def run(self): + import setuptools.command.easy_install as ei + + self.run_command("egg_info") + if self.distribution.scripts: + orig.install_scripts.run(self) # run first to set up self.outfiles + else: + self.outfiles = [] + if self.no_ep: + # don't install entry point scripts into .egg file! + return + + ei_cmd = self.get_finalized_command("egg_info") + dist = Distribution( + ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), + ei_cmd.egg_name, ei_cmd.egg_version, + ) + bs_cmd = self.get_finalized_command('build_scripts') + exec_param = getattr(bs_cmd, 'executable', None) + bw_cmd = self.get_finalized_command("bdist_wininst") + is_wininst = getattr(bw_cmd, '_is_running', False) + writer = ei.ScriptWriter + if is_wininst: + exec_param = "python.exe" + writer = ei.WindowsScriptWriter + if exec_param == sys.executable: + # In case the path to the Python executable contains a space, wrap + # it so it's not split up. + exec_param = [exec_param] + # resolve the writer to the environment + writer = writer.best() + cmd = writer.command_spec_class.best().from_param(exec_param) + for args in writer.get_args(dist, cmd.as_header()): + self.write_script(*args) + + def write_script(self, script_name, contents, mode="t", *ignored): + """Write an executable file to the scripts directory""" + from setuptools.command.easy_install import chmod, current_umask + + log.info("Installing %s script to %s", script_name, self.install_dir) + target = os.path.join(self.install_dir, script_name) + self.outfiles.append(target) + + mask = current_umask() + if not self.dry_run: + ensure_directory(target) + f = open(target, "w" + mode) + f.write(contents) + f.close() + chmod(target, 0o777 - mask) diff --git a/env/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml b/env/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml new file mode 100644 index 0000000..5972a96 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/launcher manifest.xml @@ -0,0 +1,15 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> + <assemblyIdentity version="1.0.0.0" + processorArchitecture="X86" + name="%(name)s" + type="win32"/> + <!-- Identify the application security requirements. --> + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> + <security> + <requestedPrivileges> + <requestedExecutionLevel level="asInvoker" uiAccess="false"/> + </requestedPrivileges> + </security> + </trustInfo> +</assembly> diff --git a/env/lib/python3.7/site-packages/setuptools/command/py36compat.py b/env/lib/python3.7/site-packages/setuptools/command/py36compat.py new file mode 100644 index 0000000..61063e7 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/py36compat.py @@ -0,0 +1,136 @@ +import os +from glob import glob +from distutils.util import convert_path +from distutils.command import sdist + +from setuptools.extern.six.moves import filter + + +class sdist_add_defaults: + """ + Mix-in providing forward-compatibility for functionality as found in + distutils on Python 3.7. + + Do not edit the code in this class except to update functionality + as implemented in distutils. Instead, override in the subclass. + """ + + def add_defaults(self): + """Add all the default files to self.filelist: + - README or README.txt + - setup.py + - test/test*.py + - all pure Python modules mentioned in setup script + - all files pointed by package_data (build_py) + - all files defined in data_files. + - all files defined as scripts. + - all C sources listed as part of extensions or C libraries + in the setup script (doesn't catch C headers!) + Warns if (README or README.txt) or setup.py are missing; everything + else is optional. + """ + self._add_defaults_standards() + self._add_defaults_optional() + self._add_defaults_python() + self._add_defaults_data_files() + self._add_defaults_ext() + self._add_defaults_c_libs() + self._add_defaults_scripts() + + @staticmethod + def _cs_path_exists(fspath): + """ + Case-sensitive path existence check + + >>> sdist_add_defaults._cs_path_exists(__file__) + True + >>> sdist_add_defaults._cs_path_exists(__file__.upper()) + False + """ + if not os.path.exists(fspath): + return False + # make absolute so we always have a directory + abspath = os.path.abspath(fspath) + directory, filename = os.path.split(abspath) + return filename in os.listdir(directory) + + def _add_defaults_standards(self): + standards = [self.READMES, self.distribution.script_name] + for fn in standards: + if isinstance(fn, tuple): + alts = fn + got_it = False + for fn in alts: + if self._cs_path_exists(fn): + got_it = True + self.filelist.append(fn) + break + + if not got_it: + self.warn("standard file not found: should have one of " + + ', '.join(alts)) + else: + if self._cs_path_exists(fn): + self.filelist.append(fn) + else: + self.warn("standard file '%s' not found" % fn) + + def _add_defaults_optional(self): + optional = ['test/test*.py', 'setup.cfg'] + for pattern in optional: + files = filter(os.path.isfile, glob(pattern)) + self.filelist.extend(files) + + def _add_defaults_python(self): + # build_py is used to get: + # - python modules + # - files defined in package_data + build_py = self.get_finalized_command('build_py') + + # getting python files + if self.distribution.has_pure_modules(): + self.filelist.extend(build_py.get_source_files()) + + # getting package_data files + # (computed in build_py.data_files by build_py.finalize_options) + for pkg, src_dir, build_dir, filenames in build_py.data_files: + for filename in filenames: + self.filelist.append(os.path.join(src_dir, filename)) + + def _add_defaults_data_files(self): + # getting distribution.data_files + if self.distribution.has_data_files(): + for item in self.distribution.data_files: + if isinstance(item, str): + # plain file + item = convert_path(item) + if os.path.isfile(item): + self.filelist.append(item) + else: + # a (dirname, filenames) tuple + dirname, filenames = item + for f in filenames: + f = convert_path(f) + if os.path.isfile(f): + self.filelist.append(f) + + def _add_defaults_ext(self): + if self.distribution.has_ext_modules(): + build_ext = self.get_finalized_command('build_ext') + self.filelist.extend(build_ext.get_source_files()) + + def _add_defaults_c_libs(self): + if self.distribution.has_c_libraries(): + build_clib = self.get_finalized_command('build_clib') + self.filelist.extend(build_clib.get_source_files()) + + def _add_defaults_scripts(self): + if self.distribution.has_scripts(): + build_scripts = self.get_finalized_command('build_scripts') + self.filelist.extend(build_scripts.get_source_files()) + + +if hasattr(sdist.sdist, '_add_defaults_standards'): + # disable the functionality already available upstream + class sdist_add_defaults: + pass diff --git a/env/lib/python3.7/site-packages/setuptools/command/register.py b/env/lib/python3.7/site-packages/setuptools/command/register.py new file mode 100644 index 0000000..98bc015 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/register.py @@ -0,0 +1,18 @@ +from distutils import log +import distutils.command.register as orig + + +class register(orig.register): + __doc__ = orig.register.__doc__ + + def run(self): + try: + # Make sure that we are using valid current name/version info + self.run_command('egg_info') + orig.register.run(self) + finally: + self.announce( + "WARNING: Registering is deprecated, use twine to " + "upload instead (https://pypi.org/p/twine/)", + log.WARN + ) diff --git a/env/lib/python3.7/site-packages/setuptools/command/rotate.py b/env/lib/python3.7/site-packages/setuptools/command/rotate.py new file mode 100644 index 0000000..b89353f --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/rotate.py @@ -0,0 +1,66 @@ +from distutils.util import convert_path +from distutils import log +from distutils.errors import DistutilsOptionError +import os +import shutil + +from setuptools.extern import six + +from setuptools import Command + + +class rotate(Command): + """Delete older distributions""" + + description = "delete older distributions, keeping N newest files" + user_options = [ + ('match=', 'm', "patterns to match (required)"), + ('dist-dir=', 'd', "directory where the distributions are"), + ('keep=', 'k', "number of matching distributions to keep"), + ] + + boolean_options = [] + + def initialize_options(self): + self.match = None + self.dist_dir = None + self.keep = None + + def finalize_options(self): + if self.match is None: + raise DistutilsOptionError( + "Must specify one or more (comma-separated) match patterns " + "(e.g. '.zip' or '.egg')" + ) + if self.keep is None: + raise DistutilsOptionError("Must specify number of files to keep") + try: + self.keep = int(self.keep) + except ValueError: + raise DistutilsOptionError("--keep must be an integer") + if isinstance(self.match, six.string_types): + self.match = [ + convert_path(p.strip()) for p in self.match.split(',') + ] + self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) + + def run(self): + self.run_command("egg_info") + from glob import glob + + for pattern in self.match: + pattern = self.distribution.get_name() + '*' + pattern + files = glob(os.path.join(self.dist_dir, pattern)) + files = [(os.path.getmtime(f), f) for f in files] + files.sort() + files.reverse() + + log.info("%d file(s) matching %s", len(files), pattern) + files = files[self.keep:] + for (t, f) in files: + log.info("Deleting %s", f) + if not self.dry_run: + if os.path.isdir(f): + shutil.rmtree(f) + else: + os.unlink(f) diff --git a/env/lib/python3.7/site-packages/setuptools/command/saveopts.py b/env/lib/python3.7/site-packages/setuptools/command/saveopts.py new file mode 100644 index 0000000..611cec5 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/saveopts.py @@ -0,0 +1,22 @@ +from setuptools.command.setopt import edit_config, option_base + + +class saveopts(option_base): + """Save command-line options to a file""" + + description = "save supplied options to setup.cfg or other config file" + + def run(self): + dist = self.distribution + settings = {} + + for cmd in dist.command_options: + + if cmd == 'saveopts': + continue # don't save our own options! + + for opt, (src, val) in dist.get_option_dict(cmd).items(): + if src == "command line": + settings.setdefault(cmd, {})[opt] = val + + edit_config(self.filename, settings, self.dry_run) diff --git a/env/lib/python3.7/site-packages/setuptools/command/sdist.py b/env/lib/python3.7/site-packages/setuptools/command/sdist.py new file mode 100644 index 0000000..bcfae4d --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/sdist.py @@ -0,0 +1,200 @@ +from distutils import log +import distutils.command.sdist as orig +import os +import sys +import io +import contextlib + +from setuptools.extern import six + +from .py36compat import sdist_add_defaults + +import pkg_resources + +_default_revctrl = list + + +def walk_revctrl(dirname=''): + """Find all files under revision control""" + for ep in pkg_resources.iter_entry_points('setuptools.file_finders'): + for item in ep.load()(dirname): + yield item + + +class sdist(sdist_add_defaults, orig.sdist): + """Smart sdist that finds anything supported by revision control""" + + user_options = [ + ('formats=', None, + "formats for source distribution (comma-separated list)"), + ('keep-temp', 'k', + "keep the distribution tree around after creating " + + "archive file(s)"), + ('dist-dir=', 'd', + "directory to put the source distribution archive(s) in " + "[default: dist]"), + ] + + negative_opt = {} + + README_EXTENSIONS = ['', '.rst', '.txt', '.md'] + READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS) + + def run(self): + self.run_command('egg_info') + ei_cmd = self.get_finalized_command('egg_info') + self.filelist = ei_cmd.filelist + self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt')) + self.check_readme() + + # Run sub commands + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + self.make_distribution() + + dist_files = getattr(self.distribution, 'dist_files', []) + for file in self.archive_files: + data = ('sdist', '', file) + if data not in dist_files: + dist_files.append(data) + + def initialize_options(self): + orig.sdist.initialize_options(self) + + self._default_to_gztar() + + def _default_to_gztar(self): + # only needed on Python prior to 3.6. + if sys.version_info >= (3, 6, 0, 'beta', 1): + return + self.formats = ['gztar'] + + def make_distribution(self): + """ + Workaround for #516 + """ + with self._remove_os_link(): + orig.sdist.make_distribution(self) + + @staticmethod + @contextlib.contextmanager + def _remove_os_link(): + """ + In a context, remove and restore os.link if it exists + """ + + class NoValue: + pass + + orig_val = getattr(os, 'link', NoValue) + try: + del os.link + except Exception: + pass + try: + yield + finally: + if orig_val is not NoValue: + setattr(os, 'link', orig_val) + + def __read_template_hack(self): + # This grody hack closes the template file (MANIFEST.in) if an + # exception occurs during read_template. + # Doing so prevents an error when easy_install attempts to delete the + # file. + try: + orig.sdist.read_template(self) + except Exception: + _, _, tb = sys.exc_info() + tb.tb_next.tb_frame.f_locals['template'].close() + raise + + # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle + # has been fixed, so only override the method if we're using an earlier + # Python. + has_leaky_handle = ( + sys.version_info < (2, 7, 2) + or (3, 0) <= sys.version_info < (3, 1, 4) + or (3, 2) <= sys.version_info < (3, 2, 1) + ) + if has_leaky_handle: + read_template = __read_template_hack + + def _add_defaults_python(self): + """getting python files""" + if self.distribution.has_pure_modules(): + build_py = self.get_finalized_command('build_py') + self.filelist.extend(build_py.get_source_files()) + # This functionality is incompatible with include_package_data, and + # will in fact create an infinite recursion if include_package_data + # is True. Use of include_package_data will imply that + # distutils-style automatic handling of package_data is disabled + if not self.distribution.include_package_data: + for _, src_dir, _, filenames in build_py.data_files: + self.filelist.extend([os.path.join(src_dir, filename) + for filename in filenames]) + + def _add_defaults_data_files(self): + try: + if six.PY2: + sdist_add_defaults._add_defaults_data_files(self) + else: + super()._add_defaults_data_files() + except TypeError: + log.warn("data_files contains unexpected objects") + + def check_readme(self): + for f in self.READMES: + if os.path.exists(f): + return + else: + self.warn( + "standard file not found: should have one of " + + ', '.join(self.READMES) + ) + + def make_release_tree(self, base_dir, files): + orig.sdist.make_release_tree(self, base_dir, files) + + # Save any egg_info command line options used to create this sdist + dest = os.path.join(base_dir, 'setup.cfg') + if hasattr(os, 'link') and os.path.exists(dest): + # unlink and re-copy, since it might be hard-linked, and + # we don't want to change the source version + os.unlink(dest) + self.copy_file('setup.cfg', dest) + + self.get_finalized_command('egg_info').save_version_info(dest) + + def _manifest_is_not_generated(self): + # check for special comment used in 2.7.1 and higher + if not os.path.isfile(self.manifest): + return False + + with io.open(self.manifest, 'rb') as fp: + first_line = fp.readline() + return (first_line != + '# file GENERATED by distutils, do NOT edit\n'.encode()) + + def read_manifest(self): + """Read the manifest file (named by 'self.manifest') and use it to + fill in 'self.filelist', the list of files to include in the source + distribution. + """ + log.info("reading manifest file '%s'", self.manifest) + manifest = open(self.manifest, 'rb') + for line in manifest: + # The manifest must contain UTF-8. See #303. + if six.PY3: + try: + line = line.decode('UTF-8') + except UnicodeDecodeError: + log.warn("%r not UTF-8 decodable -- skipping" % line) + continue + # ignore comments and blank lines + line = line.strip() + if line.startswith('#') or not line: + continue + self.filelist.append(line) + manifest.close() diff --git a/env/lib/python3.7/site-packages/setuptools/command/setopt.py b/env/lib/python3.7/site-packages/setuptools/command/setopt.py new file mode 100644 index 0000000..7e57cc0 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/setopt.py @@ -0,0 +1,149 @@ +from distutils.util import convert_path +from distutils import log +from distutils.errors import DistutilsOptionError +import distutils +import os + +from setuptools.extern.six.moves import configparser + +from setuptools import Command + +__all__ = ['config_file', 'edit_config', 'option_base', 'setopt'] + + +def config_file(kind="local"): + """Get the filename of the distutils, local, global, or per-user config + + `kind` must be one of "local", "global", or "user" + """ + if kind == 'local': + return 'setup.cfg' + if kind == 'global': + return os.path.join( + os.path.dirname(distutils.__file__), 'distutils.cfg' + ) + if kind == 'user': + dot = os.name == 'posix' and '.' or '' + return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot)) + raise ValueError( + "config_file() type must be 'local', 'global', or 'user'", kind + ) + + +def edit_config(filename, settings, dry_run=False): + """Edit a configuration file to include `settings` + + `settings` is a dictionary of dictionaries or ``None`` values, keyed by + command/section name. A ``None`` value means to delete the entire section, + while a dictionary lists settings to be changed or deleted in that section. + A setting of ``None`` means to delete that setting. + """ + log.debug("Reading configuration from %s", filename) + opts = configparser.RawConfigParser() + opts.read([filename]) + for section, options in settings.items(): + if options is None: + log.info("Deleting section [%s] from %s", section, filename) + opts.remove_section(section) + else: + if not opts.has_section(section): + log.debug("Adding new section [%s] to %s", section, filename) + opts.add_section(section) + for option, value in options.items(): + if value is None: + log.debug( + "Deleting %s.%s from %s", + section, option, filename + ) + opts.remove_option(section, option) + if not opts.options(section): + log.info("Deleting empty [%s] section from %s", + section, filename) + opts.remove_section(section) + else: + log.debug( + "Setting %s.%s to %r in %s", + section, option, value, filename + ) + opts.set(section, option, value) + + log.info("Writing %s", filename) + if not dry_run: + with open(filename, 'w') as f: + opts.write(f) + + +class option_base(Command): + """Abstract base class for commands that mess with config files""" + + user_options = [ + ('global-config', 'g', + "save options to the site-wide distutils.cfg file"), + ('user-config', 'u', + "save options to the current user's pydistutils.cfg file"), + ('filename=', 'f', + "configuration file to use (default=setup.cfg)"), + ] + + boolean_options = [ + 'global-config', 'user-config', + ] + + def initialize_options(self): + self.global_config = None + self.user_config = None + self.filename = None + + def finalize_options(self): + filenames = [] + if self.global_config: + filenames.append(config_file('global')) + if self.user_config: + filenames.append(config_file('user')) + if self.filename is not None: + filenames.append(self.filename) + if not filenames: + filenames.append(config_file('local')) + if len(filenames) > 1: + raise DistutilsOptionError( + "Must specify only one configuration file option", + filenames + ) + self.filename, = filenames + + +class setopt(option_base): + """Save command-line options to a file""" + + description = "set an option in setup.cfg or another config file" + + user_options = [ + ('command=', 'c', 'command to set an option for'), + ('option=', 'o', 'option to set'), + ('set-value=', 's', 'value of the option'), + ('remove', 'r', 'remove (unset) the value'), + ] + option_base.user_options + + boolean_options = option_base.boolean_options + ['remove'] + + def initialize_options(self): + option_base.initialize_options(self) + self.command = None + self.option = None + self.set_value = None + self.remove = None + + def finalize_options(self): + option_base.finalize_options(self) + if self.command is None or self.option is None: + raise DistutilsOptionError("Must specify --command *and* --option") + if self.set_value is None and not self.remove: + raise DistutilsOptionError("Must specify --set-value or --remove") + + def run(self): + edit_config( + self.filename, { + self.command: {self.option.replace('-', '_'): self.set_value} + }, + self.dry_run + ) diff --git a/env/lib/python3.7/site-packages/setuptools/command/test.py b/env/lib/python3.7/site-packages/setuptools/command/test.py new file mode 100644 index 0000000..dde0118 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/test.py @@ -0,0 +1,270 @@ +import os +import operator +import sys +import contextlib +import itertools +import unittest +from distutils.errors import DistutilsError, DistutilsOptionError +from distutils import log +from unittest import TestLoader + +from setuptools.extern import six +from setuptools.extern.six.moves import map, filter + +from pkg_resources import (resource_listdir, resource_exists, normalize_path, + working_set, _namespace_packages, evaluate_marker, + add_activation_listener, require, EntryPoint) +from setuptools import Command + +__metaclass__ = type + + +class ScanningLoader(TestLoader): + + def __init__(self): + TestLoader.__init__(self) + self._visited = set() + + def loadTestsFromModule(self, module, pattern=None): + """Return a suite of all tests cases contained in the given module + + If the module is a package, load tests from all the modules in it. + If the module has an ``additional_tests`` function, call it and add + the return value to the tests. + """ + if module in self._visited: + return None + self._visited.add(module) + + tests = [] + tests.append(TestLoader.loadTestsFromModule(self, module)) + + if hasattr(module, "additional_tests"): + tests.append(module.additional_tests()) + + if hasattr(module, '__path__'): + for file in resource_listdir(module.__name__, ''): + if file.endswith('.py') and file != '__init__.py': + submodule = module.__name__ + '.' + file[:-3] + else: + if resource_exists(module.__name__, file + '/__init__.py'): + submodule = module.__name__ + '.' + file + else: + continue + tests.append(self.loadTestsFromName(submodule)) + + if len(tests) != 1: + return self.suiteClass(tests) + else: + return tests[0] # don't create a nested suite for only one return + + +# adapted from jaraco.classes.properties:NonDataProperty +class NonDataProperty: + def __init__(self, fget): + self.fget = fget + + def __get__(self, obj, objtype=None): + if obj is None: + return self + return self.fget(obj) + + +class test(Command): + """Command to run unit tests after in-place build""" + + description = "run unit tests after in-place build" + + user_options = [ + ('test-module=', 'm', "Run 'test_suite' in specified module"), + ('test-suite=', 's', + "Run single test, case or suite (e.g. 'module.test_suite')"), + ('test-runner=', 'r', "Test runner to use"), + ] + + def initialize_options(self): + self.test_suite = None + self.test_module = None + self.test_loader = None + self.test_runner = None + + def finalize_options(self): + + if self.test_suite and self.test_module: + msg = "You may specify a module or a suite, but not both" + raise DistutilsOptionError(msg) + + if self.test_suite is None: + if self.test_module is None: + self.test_suite = self.distribution.test_suite + else: + self.test_suite = self.test_module + ".test_suite" + + if self.test_loader is None: + self.test_loader = getattr(self.distribution, 'test_loader', None) + if self.test_loader is None: + self.test_loader = "setuptools.command.test:ScanningLoader" + if self.test_runner is None: + self.test_runner = getattr(self.distribution, 'test_runner', None) + + @NonDataProperty + def test_args(self): + return list(self._test_args()) + + def _test_args(self): + if not self.test_suite and sys.version_info >= (2, 7): + yield 'discover' + if self.verbose: + yield '--verbose' + if self.test_suite: + yield self.test_suite + + def with_project_on_sys_path(self, func): + """ + Backward compatibility for project_on_sys_path context. + """ + with self.project_on_sys_path(): + func() + + @contextlib.contextmanager + def project_on_sys_path(self, include_dists=[]): + with_2to3 = six.PY3 and getattr(self.distribution, 'use_2to3', False) + + if with_2to3: + # If we run 2to3 we can not do this inplace: + + # Ensure metadata is up-to-date + self.reinitialize_command('build_py', inplace=0) + self.run_command('build_py') + bpy_cmd = self.get_finalized_command("build_py") + build_path = normalize_path(bpy_cmd.build_lib) + + # Build extensions + self.reinitialize_command('egg_info', egg_base=build_path) + self.run_command('egg_info') + + self.reinitialize_command('build_ext', inplace=0) + self.run_command('build_ext') + else: + # Without 2to3 inplace works fine: + self.run_command('egg_info') + + # Build extensions in-place + self.reinitialize_command('build_ext', inplace=1) + self.run_command('build_ext') + + ei_cmd = self.get_finalized_command("egg_info") + + old_path = sys.path[:] + old_modules = sys.modules.copy() + + try: + project_path = normalize_path(ei_cmd.egg_base) + sys.path.insert(0, project_path) + working_set.__init__() + add_activation_listener(lambda dist: dist.activate()) + require('%s==%s' % (ei_cmd.egg_name, ei_cmd.egg_version)) + with self.paths_on_pythonpath([project_path]): + yield + finally: + sys.path[:] = old_path + sys.modules.clear() + sys.modules.update(old_modules) + working_set.__init__() + + @staticmethod + @contextlib.contextmanager + def paths_on_pythonpath(paths): + """ + Add the indicated paths to the head of the PYTHONPATH environment + variable so that subprocesses will also see the packages at + these paths. + + Do this in a context that restores the value on exit. + """ + nothing = object() + orig_pythonpath = os.environ.get('PYTHONPATH', nothing) + current_pythonpath = os.environ.get('PYTHONPATH', '') + try: + prefix = os.pathsep.join(paths) + to_join = filter(None, [prefix, current_pythonpath]) + new_path = os.pathsep.join(to_join) + if new_path: + os.environ['PYTHONPATH'] = new_path + yield + finally: + if orig_pythonpath is nothing: + os.environ.pop('PYTHONPATH', None) + else: + os.environ['PYTHONPATH'] = orig_pythonpath + + @staticmethod + def install_dists(dist): + """ + Install the requirements indicated by self.distribution and + return an iterable of the dists that were built. + """ + ir_d = dist.fetch_build_eggs(dist.install_requires) + tr_d = dist.fetch_build_eggs(dist.tests_require or []) + er_d = dist.fetch_build_eggs( + v for k, v in dist.extras_require.items() + if k.startswith(':') and evaluate_marker(k[1:]) + ) + return itertools.chain(ir_d, tr_d, er_d) + + def run(self): + installed_dists = self.install_dists(self.distribution) + + cmd = ' '.join(self._argv) + if self.dry_run: + self.announce('skipping "%s" (dry run)' % cmd) + return + + self.announce('running "%s"' % cmd) + + paths = map(operator.attrgetter('location'), installed_dists) + with self.paths_on_pythonpath(paths): + with self.project_on_sys_path(): + self.run_tests() + + def run_tests(self): + # Purge modules under test from sys.modules. The test loader will + # re-import them from the build location. Required when 2to3 is used + # with namespace packages. + if six.PY3 and getattr(self.distribution, 'use_2to3', False): + module = self.test_suite.split('.')[0] + if module in _namespace_packages: + del_modules = [] + if module in sys.modules: + del_modules.append(module) + module += '.' + for name in sys.modules: + if name.startswith(module): + del_modules.append(name) + list(map(sys.modules.__delitem__, del_modules)) + + test = unittest.main( + None, None, self._argv, + testLoader=self._resolve_as_ep(self.test_loader), + testRunner=self._resolve_as_ep(self.test_runner), + exit=False, + ) + if not test.result.wasSuccessful(): + msg = 'Test failed: %s' % test.result + self.announce(msg, log.ERROR) + raise DistutilsError(msg) + + @property + def _argv(self): + return ['unittest'] + self.test_args + + @staticmethod + def _resolve_as_ep(val): + """ + Load the indicated attribute value, called, as a as if it were + specified as an entry point. + """ + if val is None: + return + parsed = EntryPoint.parse("x=" + val) + return parsed.resolve()() diff --git a/env/lib/python3.7/site-packages/setuptools/command/upload.py b/env/lib/python3.7/site-packages/setuptools/command/upload.py new file mode 100644 index 0000000..dd17f7a --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/upload.py @@ -0,0 +1,196 @@ +import io +import os +import hashlib +import getpass +import platform + +from base64 import standard_b64encode + +from distutils import log +from distutils.command import upload as orig +from distutils.spawn import spawn + +from distutils.errors import DistutilsError + +from setuptools.extern.six.moves.urllib.request import urlopen, Request +from setuptools.extern.six.moves.urllib.error import HTTPError +from setuptools.extern.six.moves.urllib.parse import urlparse + +class upload(orig.upload): + """ + Override default upload behavior to obtain password + in a variety of different ways. + """ + def run(self): + try: + orig.upload.run(self) + finally: + self.announce( + "WARNING: Uploading via this command is deprecated, use twine " + "to upload instead (https://pypi.org/p/twine/)", + log.WARN + ) + + def finalize_options(self): + orig.upload.finalize_options(self) + self.username = ( + self.username or + getpass.getuser() + ) + # Attempt to obtain password. Short circuit evaluation at the first + # sign of success. + self.password = ( + self.password or + self._load_password_from_keyring() or + self._prompt_for_password() + ) + + def upload_file(self, command, pyversion, filename): + # Makes sure the repository URL is compliant + schema, netloc, url, params, query, fragments = \ + urlparse(self.repository) + if params or query or fragments: + raise AssertionError("Incompatible url %s" % self.repository) + + if schema not in ('http', 'https'): + raise AssertionError("unsupported schema " + schema) + + # Sign if requested + if self.sign: + gpg_args = ["gpg", "--detach-sign", "-a", filename] + if self.identity: + gpg_args[2:2] = ["--local-user", self.identity] + spawn(gpg_args, + dry_run=self.dry_run) + + # Fill in the data - send all the meta-data in case we need to + # register a new release + with open(filename, 'rb') as f: + content = f.read() + + meta = self.distribution.metadata + + data = { + # action + ':action': 'file_upload', + 'protocol_version': '1', + + # identify release + 'name': meta.get_name(), + 'version': meta.get_version(), + + # file content + 'content': (os.path.basename(filename),content), + 'filetype': command, + 'pyversion': pyversion, + 'md5_digest': hashlib.md5(content).hexdigest(), + + # additional meta-data + 'metadata_version': str(meta.get_metadata_version()), + 'summary': meta.get_description(), + 'home_page': meta.get_url(), + 'author': meta.get_contact(), + 'author_email': meta.get_contact_email(), + 'license': meta.get_licence(), + 'description': meta.get_long_description(), + 'keywords': meta.get_keywords(), + 'platform': meta.get_platforms(), + 'classifiers': meta.get_classifiers(), + 'download_url': meta.get_download_url(), + # PEP 314 + 'provides': meta.get_provides(), + 'requires': meta.get_requires(), + 'obsoletes': meta.get_obsoletes(), + } + + data['comment'] = '' + + if self.sign: + data['gpg_signature'] = (os.path.basename(filename) + ".asc", + open(filename+".asc", "rb").read()) + + # set up the authentication + user_pass = (self.username + ":" + self.password).encode('ascii') + # The exact encoding of the authentication string is debated. + # Anyway PyPI only accepts ascii for both username or password. + auth = "Basic " + standard_b64encode(user_pass).decode('ascii') + + # Build up the MIME payload for the POST data + boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = b'\r\n--' + boundary.encode('ascii') + end_boundary = sep_boundary + b'--\r\n' + body = io.BytesIO() + for key, value in data.items(): + title = '\r\nContent-Disposition: form-data; name="%s"' % key + # handle multiple entries for the same name + if not isinstance(value, list): + value = [value] + for value in value: + if type(value) is tuple: + title += '; filename="%s"' % value[0] + value = value[1] + else: + value = str(value).encode('utf-8') + body.write(sep_boundary) + body.write(title.encode('utf-8')) + body.write(b"\r\n\r\n") + body.write(value) + body.write(end_boundary) + body = body.getvalue() + + msg = "Submitting %s to %s" % (filename, self.repository) + self.announce(msg, log.INFO) + + # build the Request + headers = { + 'Content-type': 'multipart/form-data; boundary=%s' % boundary, + 'Content-length': str(len(body)), + 'Authorization': auth, + } + + request = Request(self.repository, data=body, + headers=headers) + # send the data + try: + result = urlopen(request) + status = result.getcode() + reason = result.msg + except HTTPError as e: + status = e.code + reason = e.msg + except OSError as e: + self.announce(str(e), log.ERROR) + raise + + if status == 200: + self.announce('Server response (%s): %s' % (status, reason), + log.INFO) + if self.show_response: + text = getattr(self, '_read_pypi_response', + lambda x: None)(result) + if text is not None: + msg = '\n'.join(('-' * 75, text, '-' * 75)) + self.announce(msg, log.INFO) + else: + msg = 'Upload failed (%s): %s' % (status, reason) + self.announce(msg, log.ERROR) + raise DistutilsError(msg) + + def _load_password_from_keyring(self): + """ + Attempt to load password from keyring. Suppress Exceptions. + """ + try: + keyring = __import__('keyring') + return keyring.get_password(self.repository, self.username) + except Exception: + pass + + def _prompt_for_password(self): + """ + Prompt for a password on the tty. Suppress Exceptions. + """ + try: + return getpass.getpass() + except (Exception, KeyboardInterrupt): + pass diff --git a/env/lib/python3.7/site-packages/setuptools/command/upload_docs.py b/env/lib/python3.7/site-packages/setuptools/command/upload_docs.py new file mode 100644 index 0000000..07aa564 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/command/upload_docs.py @@ -0,0 +1,206 @@ +# -*- coding: utf-8 -*- +"""upload_docs + +Implements a Distutils 'upload_docs' subcommand (upload documentation to +PyPI's pythonhosted.org). +""" + +from base64 import standard_b64encode +from distutils import log +from distutils.errors import DistutilsOptionError +import os +import socket +import zipfile +import tempfile +import shutil +import itertools +import functools + +from setuptools.extern import six +from setuptools.extern.six.moves import http_client, urllib + +from pkg_resources import iter_entry_points +from .upload import upload + + +def _encode(s): + errors = 'surrogateescape' if six.PY3 else 'strict' + return s.encode('utf-8', errors) + + +class upload_docs(upload): + # override the default repository as upload_docs isn't + # supported by Warehouse (and won't be). + DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi/' + + description = 'Upload documentation to PyPI' + + user_options = [ + ('repository=', 'r', + "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY), + ('show-response', None, + 'display full response text from server'), + ('upload-dir=', None, 'directory to upload'), + ] + boolean_options = upload.boolean_options + + def has_sphinx(self): + if self.upload_dir is None: + for ep in iter_entry_points('distutils.commands', 'build_sphinx'): + return True + + sub_commands = [('build_sphinx', has_sphinx)] + + def initialize_options(self): + upload.initialize_options(self) + self.upload_dir = None + self.target_dir = None + + def finalize_options(self): + upload.finalize_options(self) + if self.upload_dir is None: + if self.has_sphinx(): + build_sphinx = self.get_finalized_command('build_sphinx') + self.target_dir = build_sphinx.builder_target_dir + else: + build = self.get_finalized_command('build') + self.target_dir = os.path.join(build.build_base, 'docs') + else: + self.ensure_dirname('upload_dir') + self.target_dir = self.upload_dir + if 'pypi.python.org' in self.repository: + log.warn("Upload_docs command is deprecated. Use RTD instead.") + self.announce('Using upload directory %s' % self.target_dir) + + def create_zipfile(self, filename): + zip_file = zipfile.ZipFile(filename, "w") + try: + self.mkpath(self.target_dir) # just in case + for root, dirs, files in os.walk(self.target_dir): + if root == self.target_dir and not files: + tmpl = "no files found in upload directory '%s'" + raise DistutilsOptionError(tmpl % self.target_dir) + for name in files: + full = os.path.join(root, name) + relative = root[len(self.target_dir):].lstrip(os.path.sep) + dest = os.path.join(relative, name) + zip_file.write(full, dest) + finally: + zip_file.close() + + def run(self): + # Run sub commands + for cmd_name in self.get_sub_commands(): + self.run_command(cmd_name) + + tmp_dir = tempfile.mkdtemp() + name = self.distribution.metadata.get_name() + zip_file = os.path.join(tmp_dir, "%s.zip" % name) + try: + self.create_zipfile(zip_file) + self.upload_file(zip_file) + finally: + shutil.rmtree(tmp_dir) + + @staticmethod + def _build_part(item, sep_boundary): + key, values = item + title = '\nContent-Disposition: form-data; name="%s"' % key + # handle multiple entries for the same name + if not isinstance(values, list): + values = [values] + for value in values: + if isinstance(value, tuple): + title += '; filename="%s"' % value[0] + value = value[1] + else: + value = _encode(value) + yield sep_boundary + yield _encode(title) + yield b"\n\n" + yield value + if value and value[-1:] == b'\r': + yield b'\n' # write an extra newline (lurve Macs) + + @classmethod + def _build_multipart(cls, data): + """ + Build up the MIME payload for the POST data + """ + boundary = b'--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' + sep_boundary = b'\n--' + boundary + end_boundary = sep_boundary + b'--' + end_items = end_boundary, b"\n", + builder = functools.partial( + cls._build_part, + sep_boundary=sep_boundary, + ) + part_groups = map(builder, data.items()) + parts = itertools.chain.from_iterable(part_groups) + body_items = itertools.chain(parts, end_items) + content_type = 'multipart/form-data; boundary=%s' % boundary.decode('ascii') + return b''.join(body_items), content_type + + def upload_file(self, filename): + with open(filename, 'rb') as f: + content = f.read() + meta = self.distribution.metadata + data = { + ':action': 'doc_upload', + 'name': meta.get_name(), + 'content': (os.path.basename(filename), content), + } + # set up the authentication + credentials = _encode(self.username + ':' + self.password) + credentials = standard_b64encode(credentials) + if six.PY3: + credentials = credentials.decode('ascii') + auth = "Basic " + credentials + + body, ct = self._build_multipart(data) + + msg = "Submitting documentation to %s" % (self.repository) + self.announce(msg, log.INFO) + + # build the Request + # We can't use urllib2 since we need to send the Basic + # auth right with the first request + schema, netloc, url, params, query, fragments = \ + urllib.parse.urlparse(self.repository) + assert not params and not query and not fragments + if schema == 'http': + conn = http_client.HTTPConnection(netloc) + elif schema == 'https': + conn = http_client.HTTPSConnection(netloc) + else: + raise AssertionError("unsupported schema " + schema) + + data = '' + try: + conn.connect() + conn.putrequest("POST", url) + content_type = ct + conn.putheader('Content-type', content_type) + conn.putheader('Content-length', str(len(body))) + conn.putheader('Authorization', auth) + conn.endheaders() + conn.send(body) + except socket.error as e: + self.announce(str(e), log.ERROR) + return + + r = conn.getresponse() + if r.status == 200: + msg = 'Server response (%s): %s' % (r.status, r.reason) + self.announce(msg, log.INFO) + elif r.status == 301: + location = r.getheader('Location') + if location is None: + location = 'https://pythonhosted.org/%s/' % meta.get_name() + msg = 'Upload successful. Visit %s' % location + self.announce(msg, log.INFO) + else: + msg = 'Upload failed (%s): %s' % (r.status, r.reason) + self.announce(msg, log.ERROR) + if self.show_response: + print('-' * 75, r.read(), '-' * 75) diff --git a/env/lib/python3.7/site-packages/setuptools/config.py b/env/lib/python3.7/site-packages/setuptools/config.py new file mode 100644 index 0000000..d1ac673 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/config.py @@ -0,0 +1,635 @@ +from __future__ import absolute_import, unicode_literals +import io +import os +import sys + +import warnings +import functools +from collections import defaultdict +from functools import partial +from functools import wraps +from importlib import import_module + +from distutils.errors import DistutilsOptionError, DistutilsFileError +from setuptools.extern.packaging.version import LegacyVersion, parse +from setuptools.extern.six import string_types, PY3 + + +__metaclass__ = type + + +def read_configuration( + filepath, find_others=False, ignore_option_errors=False): + """Read given configuration file and returns options from it as a dict. + + :param str|unicode filepath: Path to configuration file + to get options from. + + :param bool find_others: Whether to search for other configuration files + which could be on in various places. + + :param bool ignore_option_errors: Whether to silently ignore + options, values of which could not be resolved (e.g. due to exceptions + in directives such as file:, attr:, etc.). + If False exceptions are propagated as expected. + + :rtype: dict + """ + from setuptools.dist import Distribution, _Distribution + + filepath = os.path.abspath(filepath) + + if not os.path.isfile(filepath): + raise DistutilsFileError( + 'Configuration file %s does not exist.' % filepath) + + current_directory = os.getcwd() + os.chdir(os.path.dirname(filepath)) + + try: + dist = Distribution() + + filenames = dist.find_config_files() if find_others else [] + if filepath not in filenames: + filenames.append(filepath) + + _Distribution.parse_config_files(dist, filenames=filenames) + + handlers = parse_configuration( + dist, dist.command_options, + ignore_option_errors=ignore_option_errors) + + finally: + os.chdir(current_directory) + + return configuration_to_dict(handlers) + + +def _get_option(target_obj, key): + """ + Given a target object and option key, get that option from + the target object, either through a get_{key} method or + from an attribute directly. + """ + getter_name = 'get_{key}'.format(**locals()) + by_attribute = functools.partial(getattr, target_obj, key) + getter = getattr(target_obj, getter_name, by_attribute) + return getter() + + +def configuration_to_dict(handlers): + """Returns configuration data gathered by given handlers as a dict. + + :param list[ConfigHandler] handlers: Handlers list, + usually from parse_configuration() + + :rtype: dict + """ + config_dict = defaultdict(dict) + + for handler in handlers: + for option in handler.set_options: + value = _get_option(handler.target_obj, option) + config_dict[handler.section_prefix][option] = value + + return config_dict + + +def parse_configuration( + distribution, command_options, ignore_option_errors=False): + """Performs additional parsing of configuration options + for a distribution. + + Returns a list of used option handlers. + + :param Distribution distribution: + :param dict command_options: + :param bool ignore_option_errors: Whether to silently ignore + options, values of which could not be resolved (e.g. due to exceptions + in directives such as file:, attr:, etc.). + If False exceptions are propagated as expected. + :rtype: list + """ + options = ConfigOptionsHandler( + distribution, command_options, ignore_option_errors) + options.parse() + + meta = ConfigMetadataHandler( + distribution.metadata, command_options, ignore_option_errors, + distribution.package_dir) + meta.parse() + + return meta, options + + +class ConfigHandler: + """Handles metadata supplied in configuration files.""" + + section_prefix = None + """Prefix for config sections handled by this handler. + Must be provided by class heirs. + + """ + + aliases = {} + """Options aliases. + For compatibility with various packages. E.g.: d2to1 and pbr. + Note: `-` in keys is replaced with `_` by config parser. + + """ + + def __init__(self, target_obj, options, ignore_option_errors=False): + sections = {} + + section_prefix = self.section_prefix + for section_name, section_options in options.items(): + if not section_name.startswith(section_prefix): + continue + + section_name = section_name.replace(section_prefix, '').strip('.') + sections[section_name] = section_options + + self.ignore_option_errors = ignore_option_errors + self.target_obj = target_obj + self.sections = sections + self.set_options = [] + + @property + def parsers(self): + """Metadata item name to parser function mapping.""" + raise NotImplementedError( + '%s must provide .parsers property' % self.__class__.__name__) + + def __setitem__(self, option_name, value): + unknown = tuple() + target_obj = self.target_obj + + # Translate alias into real name. + option_name = self.aliases.get(option_name, option_name) + + current_value = getattr(target_obj, option_name, unknown) + + if current_value is unknown: + raise KeyError(option_name) + + if current_value: + # Already inhabited. Skipping. + return + + skip_option = False + parser = self.parsers.get(option_name) + if parser: + try: + value = parser(value) + + except Exception: + skip_option = True + if not self.ignore_option_errors: + raise + + if skip_option: + return + + setter = getattr(target_obj, 'set_%s' % option_name, None) + if setter is None: + setattr(target_obj, option_name, value) + else: + setter(value) + + self.set_options.append(option_name) + + @classmethod + def _parse_list(cls, value, separator=','): + """Represents value as a list. + + Value is split either by separator (defaults to comma) or by lines. + + :param value: + :param separator: List items separator character. + :rtype: list + """ + if isinstance(value, list): # _get_parser_compound case + return value + + if '\n' in value: + value = value.splitlines() + else: + value = value.split(separator) + + return [chunk.strip() for chunk in value if chunk.strip()] + + @classmethod + def _parse_dict(cls, value): + """Represents value as a dict. + + :param value: + :rtype: dict + """ + separator = '=' + result = {} + for line in cls._parse_list(value): + key, sep, val = line.partition(separator) + if sep != separator: + raise DistutilsOptionError( + 'Unable to parse option value to dict: %s' % value) + result[key.strip()] = val.strip() + + return result + + @classmethod + def _parse_bool(cls, value): + """Represents value as boolean. + + :param value: + :rtype: bool + """ + value = value.lower() + return value in ('1', 'true', 'yes') + + @classmethod + def _parse_file(cls, value): + """Represents value as a string, allowing including text + from nearest files using `file:` directive. + + Directive is sandboxed and won't reach anything outside + directory with setup.py. + + Examples: + file: LICENSE + file: README.rst, CHANGELOG.md, src/file.txt + + :param str value: + :rtype: str + """ + include_directive = 'file:' + + if not isinstance(value, string_types): + return value + + if not value.startswith(include_directive): + return value + + spec = value[len(include_directive):] + filepaths = (os.path.abspath(path.strip()) for path in spec.split(',')) + return '\n'.join( + cls._read_file(path) + for path in filepaths + if (cls._assert_local(path) or True) + and os.path.isfile(path) + ) + + @staticmethod + def _assert_local(filepath): + if not filepath.startswith(os.getcwd()): + raise DistutilsOptionError( + '`file:` directive can not access %s' % filepath) + + @staticmethod + def _read_file(filepath): + with io.open(filepath, encoding='utf-8') as f: + return f.read() + + @classmethod + def _parse_attr(cls, value, package_dir=None): + """Represents value as a module attribute. + + Examples: + attr: package.attr + attr: package.module.attr + + :param str value: + :rtype: str + """ + attr_directive = 'attr:' + if not value.startswith(attr_directive): + return value + + attrs_path = value.replace(attr_directive, '').strip().split('.') + attr_name = attrs_path.pop() + + module_name = '.'.join(attrs_path) + module_name = module_name or '__init__' + + parent_path = os.getcwd() + if package_dir: + if attrs_path[0] in package_dir: + # A custom path was specified for the module we want to import + custom_path = package_dir[attrs_path[0]] + parts = custom_path.rsplit('/', 1) + if len(parts) > 1: + parent_path = os.path.join(os.getcwd(), parts[0]) + module_name = parts[1] + else: + module_name = custom_path + elif '' in package_dir: + # A custom parent directory was specified for all root modules + parent_path = os.path.join(os.getcwd(), package_dir['']) + sys.path.insert(0, parent_path) + try: + module = import_module(module_name) + value = getattr(module, attr_name) + + finally: + sys.path = sys.path[1:] + + return value + + @classmethod + def _get_parser_compound(cls, *parse_methods): + """Returns parser function to represents value as a list. + + Parses a value applying given methods one after another. + + :param parse_methods: + :rtype: callable + """ + def parse(value): + parsed = value + + for method in parse_methods: + parsed = method(parsed) + + return parsed + + return parse + + @classmethod + def _parse_section_to_dict(cls, section_options, values_parser=None): + """Parses section options into a dictionary. + + Optionally applies a given parser to values. + + :param dict section_options: + :param callable values_parser: + :rtype: dict + """ + value = {} + values_parser = values_parser or (lambda val: val) + for key, (_, val) in section_options.items(): + value[key] = values_parser(val) + return value + + def parse_section(self, section_options): + """Parses configuration file section. + + :param dict section_options: + """ + for (name, (_, value)) in section_options.items(): + try: + self[name] = value + + except KeyError: + pass # Keep silent for a new option may appear anytime. + + def parse(self): + """Parses configuration file items from one + or more related sections. + + """ + for section_name, section_options in self.sections.items(): + + method_postfix = '' + if section_name: # [section.option] variant + method_postfix = '_%s' % section_name + + section_parser_method = getattr( + self, + # Dots in section names are tranlsated into dunderscores. + ('parse_section%s' % method_postfix).replace('.', '__'), + None) + + if section_parser_method is None: + raise DistutilsOptionError( + 'Unsupported distribution option section: [%s.%s]' % ( + self.section_prefix, section_name)) + + section_parser_method(section_options) + + def _deprecated_config_handler(self, func, msg, warning_class): + """ this function will wrap around parameters that are deprecated + + :param msg: deprecation message + :param warning_class: class of warning exception to be raised + :param func: function to be wrapped around + """ + @wraps(func) + def config_handler(*args, **kwargs): + warnings.warn(msg, warning_class) + return func(*args, **kwargs) + + return config_handler + + +class ConfigMetadataHandler(ConfigHandler): + + section_prefix = 'metadata' + + aliases = { + 'home_page': 'url', + 'summary': 'description', + 'classifier': 'classifiers', + 'platform': 'platforms', + } + + strict_mode = False + """We need to keep it loose, to be partially compatible with + `pbr` and `d2to1` packages which also uses `metadata` section. + + """ + + def __init__(self, target_obj, options, ignore_option_errors=False, + package_dir=None): + super(ConfigMetadataHandler, self).__init__(target_obj, options, + ignore_option_errors) + self.package_dir = package_dir + + @property + def parsers(self): + """Metadata item name to parser function mapping.""" + parse_list = self._parse_list + parse_file = self._parse_file + parse_dict = self._parse_dict + + return { + 'platforms': parse_list, + 'keywords': parse_list, + 'provides': parse_list, + 'requires': self._deprecated_config_handler(parse_list, + "The requires parameter is deprecated, please use " + + "install_requires for runtime dependencies.", + DeprecationWarning), + 'obsoletes': parse_list, + 'classifiers': self._get_parser_compound(parse_file, parse_list), + 'license': parse_file, + 'description': parse_file, + 'long_description': parse_file, + 'version': self._parse_version, + 'project_urls': parse_dict, + } + + def _parse_version(self, value): + """Parses `version` option value. + + :param value: + :rtype: str + + """ + version = self._parse_file(value) + + if version != value: + version = version.strip() + # Be strict about versions loaded from file because it's easy to + # accidentally include newlines and other unintended content + if isinstance(parse(version), LegacyVersion): + tmpl = ( + 'Version loaded from {value} does not ' + 'comply with PEP 440: {version}' + ) + raise DistutilsOptionError(tmpl.format(**locals())) + + return version + + version = self._parse_attr(value, self.package_dir) + + if callable(version): + version = version() + + if not isinstance(version, string_types): + if hasattr(version, '__iter__'): + version = '.'.join(map(str, version)) + else: + version = '%s' % version + + return version + + +class ConfigOptionsHandler(ConfigHandler): + + section_prefix = 'options' + + @property + def parsers(self): + """Metadata item name to parser function mapping.""" + parse_list = self._parse_list + parse_list_semicolon = partial(self._parse_list, separator=';') + parse_bool = self._parse_bool + parse_dict = self._parse_dict + + return { + 'zip_safe': parse_bool, + 'use_2to3': parse_bool, + 'include_package_data': parse_bool, + 'package_dir': parse_dict, + 'use_2to3_fixers': parse_list, + 'use_2to3_exclude_fixers': parse_list, + 'convert_2to3_doctests': parse_list, + 'scripts': parse_list, + 'eager_resources': parse_list, + 'dependency_links': parse_list, + 'namespace_packages': parse_list, + 'install_requires': parse_list_semicolon, + 'setup_requires': parse_list_semicolon, + 'tests_require': parse_list_semicolon, + 'packages': self._parse_packages, + 'entry_points': self._parse_file, + 'py_modules': parse_list, + } + + def _parse_packages(self, value): + """Parses `packages` option value. + + :param value: + :rtype: list + """ + find_directives = ['find:', 'find_namespace:'] + trimmed_value = value.strip() + + if trimmed_value not in find_directives: + return self._parse_list(value) + + findns = trimmed_value == find_directives[1] + if findns and not PY3: + raise DistutilsOptionError( + 'find_namespace: directive is unsupported on Python < 3.3') + + # Read function arguments from a dedicated section. + find_kwargs = self.parse_section_packages__find( + self.sections.get('packages.find', {})) + + if findns: + from setuptools import find_namespace_packages as find_packages + else: + from setuptools import find_packages + + return find_packages(**find_kwargs) + + def parse_section_packages__find(self, section_options): + """Parses `packages.find` configuration file section. + + To be used in conjunction with _parse_packages(). + + :param dict section_options: + """ + section_data = self._parse_section_to_dict( + section_options, self._parse_list) + + valid_keys = ['where', 'include', 'exclude'] + + find_kwargs = dict( + [(k, v) for k, v in section_data.items() if k in valid_keys and v]) + + where = find_kwargs.get('where') + if where is not None: + find_kwargs['where'] = where[0] # cast list to single val + + return find_kwargs + + def parse_section_entry_points(self, section_options): + """Parses `entry_points` configuration file section. + + :param dict section_options: + """ + parsed = self._parse_section_to_dict(section_options, self._parse_list) + self['entry_points'] = parsed + + def _parse_package_data(self, section_options): + parsed = self._parse_section_to_dict(section_options, self._parse_list) + + root = parsed.get('*') + if root: + parsed[''] = root + del parsed['*'] + + return parsed + + def parse_section_package_data(self, section_options): + """Parses `package_data` configuration file section. + + :param dict section_options: + """ + self['package_data'] = self._parse_package_data(section_options) + + def parse_section_exclude_package_data(self, section_options): + """Parses `exclude_package_data` configuration file section. + + :param dict section_options: + """ + self['exclude_package_data'] = self._parse_package_data( + section_options) + + def parse_section_extras_require(self, section_options): + """Parses `extras_require` configuration file section. + + :param dict section_options: + """ + parse_list = partial(self._parse_list, separator=';') + self['extras_require'] = self._parse_section_to_dict( + section_options, parse_list) + + def parse_section_data_files(self, section_options): + """Parses `data_files` configuration file section. + + :param dict section_options: + """ + parsed = self._parse_section_to_dict(section_options, self._parse_list) + self['data_files'] = [(k, v) for k, v in parsed.items()] diff --git a/env/lib/python3.7/site-packages/setuptools/dep_util.py b/env/lib/python3.7/site-packages/setuptools/dep_util.py new file mode 100644 index 0000000..2931c13 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/dep_util.py @@ -0,0 +1,23 @@ +from distutils.dep_util import newer_group + +# yes, this is was almost entirely copy-pasted from +# 'newer_pairwise()', this is just another convenience +# function. +def newer_pairwise_group(sources_groups, targets): + """Walk both arguments in parallel, testing if each source group is newer + than its corresponding target. Returns a pair of lists (sources_groups, + targets) where sources is newer than target, according to the semantics + of 'newer_group()'. + """ + if len(sources_groups) != len(targets): + raise ValueError("'sources_group' and 'targets' must be the same length") + + # build a pair of lists (sources_groups, targets) where source is newer + n_sources = [] + n_targets = [] + for i in range(len(sources_groups)): + if newer_group(sources_groups[i], targets[i]): + n_sources.append(sources_groups[i]) + n_targets.append(targets[i]) + + return n_sources, n_targets diff --git a/env/lib/python3.7/site-packages/setuptools/depends.py b/env/lib/python3.7/site-packages/setuptools/depends.py new file mode 100644 index 0000000..45e7052 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/depends.py @@ -0,0 +1,186 @@ +import sys +import imp +import marshal +from distutils.version import StrictVersion +from imp import PKG_DIRECTORY, PY_COMPILED, PY_SOURCE, PY_FROZEN + +from .py33compat import Bytecode + + +__all__ = [ + 'Require', 'find_module', 'get_module_constant', 'extract_constant' +] + + +class Require: + """A prerequisite to building or installing a distribution""" + + def __init__(self, name, requested_version, module, homepage='', + attribute=None, format=None): + + if format is None and requested_version is not None: + format = StrictVersion + + if format is not None: + requested_version = format(requested_version) + if attribute is None: + attribute = '__version__' + + self.__dict__.update(locals()) + del self.self + + def full_name(self): + """Return full package/distribution name, w/version""" + if self.requested_version is not None: + return '%s-%s' % (self.name, self.requested_version) + return self.name + + def version_ok(self, version): + """Is 'version' sufficiently up-to-date?""" + return self.attribute is None or self.format is None or \ + str(version) != "unknown" and version >= self.requested_version + + def get_version(self, paths=None, default="unknown"): + """Get version number of installed module, 'None', or 'default' + + Search 'paths' for module. If not found, return 'None'. If found, + return the extracted version attribute, or 'default' if no version + attribute was specified, or the value cannot be determined without + importing the module. The version is formatted according to the + requirement's version format (if any), unless it is 'None' or the + supplied 'default'. + """ + + if self.attribute is None: + try: + f, p, i = find_module(self.module, paths) + if f: + f.close() + return default + except ImportError: + return None + + v = get_module_constant(self.module, self.attribute, default, paths) + + if v is not None and v is not default and self.format is not None: + return self.format(v) + + return v + + def is_present(self, paths=None): + """Return true if dependency is present on 'paths'""" + return self.get_version(paths) is not None + + def is_current(self, paths=None): + """Return true if dependency is present and up-to-date on 'paths'""" + version = self.get_version(paths) + if version is None: + return False + return self.version_ok(version) + + +def find_module(module, paths=None): + """Just like 'imp.find_module()', but with package support""" + + parts = module.split('.') + + while parts: + part = parts.pop(0) + f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) + + if kind == PKG_DIRECTORY: + parts = parts or ['__init__'] + paths = [path] + + elif parts: + raise ImportError("Can't find %r in %s" % (parts, module)) + + return info + + +def get_module_constant(module, symbol, default=-1, paths=None): + """Find 'module' by searching 'paths', and extract 'symbol' + + Return 'None' if 'module' does not exist on 'paths', or it does not define + 'symbol'. If the module defines 'symbol' as a constant, return the + constant. Otherwise, return 'default'.""" + + try: + f, path, (suffix, mode, kind) = find_module(module, paths) + except ImportError: + # Module doesn't exist + return None + + try: + if kind == PY_COMPILED: + f.read(8) # skip magic & date + code = marshal.load(f) + elif kind == PY_FROZEN: + code = imp.get_frozen_object(module) + elif kind == PY_SOURCE: + code = compile(f.read(), path, 'exec') + else: + # Not something we can parse; we'll have to import it. :( + if module not in sys.modules: + imp.load_module(module, f, path, (suffix, mode, kind)) + return getattr(sys.modules[module], symbol, None) + + finally: + if f: + f.close() + + return extract_constant(code, symbol, default) + + +def extract_constant(code, symbol, default=-1): + """Extract the constant value of 'symbol' from 'code' + + If the name 'symbol' is bound to a constant value by the Python code + object 'code', return that value. If 'symbol' is bound to an expression, + return 'default'. Otherwise, return 'None'. + + Return value is based on the first assignment to 'symbol'. 'symbol' must + be a global, or at least a non-"fast" local in the code block. That is, + only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol' + must be present in 'code.co_names'. + """ + if symbol not in code.co_names: + # name's not there, can't possibly be an assignment + return None + + name_idx = list(code.co_names).index(symbol) + + STORE_NAME = 90 + STORE_GLOBAL = 97 + LOAD_CONST = 100 + + const = default + + for byte_code in Bytecode(code): + op = byte_code.opcode + arg = byte_code.arg + + if op == LOAD_CONST: + const = code.co_consts[arg] + elif arg == name_idx and (op == STORE_NAME or op == STORE_GLOBAL): + return const + else: + const = default + + +def _update_globals(): + """ + Patch the globals to remove the objects not available on some platforms. + + XXX it'd be better to test assertions about bytecode instead. + """ + + if not sys.platform.startswith('java') and sys.platform != 'cli': + return + incompatible = 'extract_constant', 'get_module_constant' + for name in incompatible: + del globals()[name] + __all__.remove(name) + + +_update_globals() diff --git a/env/lib/python3.7/site-packages/setuptools/dist.py b/env/lib/python3.7/site-packages/setuptools/dist.py new file mode 100644 index 0000000..7062ae8 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/dist.py @@ -0,0 +1,1147 @@ +# -*- coding: utf-8 -*- +__all__ = ['Distribution'] + +import re +import os +import warnings +import numbers +import distutils.log +import distutils.core +import distutils.cmd +import distutils.dist +import itertools + + +from collections import defaultdict +from email import message_from_file + +from distutils.errors import ( + DistutilsOptionError, DistutilsPlatformError, DistutilsSetupError, +) +from distutils.util import rfc822_escape +from distutils.version import StrictVersion + +from setuptools.extern import six +from setuptools.extern import packaging +from setuptools.extern.six.moves import map, filter, filterfalse + +from . import SetuptoolsDeprecationWarning + +from setuptools.depends import Require +from setuptools import windows_support +from setuptools.monkey import get_unpatched +from setuptools.config import parse_configuration +import pkg_resources +from .py36compat import Distribution_parse_config_files + +__import__('setuptools.extern.packaging.specifiers') +__import__('setuptools.extern.packaging.version') + + +def _get_unpatched(cls): + warnings.warn("Do not call this function", DistDeprecationWarning) + return get_unpatched(cls) + + +def get_metadata_version(self): + mv = getattr(self, 'metadata_version', None) + + if mv is None: + if self.long_description_content_type or self.provides_extras: + mv = StrictVersion('2.1') + elif (self.maintainer is not None or + self.maintainer_email is not None or + getattr(self, 'python_requires', None) is not None): + mv = StrictVersion('1.2') + elif (self.provides or self.requires or self.obsoletes or + self.classifiers or self.download_url): + mv = StrictVersion('1.1') + else: + mv = StrictVersion('1.0') + + self.metadata_version = mv + + return mv + + +def read_pkg_file(self, file): + """Reads the metadata values from a file object.""" + msg = message_from_file(file) + + def _read_field(name): + value = msg[name] + if value == 'UNKNOWN': + return None + return value + + def _read_list(name): + values = msg.get_all(name, None) + if values == []: + return None + return values + + self.metadata_version = StrictVersion(msg['metadata-version']) + self.name = _read_field('name') + self.version = _read_field('version') + self.description = _read_field('summary') + # we are filling author only. + self.author = _read_field('author') + self.maintainer = None + self.author_email = _read_field('author-email') + self.maintainer_email = None + self.url = _read_field('home-page') + self.license = _read_field('license') + + if 'download-url' in msg: + self.download_url = _read_field('download-url') + else: + self.download_url = None + + self.long_description = _read_field('description') + self.description = _read_field('summary') + + if 'keywords' in msg: + self.keywords = _read_field('keywords').split(',') + + self.platforms = _read_list('platform') + self.classifiers = _read_list('classifier') + + # PEP 314 - these fields only exist in 1.1 + if self.metadata_version == StrictVersion('1.1'): + self.requires = _read_list('requires') + self.provides = _read_list('provides') + self.obsoletes = _read_list('obsoletes') + else: + self.requires = None + self.provides = None + self.obsoletes = None + + +# Based on Python 3.5 version +def write_pkg_file(self, file): + """Write the PKG-INFO format data to a file object. + """ + version = self.get_metadata_version() + + if six.PY2: + def write_field(key, value): + file.write("%s: %s\n" % (key, self._encode_field(value))) + else: + def write_field(key, value): + file.write("%s: %s\n" % (key, value)) + + + write_field('Metadata-Version', str(version)) + write_field('Name', self.get_name()) + write_field('Version', self.get_version()) + write_field('Summary', self.get_description()) + write_field('Home-page', self.get_url()) + + if version < StrictVersion('1.2'): + write_field('Author', self.get_contact()) + write_field('Author-email', self.get_contact_email()) + else: + optional_fields = ( + ('Author', 'author'), + ('Author-email', 'author_email'), + ('Maintainer', 'maintainer'), + ('Maintainer-email', 'maintainer_email'), + ) + + for field, attr in optional_fields: + attr_val = getattr(self, attr) + + if attr_val is not None: + write_field(field, attr_val) + + write_field('License', self.get_license()) + if self.download_url: + write_field('Download-URL', self.download_url) + for project_url in self.project_urls.items(): + write_field('Project-URL', '%s, %s' % project_url) + + long_desc = rfc822_escape(self.get_long_description()) + write_field('Description', long_desc) + + keywords = ','.join(self.get_keywords()) + if keywords: + write_field('Keywords', keywords) + + if version >= StrictVersion('1.2'): + for platform in self.get_platforms(): + write_field('Platform', platform) + else: + self._write_list(file, 'Platform', self.get_platforms()) + + self._write_list(file, 'Classifier', self.get_classifiers()) + + # PEP 314 + self._write_list(file, 'Requires', self.get_requires()) + self._write_list(file, 'Provides', self.get_provides()) + self._write_list(file, 'Obsoletes', self.get_obsoletes()) + + # Setuptools specific for PEP 345 + if hasattr(self, 'python_requires'): + write_field('Requires-Python', self.python_requires) + + # PEP 566 + if self.long_description_content_type: + write_field( + 'Description-Content-Type', + self.long_description_content_type + ) + if self.provides_extras: + for extra in self.provides_extras: + write_field('Provides-Extra', extra) + + +sequence = tuple, list + + +def check_importable(dist, attr, value): + try: + ep = pkg_resources.EntryPoint.parse('x=' + value) + assert not ep.extras + except (TypeError, ValueError, AttributeError, AssertionError): + raise DistutilsSetupError( + "%r must be importable 'module:attrs' string (got %r)" + % (attr, value) + ) + + +def assert_string_list(dist, attr, value): + """Verify that value is a string list or None""" + try: + assert ''.join(value) != value + except (TypeError, ValueError, AttributeError, AssertionError): + raise DistutilsSetupError( + "%r must be a list of strings (got %r)" % (attr, value) + ) + + +def check_nsp(dist, attr, value): + """Verify that namespace packages are valid""" + ns_packages = value + assert_string_list(dist, attr, ns_packages) + for nsp in ns_packages: + if not dist.has_contents_for(nsp): + raise DistutilsSetupError( + "Distribution contains no modules or packages for " + + "namespace package %r" % nsp + ) + parent, sep, child = nsp.rpartition('.') + if parent and parent not in ns_packages: + distutils.log.warn( + "WARNING: %r is declared as a package namespace, but %r" + " is not: please correct this in setup.py", nsp, parent + ) + + +def check_extras(dist, attr, value): + """Verify that extras_require mapping is valid""" + try: + list(itertools.starmap(_check_extra, value.items())) + except (TypeError, ValueError, AttributeError): + raise DistutilsSetupError( + "'extras_require' must be a dictionary whose values are " + "strings or lists of strings containing valid project/version " + "requirement specifiers." + ) + + +def _check_extra(extra, reqs): + name, sep, marker = extra.partition(':') + if marker and pkg_resources.invalid_marker(marker): + raise DistutilsSetupError("Invalid environment marker: " + marker) + list(pkg_resources.parse_requirements(reqs)) + + +def assert_bool(dist, attr, value): + """Verify that value is True, False, 0, or 1""" + if bool(value) != value: + tmpl = "{attr!r} must be a boolean value (got {value!r})" + raise DistutilsSetupError(tmpl.format(attr=attr, value=value)) + + +def check_requirements(dist, attr, value): + """Verify that install_requires is a valid requirements list""" + try: + list(pkg_resources.parse_requirements(value)) + if isinstance(value, (dict, set)): + raise TypeError("Unordered types are not allowed") + except (TypeError, ValueError) as error: + tmpl = ( + "{attr!r} must be a string or list of strings " + "containing valid project/version requirement specifiers; {error}" + ) + raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) + + +def check_specifier(dist, attr, value): + """Verify that value is a valid version specifier""" + try: + packaging.specifiers.SpecifierSet(value) + except packaging.specifiers.InvalidSpecifier as error: + tmpl = ( + "{attr!r} must be a string " + "containing valid version specifiers; {error}" + ) + raise DistutilsSetupError(tmpl.format(attr=attr, error=error)) + + +def check_entry_points(dist, attr, value): + """Verify that entry_points map is parseable""" + try: + pkg_resources.EntryPoint.parse_map(value) + except ValueError as e: + raise DistutilsSetupError(e) + + +def check_test_suite(dist, attr, value): + if not isinstance(value, six.string_types): + raise DistutilsSetupError("test_suite must be a string") + + +def check_package_data(dist, attr, value): + """Verify that value is a dictionary of package names to glob lists""" + if isinstance(value, dict): + for k, v in value.items(): + if not isinstance(k, str): + break + try: + iter(v) + except TypeError: + break + else: + return + raise DistutilsSetupError( + attr + " must be a dictionary mapping package names to lists of " + "wildcard patterns" + ) + + +def check_packages(dist, attr, value): + for pkgname in value: + if not re.match(r'\w+(\.\w+)*', pkgname): + distutils.log.warn( + "WARNING: %r not a valid package name; please use only " + ".-separated package names in setup.py", pkgname + ) + + +_Distribution = get_unpatched(distutils.core.Distribution) + + +class Distribution(Distribution_parse_config_files, _Distribution): + """Distribution with support for features, tests, and package data + + This is an enhanced version of 'distutils.dist.Distribution' that + effectively adds the following new optional keyword arguments to 'setup()': + + 'install_requires' -- a string or sequence of strings specifying project + versions that the distribution requires when installed, in the format + used by 'pkg_resources.require()'. They will be installed + automatically when the package is installed. If you wish to use + packages that are not available in PyPI, or want to give your users an + alternate download location, you can add a 'find_links' option to the + '[easy_install]' section of your project's 'setup.cfg' file, and then + setuptools will scan the listed web pages for links that satisfy the + requirements. + + 'extras_require' -- a dictionary mapping names of optional "extras" to the + additional requirement(s) that using those extras incurs. For example, + this:: + + extras_require = dict(reST = ["docutils>=0.3", "reSTedit"]) + + indicates that the distribution can optionally provide an extra + capability called "reST", but it can only be used if docutils and + reSTedit are installed. If the user installs your package using + EasyInstall and requests one of your extras, the corresponding + additional requirements will be installed if needed. + + 'features' **deprecated** -- a dictionary mapping option names to + 'setuptools.Feature' + objects. Features are a portion of the distribution that can be + included or excluded based on user options, inter-feature dependencies, + and availability on the current system. Excluded features are omitted + from all setup commands, including source and binary distributions, so + you can create multiple distributions from the same source tree. + Feature names should be valid Python identifiers, except that they may + contain the '-' (minus) sign. Features can be included or excluded + via the command line options '--with-X' and '--without-X', where 'X' is + the name of the feature. Whether a feature is included by default, and + whether you are allowed to control this from the command line, is + determined by the Feature object. See the 'Feature' class for more + information. + + 'test_suite' -- the name of a test suite to run for the 'test' command. + If the user runs 'python setup.py test', the package will be installed, + and the named test suite will be run. The format is the same as + would be used on a 'unittest.py' command line. That is, it is the + dotted name of an object to import and call to generate a test suite. + + 'package_data' -- a dictionary mapping package names to lists of filenames + or globs to use to find data files contained in the named packages. + If the dictionary has filenames or globs listed under '""' (the empty + string), those names will be searched for in every package, in addition + to any names for the specific package. Data files found using these + names/globs will be installed along with the package, in the same + location as the package. Note that globs are allowed to reference + the contents of non-package subdirectories, as long as you use '/' as + a path separator. (Globs are automatically converted to + platform-specific paths at runtime.) + + In addition to these new keywords, this class also has several new methods + for manipulating the distribution's contents. For example, the 'include()' + and 'exclude()' methods can be thought of as in-place add and subtract + commands that add or remove packages, modules, extensions, and so on from + the distribution. They are used by the feature subsystem to configure the + distribution for the included and excluded features. + """ + + _DISTUTILS_UNSUPPORTED_METADATA = { + 'long_description_content_type': None, + 'project_urls': dict, + 'provides_extras': set, + } + + _patched_dist = None + + def patch_missing_pkg_info(self, attrs): + # Fake up a replacement for the data that would normally come from + # PKG-INFO, but which might not yet be built if this is a fresh + # checkout. + # + if not attrs or 'name' not in attrs or 'version' not in attrs: + return + key = pkg_resources.safe_name(str(attrs['name'])).lower() + dist = pkg_resources.working_set.by_key.get(key) + if dist is not None and not dist.has_metadata('PKG-INFO'): + dist._version = pkg_resources.safe_version(str(attrs['version'])) + self._patched_dist = dist + + def __init__(self, attrs=None): + have_package_data = hasattr(self, "package_data") + if not have_package_data: + self.package_data = {} + attrs = attrs or {} + if 'features' in attrs or 'require_features' in attrs: + Feature.warn_deprecated() + self.require_features = [] + self.features = {} + self.dist_files = [] + # Filter-out setuptools' specific options. + self.src_root = attrs.pop("src_root", None) + self.patch_missing_pkg_info(attrs) + self.dependency_links = attrs.pop('dependency_links', []) + self.setup_requires = attrs.pop('setup_requires', []) + for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'): + vars(self).setdefault(ep.name, None) + _Distribution.__init__(self, { + k: v for k, v in attrs.items() + if k not in self._DISTUTILS_UNSUPPORTED_METADATA + }) + + # Fill-in missing metadata fields not supported by distutils. + # Note some fields may have been set by other tools (e.g. pbr) + # above; they are taken preferrentially to setup() arguments + for option, default in self._DISTUTILS_UNSUPPORTED_METADATA.items(): + for source in self.metadata.__dict__, attrs: + if option in source: + value = source[option] + break + else: + value = default() if default else None + setattr(self.metadata, option, value) + + if isinstance(self.metadata.version, numbers.Number): + # Some people apparently take "version number" too literally :) + self.metadata.version = str(self.metadata.version) + + if self.metadata.version is not None: + try: + ver = packaging.version.Version(self.metadata.version) + normalized_version = str(ver) + if self.metadata.version != normalized_version: + warnings.warn( + "Normalizing '%s' to '%s'" % ( + self.metadata.version, + normalized_version, + ) + ) + self.metadata.version = normalized_version + except (packaging.version.InvalidVersion, TypeError): + warnings.warn( + "The version specified (%r) is an invalid version, this " + "may not work as expected with newer versions of " + "setuptools, pip, and PyPI. Please see PEP 440 for more " + "details." % self.metadata.version + ) + self._finalize_requires() + + def _finalize_requires(self): + """ + Set `metadata.python_requires` and fix environment markers + in `install_requires` and `extras_require`. + """ + if getattr(self, 'python_requires', None): + self.metadata.python_requires = self.python_requires + + if getattr(self, 'extras_require', None): + for extra in self.extras_require.keys(): + # Since this gets called multiple times at points where the + # keys have become 'converted' extras, ensure that we are only + # truly adding extras we haven't seen before here. + extra = extra.split(':')[0] + if extra: + self.metadata.provides_extras.add(extra) + + self._convert_extras_requirements() + self._move_install_requirements_markers() + + def _convert_extras_requirements(self): + """ + Convert requirements in `extras_require` of the form + `"extra": ["barbazquux; {marker}"]` to + `"extra:{marker}": ["barbazquux"]`. + """ + spec_ext_reqs = getattr(self, 'extras_require', None) or {} + self._tmp_extras_require = defaultdict(list) + for section, v in spec_ext_reqs.items(): + # Do not strip empty sections. + self._tmp_extras_require[section] + for r in pkg_resources.parse_requirements(v): + suffix = self._suffix_for(r) + self._tmp_extras_require[section + suffix].append(r) + + @staticmethod + def _suffix_for(req): + """ + For a requirement, return the 'extras_require' suffix for + that requirement. + """ + return ':' + str(req.marker) if req.marker else '' + + def _move_install_requirements_markers(self): + """ + Move requirements in `install_requires` that are using environment + markers `extras_require`. + """ + + # divide the install_requires into two sets, simple ones still + # handled by install_requires and more complex ones handled + # by extras_require. + + def is_simple_req(req): + return not req.marker + + spec_inst_reqs = getattr(self, 'install_requires', None) or () + inst_reqs = list(pkg_resources.parse_requirements(spec_inst_reqs)) + simple_reqs = filter(is_simple_req, inst_reqs) + complex_reqs = filterfalse(is_simple_req, inst_reqs) + self.install_requires = list(map(str, simple_reqs)) + + for r in complex_reqs: + self._tmp_extras_require[':' + str(r.marker)].append(r) + self.extras_require = dict( + (k, [str(r) for r in map(self._clean_req, v)]) + for k, v in self._tmp_extras_require.items() + ) + + def _clean_req(self, req): + """ + Given a Requirement, remove environment markers and return it. + """ + req.marker = None + return req + + def parse_config_files(self, filenames=None, ignore_option_errors=False): + """Parses configuration files from various levels + and loads configuration. + + """ + _Distribution.parse_config_files(self, filenames=filenames) + + parse_configuration(self, self.command_options, + ignore_option_errors=ignore_option_errors) + self._finalize_requires() + + def parse_command_line(self): + """Process features after parsing command line options""" + result = _Distribution.parse_command_line(self) + if self.features: + self._finalize_features() + return result + + def _feature_attrname(self, name): + """Convert feature name to corresponding option attribute name""" + return 'with_' + name.replace('-', '_') + + def fetch_build_eggs(self, requires): + """Resolve pre-setup requirements""" + resolved_dists = pkg_resources.working_set.resolve( + pkg_resources.parse_requirements(requires), + installer=self.fetch_build_egg, + replace_conflicting=True, + ) + for dist in resolved_dists: + pkg_resources.working_set.add(dist, replace=True) + return resolved_dists + + def finalize_options(self): + _Distribution.finalize_options(self) + if self.features: + self._set_global_opts_from_features() + + for ep in pkg_resources.iter_entry_points('distutils.setup_keywords'): + value = getattr(self, ep.name, None) + if value is not None: + ep.require(installer=self.fetch_build_egg) + ep.load()(self, ep.name, value) + if getattr(self, 'convert_2to3_doctests', None): + # XXX may convert to set here when we can rely on set being builtin + self.convert_2to3_doctests = [ + os.path.abspath(p) + for p in self.convert_2to3_doctests + ] + else: + self.convert_2to3_doctests = [] + + def get_egg_cache_dir(self): + egg_cache_dir = os.path.join(os.curdir, '.eggs') + if not os.path.exists(egg_cache_dir): + os.mkdir(egg_cache_dir) + windows_support.hide_file(egg_cache_dir) + readme_txt_filename = os.path.join(egg_cache_dir, 'README.txt') + with open(readme_txt_filename, 'w') as f: + f.write('This directory contains eggs that were downloaded ' + 'by setuptools to build, test, and run plug-ins.\n\n') + f.write('This directory caches those eggs to prevent ' + 'repeated downloads.\n\n') + f.write('However, it is safe to delete this directory.\n\n') + + return egg_cache_dir + + def fetch_build_egg(self, req): + """Fetch an egg needed for building""" + from setuptools.command.easy_install import easy_install + dist = self.__class__({'script_args': ['easy_install']}) + opts = dist.get_option_dict('easy_install') + opts.clear() + opts.update( + (k, v) + for k, v in self.get_option_dict('easy_install').items() + if k in ( + # don't use any other settings + 'find_links', 'site_dirs', 'index_url', + 'optimize', 'site_dirs', 'allow_hosts', + )) + if self.dependency_links: + links = self.dependency_links[:] + if 'find_links' in opts: + links = opts['find_links'][1] + links + opts['find_links'] = ('setup', links) + install_dir = self.get_egg_cache_dir() + cmd = easy_install( + dist, args=["x"], install_dir=install_dir, + exclude_scripts=True, + always_copy=False, build_directory=None, editable=False, + upgrade=False, multi_version=True, no_report=True, user=False + ) + cmd.ensure_finalized() + return cmd.easy_install(req) + + def _set_global_opts_from_features(self): + """Add --with-X/--without-X options based on optional features""" + + go = [] + no = self.negative_opt.copy() + + for name, feature in self.features.items(): + self._set_feature(name, None) + feature.validate(self) + + if feature.optional: + descr = feature.description + incdef = ' (default)' + excdef = '' + if not feature.include_by_default(): + excdef, incdef = incdef, excdef + + new = ( + ('with-' + name, None, 'include ' + descr + incdef), + ('without-' + name, None, 'exclude ' + descr + excdef), + ) + go.extend(new) + no['without-' + name] = 'with-' + name + + self.global_options = self.feature_options = go + self.global_options + self.negative_opt = self.feature_negopt = no + + def _finalize_features(self): + """Add/remove features and resolve dependencies between them""" + + # First, flag all the enabled items (and thus their dependencies) + for name, feature in self.features.items(): + enabled = self.feature_is_included(name) + if enabled or (enabled is None and feature.include_by_default()): + feature.include_in(self) + self._set_feature(name, 1) + + # Then disable the rest, so that off-by-default features don't + # get flagged as errors when they're required by an enabled feature + for name, feature in self.features.items(): + if not self.feature_is_included(name): + feature.exclude_from(self) + self._set_feature(name, 0) + + def get_command_class(self, command): + """Pluggable version of get_command_class()""" + if command in self.cmdclass: + return self.cmdclass[command] + + eps = pkg_resources.iter_entry_points('distutils.commands', command) + for ep in eps: + ep.require(installer=self.fetch_build_egg) + self.cmdclass[command] = cmdclass = ep.load() + return cmdclass + else: + return _Distribution.get_command_class(self, command) + + def print_commands(self): + for ep in pkg_resources.iter_entry_points('distutils.commands'): + if ep.name not in self.cmdclass: + # don't require extras as the commands won't be invoked + cmdclass = ep.resolve() + self.cmdclass[ep.name] = cmdclass + return _Distribution.print_commands(self) + + def get_command_list(self): + for ep in pkg_resources.iter_entry_points('distutils.commands'): + if ep.name not in self.cmdclass: + # don't require extras as the commands won't be invoked + cmdclass = ep.resolve() + self.cmdclass[ep.name] = cmdclass + return _Distribution.get_command_list(self) + + def _set_feature(self, name, status): + """Set feature's inclusion status""" + setattr(self, self._feature_attrname(name), status) + + def feature_is_included(self, name): + """Return 1 if feature is included, 0 if excluded, 'None' if unknown""" + return getattr(self, self._feature_attrname(name)) + + def include_feature(self, name): + """Request inclusion of feature named 'name'""" + + if self.feature_is_included(name) == 0: + descr = self.features[name].description + raise DistutilsOptionError( + descr + " is required, but was excluded or is not available" + ) + self.features[name].include_in(self) + self._set_feature(name, 1) + + def include(self, **attrs): + """Add items to distribution that are named in keyword arguments + + For example, 'dist.exclude(py_modules=["x"])' would add 'x' to + the distribution's 'py_modules' attribute, if it was not already + there. + + Currently, this method only supports inclusion for attributes that are + lists or tuples. If you need to add support for adding to other + attributes in this or a subclass, you can add an '_include_X' method, + where 'X' is the name of the attribute. The method will be called with + the value passed to 'include()'. So, 'dist.include(foo={"bar":"baz"})' + will try to call 'dist._include_foo({"bar":"baz"})', which can then + handle whatever special inclusion logic is needed. + """ + for k, v in attrs.items(): + include = getattr(self, '_include_' + k, None) + if include: + include(v) + else: + self._include_misc(k, v) + + def exclude_package(self, package): + """Remove packages, modules, and extensions in named package""" + + pfx = package + '.' + if self.packages: + self.packages = [ + p for p in self.packages + if p != package and not p.startswith(pfx) + ] + + if self.py_modules: + self.py_modules = [ + p for p in self.py_modules + if p != package and not p.startswith(pfx) + ] + + if self.ext_modules: + self.ext_modules = [ + p for p in self.ext_modules + if p.name != package and not p.name.startswith(pfx) + ] + + def has_contents_for(self, package): + """Return true if 'exclude_package(package)' would do something""" + + pfx = package + '.' + + for p in self.iter_distribution_names(): + if p == package or p.startswith(pfx): + return True + + def _exclude_misc(self, name, value): + """Handle 'exclude()' for list/tuple attrs without a special handler""" + if not isinstance(value, sequence): + raise DistutilsSetupError( + "%s: setting must be a list or tuple (%r)" % (name, value) + ) + try: + old = getattr(self, name) + except AttributeError: + raise DistutilsSetupError( + "%s: No such distribution setting" % name + ) + if old is not None and not isinstance(old, sequence): + raise DistutilsSetupError( + name + ": this setting cannot be changed via include/exclude" + ) + elif old: + setattr(self, name, [item for item in old if item not in value]) + + def _include_misc(self, name, value): + """Handle 'include()' for list/tuple attrs without a special handler""" + + if not isinstance(value, sequence): + raise DistutilsSetupError( + "%s: setting must be a list (%r)" % (name, value) + ) + try: + old = getattr(self, name) + except AttributeError: + raise DistutilsSetupError( + "%s: No such distribution setting" % name + ) + if old is None: + setattr(self, name, value) + elif not isinstance(old, sequence): + raise DistutilsSetupError( + name + ": this setting cannot be changed via include/exclude" + ) + else: + new = [item for item in value if item not in old] + setattr(self, name, old + new) + + def exclude(self, **attrs): + """Remove items from distribution that are named in keyword arguments + + For example, 'dist.exclude(py_modules=["x"])' would remove 'x' from + the distribution's 'py_modules' attribute. Excluding packages uses + the 'exclude_package()' method, so all of the package's contained + packages, modules, and extensions are also excluded. + + Currently, this method only supports exclusion from attributes that are + lists or tuples. If you need to add support for excluding from other + attributes in this or a subclass, you can add an '_exclude_X' method, + where 'X' is the name of the attribute. The method will be called with + the value passed to 'exclude()'. So, 'dist.exclude(foo={"bar":"baz"})' + will try to call 'dist._exclude_foo({"bar":"baz"})', which can then + handle whatever special exclusion logic is needed. + """ + for k, v in attrs.items(): + exclude = getattr(self, '_exclude_' + k, None) + if exclude: + exclude(v) + else: + self._exclude_misc(k, v) + + def _exclude_packages(self, packages): + if not isinstance(packages, sequence): + raise DistutilsSetupError( + "packages: setting must be a list or tuple (%r)" % (packages,) + ) + list(map(self.exclude_package, packages)) + + def _parse_command_opts(self, parser, args): + # Remove --with-X/--without-X options when processing command args + self.global_options = self.__class__.global_options + self.negative_opt = self.__class__.negative_opt + + # First, expand any aliases + command = args[0] + aliases = self.get_option_dict('aliases') + while command in aliases: + src, alias = aliases[command] + del aliases[command] # ensure each alias can expand only once! + import shlex + args[:1] = shlex.split(alias, True) + command = args[0] + + nargs = _Distribution._parse_command_opts(self, parser, args) + + # Handle commands that want to consume all remaining arguments + cmd_class = self.get_command_class(command) + if getattr(cmd_class, 'command_consumes_arguments', None): + self.get_option_dict(command)['args'] = ("command line", nargs) + if nargs is not None: + return [] + + return nargs + + def get_cmdline_options(self): + """Return a '{cmd: {opt:val}}' map of all command-line options + + Option names are all long, but do not include the leading '--', and + contain dashes rather than underscores. If the option doesn't take + an argument (e.g. '--quiet'), the 'val' is 'None'. + + Note that options provided by config files are intentionally excluded. + """ + + d = {} + + for cmd, opts in self.command_options.items(): + + for opt, (src, val) in opts.items(): + + if src != "command line": + continue + + opt = opt.replace('_', '-') + + if val == 0: + cmdobj = self.get_command_obj(cmd) + neg_opt = self.negative_opt.copy() + neg_opt.update(getattr(cmdobj, 'negative_opt', {})) + for neg, pos in neg_opt.items(): + if pos == opt: + opt = neg + val = None + break + else: + raise AssertionError("Shouldn't be able to get here") + + elif val == 1: + val = None + + d.setdefault(cmd, {})[opt] = val + + return d + + def iter_distribution_names(self): + """Yield all packages, modules, and extension names in distribution""" + + for pkg in self.packages or (): + yield pkg + + for module in self.py_modules or (): + yield module + + for ext in self.ext_modules or (): + if isinstance(ext, tuple): + name, buildinfo = ext + else: + name = ext.name + if name.endswith('module'): + name = name[:-6] + yield name + + def handle_display_options(self, option_order): + """If there were any non-global "display-only" options + (--help-commands or the metadata display options) on the command + line, display the requested info and return true; else return + false. + """ + import sys + + if six.PY2 or self.help_commands: + return _Distribution.handle_display_options(self, option_order) + + # Stdout may be StringIO (e.g. in tests) + import io + if not isinstance(sys.stdout, io.TextIOWrapper): + return _Distribution.handle_display_options(self, option_order) + + # Don't wrap stdout if utf-8 is already the encoding. Provides + # workaround for #334. + if sys.stdout.encoding.lower() in ('utf-8', 'utf8'): + return _Distribution.handle_display_options(self, option_order) + + # Print metadata in UTF-8 no matter the platform + encoding = sys.stdout.encoding + errors = sys.stdout.errors + newline = sys.platform != 'win32' and '\n' or None + line_buffering = sys.stdout.line_buffering + + sys.stdout = io.TextIOWrapper( + sys.stdout.detach(), 'utf-8', errors, newline, line_buffering) + try: + return _Distribution.handle_display_options(self, option_order) + finally: + sys.stdout = io.TextIOWrapper( + sys.stdout.detach(), encoding, errors, newline, line_buffering) + + +class Feature: + """ + **deprecated** -- The `Feature` facility was never completely implemented + or supported, `has reported issues + <https://github.com/pypa/setuptools/issues/58>`_ and will be removed in + a future version. + + A subset of the distribution that can be excluded if unneeded/wanted + + Features are created using these keyword arguments: + + 'description' -- a short, human readable description of the feature, to + be used in error messages, and option help messages. + + 'standard' -- if true, the feature is included by default if it is + available on the current system. Otherwise, the feature is only + included if requested via a command line '--with-X' option, or if + another included feature requires it. The default setting is 'False'. + + 'available' -- if true, the feature is available for installation on the + current system. The default setting is 'True'. + + 'optional' -- if true, the feature's inclusion can be controlled from the + command line, using the '--with-X' or '--without-X' options. If + false, the feature's inclusion status is determined automatically, + based on 'availabile', 'standard', and whether any other feature + requires it. The default setting is 'True'. + + 'require_features' -- a string or sequence of strings naming features + that should also be included if this feature is included. Defaults to + empty list. May also contain 'Require' objects that should be + added/removed from the distribution. + + 'remove' -- a string or list of strings naming packages to be removed + from the distribution if this feature is *not* included. If the + feature *is* included, this argument is ignored. This argument exists + to support removing features that "crosscut" a distribution, such as + defining a 'tests' feature that removes all the 'tests' subpackages + provided by other features. The default for this argument is an empty + list. (Note: the named package(s) or modules must exist in the base + distribution when the 'setup()' function is initially called.) + + other keywords -- any other keyword arguments are saved, and passed to + the distribution's 'include()' and 'exclude()' methods when the + feature is included or excluded, respectively. So, for example, you + could pass 'packages=["a","b"]' to cause packages 'a' and 'b' to be + added or removed from the distribution as appropriate. + + A feature must include at least one 'requires', 'remove', or other + keyword argument. Otherwise, it can't affect the distribution in any way. + Note also that you can subclass 'Feature' to create your own specialized + feature types that modify the distribution in other ways when included or + excluded. See the docstrings for the various methods here for more detail. + Aside from the methods, the only feature attributes that distributions look + at are 'description' and 'optional'. + """ + + @staticmethod + def warn_deprecated(): + msg = ( + "Features are deprecated and will be removed in a future " + "version. See https://github.com/pypa/setuptools/issues/65." + ) + warnings.warn(msg, DistDeprecationWarning, stacklevel=3) + + def __init__( + self, description, standard=False, available=True, + optional=True, require_features=(), remove=(), **extras): + self.warn_deprecated() + + self.description = description + self.standard = standard + self.available = available + self.optional = optional + if isinstance(require_features, (str, Require)): + require_features = require_features, + + self.require_features = [ + r for r in require_features if isinstance(r, str) + ] + er = [r for r in require_features if not isinstance(r, str)] + if er: + extras['require_features'] = er + + if isinstance(remove, str): + remove = remove, + self.remove = remove + self.extras = extras + + if not remove and not require_features and not extras: + raise DistutilsSetupError( + "Feature %s: must define 'require_features', 'remove', or " + "at least one of 'packages', 'py_modules', etc." + ) + + def include_by_default(self): + """Should this feature be included by default?""" + return self.available and self.standard + + def include_in(self, dist): + """Ensure feature and its requirements are included in distribution + + You may override this in a subclass to perform additional operations on + the distribution. Note that this method may be called more than once + per feature, and so should be idempotent. + + """ + + if not self.available: + raise DistutilsPlatformError( + self.description + " is required, " + "but is not available on this platform" + ) + + dist.include(**self.extras) + + for f in self.require_features: + dist.include_feature(f) + + def exclude_from(self, dist): + """Ensure feature is excluded from distribution + + You may override this in a subclass to perform additional operations on + the distribution. This method will be called at most once per + feature, and only after all included features have been asked to + include themselves. + """ + + dist.exclude(**self.extras) + + if self.remove: + for item in self.remove: + dist.exclude_package(item) + + def validate(self, dist): + """Verify that feature makes sense in context of distribution + + This method is called by the distribution just before it parses its + command line. It checks to ensure that the 'remove' attribute, if any, + contains only valid package/module names that are present in the base + distribution when 'setup()' is called. You may override it in a + subclass to perform any other required validation of the feature + against a target distribution. + """ + + for item in self.remove: + if not dist.has_contents_for(item): + raise DistutilsSetupError( + "%s wants to be able to remove %s, but the distribution" + " doesn't contain any packages or modules under %s" + % (self.description, item, item) + ) + + +class DistDeprecationWarning(SetuptoolsDeprecationWarning): + """Class for warning about deprecations in dist in setuptools. Not ignored by default, unlike DeprecationWarning.""" diff --git a/env/lib/python3.7/site-packages/setuptools/extension.py b/env/lib/python3.7/site-packages/setuptools/extension.py new file mode 100644 index 0000000..2946889 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/extension.py @@ -0,0 +1,57 @@ +import re +import functools +import distutils.core +import distutils.errors +import distutils.extension + +from setuptools.extern.six.moves import map + +from .monkey import get_unpatched + + +def _have_cython(): + """ + Return True if Cython can be imported. + """ + cython_impl = 'Cython.Distutils.build_ext' + try: + # from (cython_impl) import build_ext + __import__(cython_impl, fromlist=['build_ext']).build_ext + return True + except Exception: + pass + return False + + +# for compatibility +have_pyrex = _have_cython + +_Extension = get_unpatched(distutils.core.Extension) + + +class Extension(_Extension): + """Extension that uses '.c' files in place of '.pyx' files""" + + def __init__(self, name, sources, *args, **kw): + # The *args is needed for compatibility as calls may use positional + # arguments. py_limited_api may be set only via keyword. + self.py_limited_api = kw.pop("py_limited_api", False) + _Extension.__init__(self, name, sources, *args, **kw) + + def _convert_pyx_sources_to_lang(self): + """ + Replace sources with .pyx extensions to sources with the target + language extension. This mechanism allows language authors to supply + pre-converted sources but to prefer the .pyx sources. + """ + if _have_cython(): + # the build has Cython, so allow it to compile the .pyx files + return + lang = self.language or '' + target_ext = '.cpp' if lang.lower() == 'c++' else '.c' + sub = functools.partial(re.sub, '.pyx$', target_ext) + self.sources = list(map(sub, self.sources)) + + +class Library(Extension): + """Just like a regular Extension, but built as a library instead""" diff --git a/env/lib/python3.7/site-packages/setuptools/extern/__init__.py b/env/lib/python3.7/site-packages/setuptools/extern/__init__.py new file mode 100644 index 0000000..cb2fa32 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/extern/__init__.py @@ -0,0 +1,73 @@ +import sys + + +class VendorImporter: + """ + A PEP 302 meta path importer for finding optionally-vendored + or otherwise naturally-installed packages from root_name. + """ + + def __init__(self, root_name, vendored_names=(), vendor_pkg=None): + self.root_name = root_name + self.vendored_names = set(vendored_names) + self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') + + @property + def search_path(self): + """ + Search first the vendor package then as a natural package. + """ + yield self.vendor_pkg + '.' + yield '' + + def find_module(self, fullname, path=None): + """ + Return self when fullname starts with root_name and the + target module is one vendored through this importer. + """ + root, base, target = fullname.partition(self.root_name + '.') + if root: + return + if not any(map(target.startswith, self.vendored_names)): + return + return self + + def load_module(self, fullname): + """ + Iterate over the search path to locate and load fullname. + """ + root, base, target = fullname.partition(self.root_name + '.') + for prefix in self.search_path: + try: + extant = prefix + target + __import__(extant) + mod = sys.modules[extant] + sys.modules[fullname] = mod + # mysterious hack: + # Remove the reference to the extant package/module + # on later Python versions to cause relative imports + # in the vendor package to resolve the same modules + # as those going through this importer. + if sys.version_info >= (3, ): + del sys.modules[extant] + return mod + except ImportError: + pass + else: + raise ImportError( + "The '{target}' package is required; " + "normally this is bundled with this package so if you get " + "this warning, consult the packager of your " + "distribution.".format(**locals()) + ) + + def install(self): + """ + Install this importer into sys.meta_path if not already present. + """ + if self not in sys.meta_path: + sys.meta_path.append(self) + + +names = 'six', 'packaging', 'pyparsing', +VendorImporter(__name__, names, 'setuptools._vendor').install() diff --git a/env/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/setuptools/extern/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e0e2c8aca8de703facbc221c480fe38bf3dd9fca GIT binary patch literal 2377 zcmZ`)O>Z1E7`EqYcPE>)s!&2Jh%A9xR-zjOJs>Ek^h2luMO9N3SQU+?Yi}~i?08~( zo9r@sVIxk68)up$zk`3_E2sViPQ0&Ycat`%M}F<`=j-=*{P^zbYD^&Y{<{9`pB5qi z;?E)lP`LwHcfoMNX-<0NTf#l=pAhcPydLF2&l6Pm!sFr0e;J$-3gdQ2Cwc{Q$aWv? zBKc6c16iXH1ZI<-$7#>!YdqlL3GD?U<PmS2kQwbo{1R{S7PK~a%vVlGugTkd70MR( zVTa3h?WriZR1b%xR7R-DNz5R9!yY|J7vQ#KSPWo2siST-NR22!y>R`9IYWwJDx zEYdt5-+bW~65K5SL!{Xg>L}BK6{#61Hzq5zfr{X;Wd9)D6`Bo{95N-PNs4qRx^DL0 zaA*u1CM+@EgRHNEsc1zKVrb>fu;x{MxmnSdKBwF}^`Ir-1dir!_abo&M=ES1seS8& zwzb^J`dS#fw(#2Ru5Ck!GEe)$#&t(h9_)4k8)%UaR0zAP1{y$_D1^e9|L$&?VYyXi z<<0p4Z}yLNi+yu=YYR3Rl}5^3pRd-AZ6!%oWF|?v<=8eCKgcB=fgv=aF`aBYeGQ@R zVqBl%7)V%pkdY^P9ZW^`fj}GNDH6$Z7QqfC-@E7{z&j#U{XKwDX~O_0Rv&i(3pN!j z)hu0rx9F(>!X+&2TC&}tE*Mat-)AvVEAVSqwA&{^0$oD)9I9cPPOiOis&fPT7+6dg zgeCN!!w<lWhogA7Q~J!G`qN+<R=(Qg-VQOI@vCq@fDz#g$f0jxYvsr=`E7ah$AE|` z7$VA!@R);9o+I}da8nu0jxu2Tk|!)JIEG_69|r9T!-kTNa=|jqWU&Yz@Y?JtIojQW z5_%R_<}7Gx6^^mpiEOKcy)wK!j#k!Bi?Q{GX=&ry4fMj1trNM>+UCMf8(=tXfG*nL zd8&ntYNsxQAFpXrd%6J|>oyn?uG0X%E08b1aBe~$IfbbS83}(6vi=>+1sFU8;<$vs zd-uuDPp0Aciz=*w4Kj@Yl4wRLF~NRVMOVqRQ8iqh-p00wdk3NF)xBSls<8uzo5n$` zN($_y<R@~t`6J{Xpq2ak%>gm38To_G=&vB0!0K@F-4dFIaNScQn0z4=Vg?{Pnmhe6 zlI60G-H2!|Q@%w04SYKE6;g2W=Mz}s#xHejr#BW?05MnMaFi**zhs3}L)5l8;+j1l z6&w}L(a6zYu60aHmJQfgju;ZibseRu03H39^<|+)d3_h><3U2*XvKJ@jmn;nkS^Wr zPOL72d$k<lt+Fv_f>Y-t0a+V^jMbQH+lEMJm<2*Jkane(`3Fi#Wh2n>VQOrIQOR|u zS>NDyaA{N#g^W?};`&jk#2`C%f|?cvcq;h?u3<#yT>Ahf=}j;sSf_33(I$K`jiVUK zfUeQl^JwH>VBfhVUQ;(j!?EugR4QUX0uCB#9m|)X_@}@x_h5RH$7fuqpPJV%BFhS( z0Ys>a@0yb(grty$rMVI*A2T?r7KJ&Z#CFG5@4>#dwVY$4v@AiD-=cbr`73Y-X4Q%p zfR3-fp?LE_9nVD)gcN|qR{*65a0E<i5TV{qlEYEzL<;^INy246Nfh2@+boqVg)(D> zR8UvZe2C@-8jRdIgQBePUZbo!HE0Hb7l-X;+-|<_dOAK(C_6@h!WSCI3Dq&Em4@o% p%GrC?UB0R=JZ`cL(R-~v!hPQ6fNkEcPxdvwT<)oB`fK+C`ahrPa|Qqa literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/glibc.py b/env/lib/python3.7/site-packages/setuptools/glibc.py new file mode 100644 index 0000000..a134591 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/glibc.py @@ -0,0 +1,86 @@ +# This file originally from pip: +# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/utils/glibc.py +from __future__ import absolute_import + +import ctypes +import re +import warnings + + +def glibc_version_string(): + "Returns glibc version string, or None if not using glibc." + + # ctypes.CDLL(None) internally calls dlopen(NULL), and as the dlopen + # manpage says, "If filename is NULL, then the returned handle is for the + # main program". This way we can let the linker do the work to figure out + # which libc our process is actually using. + process_namespace = ctypes.CDLL(None) + try: + gnu_get_libc_version = process_namespace.gnu_get_libc_version + except AttributeError: + # Symbol doesn't exist -> therefore, we are not linked to + # glibc. + return None + + # Call gnu_get_libc_version, which returns a string like "2.5" + gnu_get_libc_version.restype = ctypes.c_char_p + version_str = gnu_get_libc_version() + # py2 / py3 compatibility: + if not isinstance(version_str, str): + version_str = version_str.decode("ascii") + + return version_str + + +# Separated out from have_compatible_glibc for easier unit testing +def check_glibc_version(version_str, required_major, minimum_minor): + # Parse string and check against requested version. + # + # We use a regexp instead of str.split because we want to discard any + # random junk that might come after the minor version -- this might happen + # in patched/forked versions of glibc (e.g. Linaro's version of glibc + # uses version strings like "2.20-2014.11"). See gh-3588. + m = re.match(r"(?P<major>[0-9]+)\.(?P<minor>[0-9]+)", version_str) + if not m: + warnings.warn("Expected glibc version with 2 components major.minor," + " got: %s" % version_str, RuntimeWarning) + return False + return (int(m.group("major")) == required_major and + int(m.group("minor")) >= minimum_minor) + + +def have_compatible_glibc(required_major, minimum_minor): + version_str = glibc_version_string() + if version_str is None: + return False + return check_glibc_version(version_str, required_major, minimum_minor) + + +# platform.libc_ver regularly returns completely nonsensical glibc +# versions. E.g. on my computer, platform says: +# +# ~$ python2.7 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.7') +# ~$ python3.5 -c 'import platform; print(platform.libc_ver())' +# ('glibc', '2.9') +# +# But the truth is: +# +# ~$ ldd --version +# ldd (Debian GLIBC 2.22-11) 2.22 +# +# This is unfortunate, because it means that the linehaul data on libc +# versions that was generated by pip 8.1.2 and earlier is useless and +# misleading. Solution: instead of using platform, use our code that actually +# works. +def libc_ver(): + """Try to determine the glibc version + + Returns a tuple of strings (lib, version) which default to empty strings + in case the lookup fails. + """ + glibc_version = glibc_version_string() + if glibc_version is None: + return ("", "") + else: + return ("glibc", glibc_version) diff --git a/env/lib/python3.7/site-packages/setuptools/glob.py b/env/lib/python3.7/site-packages/setuptools/glob.py new file mode 100644 index 0000000..9d7cbc5 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/glob.py @@ -0,0 +1,174 @@ +""" +Filename globbing utility. Mostly a copy of `glob` from Python 3.5. + +Changes include: + * `yield from` and PEP3102 `*` removed. + * Hidden files are not ignored. +""" + +import os +import re +import fnmatch + +__all__ = ["glob", "iglob", "escape"] + + +def glob(pathname, recursive=False): + """Return a list of paths matching a pathname pattern. + + The pattern may contain simple shell-style wildcards a la + fnmatch. However, unlike fnmatch, filenames starting with a + dot are special cases that are not matched by '*' and '?' + patterns. + + If recursive is true, the pattern '**' will match any files and + zero or more directories and subdirectories. + """ + return list(iglob(pathname, recursive=recursive)) + + +def iglob(pathname, recursive=False): + """Return an iterator which yields the paths matching a pathname pattern. + + The pattern may contain simple shell-style wildcards a la + fnmatch. However, unlike fnmatch, filenames starting with a + dot are special cases that are not matched by '*' and '?' + patterns. + + If recursive is true, the pattern '**' will match any files and + zero or more directories and subdirectories. + """ + it = _iglob(pathname, recursive) + if recursive and _isrecursive(pathname): + s = next(it) # skip empty string + assert not s + return it + + +def _iglob(pathname, recursive): + dirname, basename = os.path.split(pathname) + if not has_magic(pathname): + if basename: + if os.path.lexists(pathname): + yield pathname + else: + # Patterns ending with a slash should match only directories + if os.path.isdir(dirname): + yield pathname + return + if not dirname: + if recursive and _isrecursive(basename): + for x in glob2(dirname, basename): + yield x + else: + for x in glob1(dirname, basename): + yield x + return + # `os.path.split()` returns the argument itself as a dirname if it is a + # drive or UNC path. Prevent an infinite recursion if a drive or UNC path + # contains magic characters (i.e. r'\\?\C:'). + if dirname != pathname and has_magic(dirname): + dirs = _iglob(dirname, recursive) + else: + dirs = [dirname] + if has_magic(basename): + if recursive and _isrecursive(basename): + glob_in_dir = glob2 + else: + glob_in_dir = glob1 + else: + glob_in_dir = glob0 + for dirname in dirs: + for name in glob_in_dir(dirname, basename): + yield os.path.join(dirname, name) + + +# These 2 helper functions non-recursively glob inside a literal directory. +# They return a list of basenames. `glob1` accepts a pattern while `glob0` +# takes a literal basename (so it only has to check for its existence). + + +def glob1(dirname, pattern): + if not dirname: + if isinstance(pattern, bytes): + dirname = os.curdir.encode('ASCII') + else: + dirname = os.curdir + try: + names = os.listdir(dirname) + except OSError: + return [] + return fnmatch.filter(names, pattern) + + +def glob0(dirname, basename): + if not basename: + # `os.path.split()` returns an empty basename for paths ending with a + # directory separator. 'q*x/' should match only directories. + if os.path.isdir(dirname): + return [basename] + else: + if os.path.lexists(os.path.join(dirname, basename)): + return [basename] + return [] + + +# This helper function recursively yields relative pathnames inside a literal +# directory. + + +def glob2(dirname, pattern): + assert _isrecursive(pattern) + yield pattern[:0] + for x in _rlistdir(dirname): + yield x + + +# Recursively yields relative pathnames inside a literal directory. +def _rlistdir(dirname): + if not dirname: + if isinstance(dirname, bytes): + dirname = os.curdir.encode('ASCII') + else: + dirname = os.curdir + try: + names = os.listdir(dirname) + except os.error: + return + for x in names: + yield x + path = os.path.join(dirname, x) if dirname else x + for y in _rlistdir(path): + yield os.path.join(x, y) + + +magic_check = re.compile('([*?[])') +magic_check_bytes = re.compile(b'([*?[])') + + +def has_magic(s): + if isinstance(s, bytes): + match = magic_check_bytes.search(s) + else: + match = magic_check.search(s) + return match is not None + + +def _isrecursive(pattern): + if isinstance(pattern, bytes): + return pattern == b'**' + else: + return pattern == '**' + + +def escape(pathname): + """Escape all special characters. + """ + # Escaping is done by wrapping any of "*?[" between square brackets. + # Metacharacters do not work in the drive part and shouldn't be escaped. + drive, pathname = os.path.splitdrive(pathname) + if isinstance(pathname, bytes): + pathname = magic_check_bytes.sub(br'[\1]', pathname) + else: + pathname = magic_check.sub(r'[\1]', pathname) + return drive + pathname diff --git a/env/lib/python3.7/site-packages/setuptools/gui-32.exe b/env/lib/python3.7/site-packages/setuptools/gui-32.exe new file mode 100644 index 0000000000000000000000000000000000000000..f8d3509653ba8f80ca7f3aa7f95616142ba83a94 GIT binary patch literal 65536 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/gui-64.exe b/env/lib/python3.7/site-packages/setuptools/gui-64.exe new file mode 100644 index 0000000000000000000000000000000000000000..330c51a5dde15a0bb610a48cd0ca11770c914dae GIT binary patch literal 75264 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/gui.exe b/env/lib/python3.7/site-packages/setuptools/gui.exe new file mode 100644 index 0000000000000000000000000000000000000000..f8d3509653ba8f80ca7f3aa7f95616142ba83a94 GIT binary patch literal 65536 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 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/setuptools/launch.py b/env/lib/python3.7/site-packages/setuptools/launch.py new file mode 100644 index 0000000..308283e --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/launch.py @@ -0,0 +1,35 @@ +""" +Launch the Python script on the command line after +setuptools is bootstrapped via import. +""" + +# Note that setuptools gets imported implicitly by the +# invocation of this script using python -m setuptools.launch + +import tokenize +import sys + + +def run(): + """ + Run the script in sys.argv[1] as if it had + been invoked naturally. + """ + __builtins__ + script_name = sys.argv[1] + namespace = dict( + __file__=script_name, + __name__='__main__', + __doc__=None, + ) + sys.argv[:] = sys.argv[1:] + + open_ = getattr(tokenize, 'open', open) + script = open_(script_name).read() + norm_script = script.replace('\\r\\n', '\\n') + code = compile(norm_script, script_name, 'exec') + exec(code, namespace) + + +if __name__ == '__main__': + run() diff --git a/env/lib/python3.7/site-packages/setuptools/lib2to3_ex.py b/env/lib/python3.7/site-packages/setuptools/lib2to3_ex.py new file mode 100644 index 0000000..4b1a73f --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/lib2to3_ex.py @@ -0,0 +1,62 @@ +""" +Customized Mixin2to3 support: + + - adds support for converting doctests + + +This module raises an ImportError on Python 2. +""" + +from distutils.util import Mixin2to3 as _Mixin2to3 +from distutils import log +from lib2to3.refactor import RefactoringTool, get_fixers_from_package + +import setuptools + + +class DistutilsRefactoringTool(RefactoringTool): + def log_error(self, msg, *args, **kw): + log.error(msg, *args) + + def log_message(self, msg, *args): + log.info(msg, *args) + + def log_debug(self, msg, *args): + log.debug(msg, *args) + + +class Mixin2to3(_Mixin2to3): + def run_2to3(self, files, doctests=False): + # See of the distribution option has been set, otherwise check the + # setuptools default. + if self.distribution.use_2to3 is not True: + return + if not files: + return + log.info("Fixing " + " ".join(files)) + self.__build_fixer_names() + self.__exclude_fixers() + if doctests: + if setuptools.run_2to3_on_doctests: + r = DistutilsRefactoringTool(self.fixer_names) + r.refactor(files, write=True, doctests_only=True) + else: + _Mixin2to3.run_2to3(self, files) + + def __build_fixer_names(self): + if self.fixer_names: + return + self.fixer_names = [] + for p in setuptools.lib2to3_fixer_packages: + self.fixer_names.extend(get_fixers_from_package(p)) + if self.distribution.use_2to3_fixers is not None: + for p in self.distribution.use_2to3_fixers: + self.fixer_names.extend(get_fixers_from_package(p)) + + def __exclude_fixers(self): + excluded_fixers = getattr(self, 'exclude_fixers', []) + if self.distribution.use_2to3_exclude_fixers is not None: + excluded_fixers.extend(self.distribution.use_2to3_exclude_fixers) + for fixer_name in excluded_fixers: + if fixer_name in self.fixer_names: + self.fixer_names.remove(fixer_name) diff --git a/env/lib/python3.7/site-packages/setuptools/monkey.py b/env/lib/python3.7/site-packages/setuptools/monkey.py new file mode 100644 index 0000000..3c77f8c --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/monkey.py @@ -0,0 +1,179 @@ +""" +Monkey patching of distutils. +""" + +import sys +import distutils.filelist +import platform +import types +import functools +from importlib import import_module +import inspect + +from setuptools.extern import six + +import setuptools + +__all__ = [] +""" +Everything is private. Contact the project team +if you think you need this functionality. +""" + + +def _get_mro(cls): + """ + Returns the bases classes for cls sorted by the MRO. + + Works around an issue on Jython where inspect.getmro will not return all + base classes if multiple classes share the same name. Instead, this + function will return a tuple containing the class itself, and the contents + of cls.__bases__. See https://github.com/pypa/setuptools/issues/1024. + """ + if platform.python_implementation() == "Jython": + return (cls,) + cls.__bases__ + return inspect.getmro(cls) + + +def get_unpatched(item): + lookup = ( + get_unpatched_class if isinstance(item, six.class_types) else + get_unpatched_function if isinstance(item, types.FunctionType) else + lambda item: None + ) + return lookup(item) + + +def get_unpatched_class(cls): + """Protect against re-patching the distutils if reloaded + + Also ensures that no other distutils extension monkeypatched the distutils + first. + """ + external_bases = ( + cls + for cls in _get_mro(cls) + if not cls.__module__.startswith('setuptools') + ) + base = next(external_bases) + if not base.__module__.startswith('distutils'): + msg = "distutils has already been patched by %r" % cls + raise AssertionError(msg) + return base + + +def patch_all(): + # we can't patch distutils.cmd, alas + distutils.core.Command = setuptools.Command + + has_issue_12885 = sys.version_info <= (3, 5, 3) + + if has_issue_12885: + # fix findall bug in distutils (http://bugs.python.org/issue12885) + distutils.filelist.findall = setuptools.findall + + needs_warehouse = ( + sys.version_info < (2, 7, 13) + or + (3, 4) < sys.version_info < (3, 4, 6) + or + (3, 5) < sys.version_info <= (3, 5, 3) + ) + + if needs_warehouse: + warehouse = 'https://upload.pypi.org/legacy/' + distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse + + _patch_distribution_metadata() + + # Install Distribution throughout the distutils + for module in distutils.dist, distutils.core, distutils.cmd: + module.Distribution = setuptools.dist.Distribution + + # Install the patched Extension + distutils.core.Extension = setuptools.extension.Extension + distutils.extension.Extension = setuptools.extension.Extension + if 'distutils.command.build_ext' in sys.modules: + sys.modules['distutils.command.build_ext'].Extension = ( + setuptools.extension.Extension + ) + + patch_for_msvc_specialized_compiler() + + +def _patch_distribution_metadata(): + """Patch write_pkg_file and read_pkg_file for higher metadata standards""" + for attr in ('write_pkg_file', 'read_pkg_file', 'get_metadata_version'): + new_val = getattr(setuptools.dist, attr) + setattr(distutils.dist.DistributionMetadata, attr, new_val) + + +def patch_func(replacement, target_mod, func_name): + """ + Patch func_name in target_mod with replacement + + Important - original must be resolved by name to avoid + patching an already patched function. + """ + original = getattr(target_mod, func_name) + + # set the 'unpatched' attribute on the replacement to + # point to the original. + vars(replacement).setdefault('unpatched', original) + + # replace the function in the original module + setattr(target_mod, func_name, replacement) + + +def get_unpatched_function(candidate): + return getattr(candidate, 'unpatched') + + +def patch_for_msvc_specialized_compiler(): + """ + Patch functions in distutils to use standalone Microsoft Visual C++ + compilers. + """ + # import late to avoid circular imports on Python < 3.5 + msvc = import_module('setuptools.msvc') + + if platform.system() != 'Windows': + # Compilers only availables on Microsoft Windows + return + + def patch_params(mod_name, func_name): + """ + Prepare the parameters for patch_func to patch indicated function. + """ + repl_prefix = 'msvc9_' if 'msvc9' in mod_name else 'msvc14_' + repl_name = repl_prefix + func_name.lstrip('_') + repl = getattr(msvc, repl_name) + mod = import_module(mod_name) + if not hasattr(mod, func_name): + raise ImportError(func_name) + return repl, mod, func_name + + # Python 2.7 to 3.4 + msvc9 = functools.partial(patch_params, 'distutils.msvc9compiler') + + # Python 3.5+ + msvc14 = functools.partial(patch_params, 'distutils._msvccompiler') + + try: + # Patch distutils.msvc9compiler + patch_func(*msvc9('find_vcvarsall')) + patch_func(*msvc9('query_vcvarsall')) + except ImportError: + pass + + try: + # Patch distutils._msvccompiler._get_vc_env + patch_func(*msvc14('_get_vc_env')) + except ImportError: + pass + + try: + # Patch distutils._msvccompiler.gen_lib_options for Numpy + patch_func(*msvc14('gen_lib_options')) + except ImportError: + pass diff --git a/env/lib/python3.7/site-packages/setuptools/msvc.py b/env/lib/python3.7/site-packages/setuptools/msvc.py new file mode 100644 index 0000000..b9c472f --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/msvc.py @@ -0,0 +1,1301 @@ +""" +Improved support for Microsoft Visual C++ compilers. + +Known supported compilers: +-------------------------- +Microsoft Visual C++ 9.0: + Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64) + Microsoft Windows SDK 6.1 (x86, x64, ia64) + Microsoft Windows SDK 7.0 (x86, x64, ia64) + +Microsoft Visual C++ 10.0: + Microsoft Windows SDK 7.1 (x86, x64, ia64) + +Microsoft Visual C++ 14.0: + Microsoft Visual C++ Build Tools 2015 (x86, x64, arm) + Microsoft Visual Studio 2017 (x86, x64, arm, arm64) + Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64) +""" + +import os +import sys +import platform +import itertools +import distutils.errors +from setuptools.extern.packaging.version import LegacyVersion + +from setuptools.extern.six.moves import filterfalse + +from .monkey import get_unpatched + +if platform.system() == 'Windows': + from setuptools.extern.six.moves import winreg + safe_env = os.environ +else: + """ + Mock winreg and environ so the module can be imported + on this platform. + """ + + class winreg: + HKEY_USERS = None + HKEY_CURRENT_USER = None + HKEY_LOCAL_MACHINE = None + HKEY_CLASSES_ROOT = None + + safe_env = dict() + +_msvc9_suppress_errors = ( + # msvc9compiler isn't available on some platforms + ImportError, + + # msvc9compiler raises DistutilsPlatformError in some + # environments. See #1118. + distutils.errors.DistutilsPlatformError, +) + +try: + from distutils.msvc9compiler import Reg +except _msvc9_suppress_errors: + pass + + +def msvc9_find_vcvarsall(version): + """ + Patched "distutils.msvc9compiler.find_vcvarsall" to use the standalone + compiler build for Python (VCForPython). Fall back to original behavior + when the standalone compiler is not available. + + Redirect the path of "vcvarsall.bat". + + Known supported compilers + ------------------------- + Microsoft Visual C++ 9.0: + Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64) + + Parameters + ---------- + version: float + Required Microsoft Visual C++ version. + + Return + ------ + vcvarsall.bat path: str + """ + VC_BASE = r'Software\%sMicrosoft\DevDiv\VCForPython\%0.1f' + key = VC_BASE % ('', version) + try: + # Per-user installs register the compiler path here + productdir = Reg.get_value(key, "installdir") + except KeyError: + try: + # All-user installs on a 64-bit system register here + key = VC_BASE % ('Wow6432Node\\', version) + productdir = Reg.get_value(key, "installdir") + except KeyError: + productdir = None + + if productdir: + vcvarsall = os.path.os.path.join(productdir, "vcvarsall.bat") + if os.path.isfile(vcvarsall): + return vcvarsall + + return get_unpatched(msvc9_find_vcvarsall)(version) + + +def msvc9_query_vcvarsall(ver, arch='x86', *args, **kwargs): + """ + Patched "distutils.msvc9compiler.query_vcvarsall" for support extra + compilers. + + Set environment without use of "vcvarsall.bat". + + Known supported compilers + ------------------------- + Microsoft Visual C++ 9.0: + Microsoft Visual C++ Compiler for Python 2.7 (x86, amd64) + Microsoft Windows SDK 6.1 (x86, x64, ia64) + Microsoft Windows SDK 7.0 (x86, x64, ia64) + + Microsoft Visual C++ 10.0: + Microsoft Windows SDK 7.1 (x86, x64, ia64) + + Parameters + ---------- + ver: float + Required Microsoft Visual C++ version. + arch: str + Target architecture. + + Return + ------ + environment: dict + """ + # Try to get environement from vcvarsall.bat (Classical way) + try: + orig = get_unpatched(msvc9_query_vcvarsall) + return orig(ver, arch, *args, **kwargs) + except distutils.errors.DistutilsPlatformError: + # Pass error if Vcvarsall.bat is missing + pass + except ValueError: + # Pass error if environment not set after executing vcvarsall.bat + pass + + # If error, try to set environment directly + try: + return EnvironmentInfo(arch, ver).return_env() + except distutils.errors.DistutilsPlatformError as exc: + _augment_exception(exc, ver, arch) + raise + + +def msvc14_get_vc_env(plat_spec): + """ + Patched "distutils._msvccompiler._get_vc_env" for support extra + compilers. + + Set environment without use of "vcvarsall.bat". + + Known supported compilers + ------------------------- + Microsoft Visual C++ 14.0: + Microsoft Visual C++ Build Tools 2015 (x86, x64, arm) + Microsoft Visual Studio 2017 (x86, x64, arm, arm64) + Microsoft Visual Studio Build Tools 2017 (x86, x64, arm, arm64) + + Parameters + ---------- + plat_spec: str + Target architecture. + + Return + ------ + environment: dict + """ + # Try to get environment from vcvarsall.bat (Classical way) + try: + return get_unpatched(msvc14_get_vc_env)(plat_spec) + except distutils.errors.DistutilsPlatformError: + # Pass error Vcvarsall.bat is missing + pass + + # If error, try to set environment directly + try: + return EnvironmentInfo(plat_spec, vc_min_ver=14.0).return_env() + except distutils.errors.DistutilsPlatformError as exc: + _augment_exception(exc, 14.0) + raise + + +def msvc14_gen_lib_options(*args, **kwargs): + """ + Patched "distutils._msvccompiler.gen_lib_options" for fix + compatibility between "numpy.distutils" and "distutils._msvccompiler" + (for Numpy < 1.11.2) + """ + if "numpy.distutils" in sys.modules: + import numpy as np + if LegacyVersion(np.__version__) < LegacyVersion('1.11.2'): + return np.distutils.ccompiler.gen_lib_options(*args, **kwargs) + return get_unpatched(msvc14_gen_lib_options)(*args, **kwargs) + + +def _augment_exception(exc, version, arch=''): + """ + Add details to the exception message to help guide the user + as to what action will resolve it. + """ + # Error if MSVC++ directory not found or environment not set + message = exc.args[0] + + if "vcvarsall" in message.lower() or "visual c" in message.lower(): + # Special error message if MSVC++ not installed + tmpl = 'Microsoft Visual C++ {version:0.1f} is required.' + message = tmpl.format(**locals()) + msdownload = 'www.microsoft.com/download/details.aspx?id=%d' + if version == 9.0: + if arch.lower().find('ia64') > -1: + # For VC++ 9.0, if IA64 support is needed, redirect user + # to Windows SDK 7.0 + message += ' Get it with "Microsoft Windows SDK 7.0": ' + message += msdownload % 3138 + else: + # For VC++ 9.0 redirect user to Vc++ for Python 2.7 : + # This redirection link is maintained by Microsoft. + # Contact vspython@microsoft.com if it needs updating. + message += ' Get it from http://aka.ms/vcpython27' + elif version == 10.0: + # For VC++ 10.0 Redirect user to Windows SDK 7.1 + message += ' Get it with "Microsoft Windows SDK 7.1": ' + message += msdownload % 8279 + elif version >= 14.0: + # For VC++ 14.0 Redirect user to Visual C++ Build Tools + message += (' Get it with "Microsoft Visual C++ Build Tools": ' + r'https://visualstudio.microsoft.com/downloads/') + + exc.args = (message, ) + + +class PlatformInfo: + """ + Current and Target Architectures informations. + + Parameters + ---------- + arch: str + Target architecture. + """ + current_cpu = safe_env.get('processor_architecture', '').lower() + + def __init__(self, arch): + self.arch = arch.lower().replace('x64', 'amd64') + + @property + def target_cpu(self): + return self.arch[self.arch.find('_') + 1:] + + def target_is_x86(self): + return self.target_cpu == 'x86' + + def current_is_x86(self): + return self.current_cpu == 'x86' + + def current_dir(self, hidex86=False, x64=False): + """ + Current platform specific subfolder. + + Parameters + ---------- + hidex86: bool + return '' and not '\x86' if architecture is x86. + x64: bool + return '\x64' and not '\amd64' if architecture is amd64. + + Return + ------ + subfolder: str + '\target', or '' (see hidex86 parameter) + """ + return ( + '' if (self.current_cpu == 'x86' and hidex86) else + r'\x64' if (self.current_cpu == 'amd64' and x64) else + r'\%s' % self.current_cpu + ) + + def target_dir(self, hidex86=False, x64=False): + r""" + Target platform specific subfolder. + + Parameters + ---------- + hidex86: bool + return '' and not '\x86' if architecture is x86. + x64: bool + return '\x64' and not '\amd64' if architecture is amd64. + + Return + ------ + subfolder: str + '\current', or '' (see hidex86 parameter) + """ + return ( + '' if (self.target_cpu == 'x86' and hidex86) else + r'\x64' if (self.target_cpu == 'amd64' and x64) else + r'\%s' % self.target_cpu + ) + + def cross_dir(self, forcex86=False): + r""" + Cross platform specific subfolder. + + Parameters + ---------- + forcex86: bool + Use 'x86' as current architecture even if current acritecture is + not x86. + + Return + ------ + subfolder: str + '' if target architecture is current architecture, + '\current_target' if not. + """ + current = 'x86' if forcex86 else self.current_cpu + return ( + '' if self.target_cpu == current else + self.target_dir().replace('\\', '\\%s_' % current) + ) + + +class RegistryInfo: + """ + Microsoft Visual Studio related registry informations. + + Parameters + ---------- + platform_info: PlatformInfo + "PlatformInfo" instance. + """ + HKEYS = (winreg.HKEY_USERS, + winreg.HKEY_CURRENT_USER, + winreg.HKEY_LOCAL_MACHINE, + winreg.HKEY_CLASSES_ROOT) + + def __init__(self, platform_info): + self.pi = platform_info + + @property + def visualstudio(self): + """ + Microsoft Visual Studio root registry key. + """ + return 'VisualStudio' + + @property + def sxs(self): + """ + Microsoft Visual Studio SxS registry key. + """ + return os.path.join(self.visualstudio, 'SxS') + + @property + def vc(self): + """ + Microsoft Visual C++ VC7 registry key. + """ + return os.path.join(self.sxs, 'VC7') + + @property + def vs(self): + """ + Microsoft Visual Studio VS7 registry key. + """ + return os.path.join(self.sxs, 'VS7') + + @property + def vc_for_python(self): + """ + Microsoft Visual C++ for Python registry key. + """ + return r'DevDiv\VCForPython' + + @property + def microsoft_sdk(self): + """ + Microsoft SDK registry key. + """ + return 'Microsoft SDKs' + + @property + def windows_sdk(self): + """ + Microsoft Windows/Platform SDK registry key. + """ + return os.path.join(self.microsoft_sdk, 'Windows') + + @property + def netfx_sdk(self): + """ + Microsoft .NET Framework SDK registry key. + """ + return os.path.join(self.microsoft_sdk, 'NETFXSDK') + + @property + def windows_kits_roots(self): + """ + Microsoft Windows Kits Roots registry key. + """ + return r'Windows Kits\Installed Roots' + + def microsoft(self, key, x86=False): + """ + Return key in Microsoft software registry. + + Parameters + ---------- + key: str + Registry key path where look. + x86: str + Force x86 software registry. + + Return + ------ + str: value + """ + node64 = '' if self.pi.current_is_x86() or x86 else 'Wow6432Node' + return os.path.join('Software', node64, 'Microsoft', key) + + def lookup(self, key, name): + """ + Look for values in registry in Microsoft software registry. + + Parameters + ---------- + key: str + Registry key path where look. + name: str + Value name to find. + + Return + ------ + str: value + """ + KEY_READ = winreg.KEY_READ + openkey = winreg.OpenKey + ms = self.microsoft + for hkey in self.HKEYS: + try: + bkey = openkey(hkey, ms(key), 0, KEY_READ) + except (OSError, IOError): + if not self.pi.current_is_x86(): + try: + bkey = openkey(hkey, ms(key, True), 0, KEY_READ) + except (OSError, IOError): + continue + else: + continue + try: + return winreg.QueryValueEx(bkey, name)[0] + except (OSError, IOError): + pass + + +class SystemInfo: + """ + Microsoft Windows and Visual Studio related system inormations. + + Parameters + ---------- + registry_info: RegistryInfo + "RegistryInfo" instance. + vc_ver: float + Required Microsoft Visual C++ version. + """ + + # Variables and properties in this class use originals CamelCase variables + # names from Microsoft source files for more easy comparaison. + WinDir = safe_env.get('WinDir', '') + ProgramFiles = safe_env.get('ProgramFiles', '') + ProgramFilesx86 = safe_env.get('ProgramFiles(x86)', ProgramFiles) + + def __init__(self, registry_info, vc_ver=None): + self.ri = registry_info + self.pi = self.ri.pi + self.vc_ver = vc_ver or self._find_latest_available_vc_ver() + + def _find_latest_available_vc_ver(self): + try: + return self.find_available_vc_vers()[-1] + except IndexError: + err = 'No Microsoft Visual C++ version found' + raise distutils.errors.DistutilsPlatformError(err) + + def find_available_vc_vers(self): + """ + Find all available Microsoft Visual C++ versions. + """ + ms = self.ri.microsoft + vckeys = (self.ri.vc, self.ri.vc_for_python, self.ri.vs) + vc_vers = [] + for hkey in self.ri.HKEYS: + for key in vckeys: + try: + bkey = winreg.OpenKey(hkey, ms(key), 0, winreg.KEY_READ) + except (OSError, IOError): + continue + subkeys, values, _ = winreg.QueryInfoKey(bkey) + for i in range(values): + try: + ver = float(winreg.EnumValue(bkey, i)[0]) + if ver not in vc_vers: + vc_vers.append(ver) + except ValueError: + pass + for i in range(subkeys): + try: + ver = float(winreg.EnumKey(bkey, i)) + if ver not in vc_vers: + vc_vers.append(ver) + except ValueError: + pass + return sorted(vc_vers) + + @property + def VSInstallDir(self): + """ + Microsoft Visual Studio directory. + """ + # Default path + name = 'Microsoft Visual Studio %0.1f' % self.vc_ver + default = os.path.join(self.ProgramFilesx86, name) + + # Try to get path from registry, if fail use default path + return self.ri.lookup(self.ri.vs, '%0.1f' % self.vc_ver) or default + + @property + def VCInstallDir(self): + """ + Microsoft Visual C++ directory. + """ + self.VSInstallDir + + guess_vc = self._guess_vc() or self._guess_vc_legacy() + + # Try to get "VC++ for Python" path from registry as default path + reg_path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) + python_vc = self.ri.lookup(reg_path, 'installdir') + default_vc = os.path.join(python_vc, 'VC') if python_vc else guess_vc + + # Try to get path from registry, if fail use default path + path = self.ri.lookup(self.ri.vc, '%0.1f' % self.vc_ver) or default_vc + + if not os.path.isdir(path): + msg = 'Microsoft Visual C++ directory not found' + raise distutils.errors.DistutilsPlatformError(msg) + + return path + + def _guess_vc(self): + """ + Locate Visual C for 2017 + """ + if self.vc_ver <= 14.0: + return + + default = r'VC\Tools\MSVC' + guess_vc = os.path.join(self.VSInstallDir, default) + # Subdir with VC exact version as name + try: + vc_exact_ver = os.listdir(guess_vc)[-1] + return os.path.join(guess_vc, vc_exact_ver) + except (OSError, IOError, IndexError): + pass + + def _guess_vc_legacy(self): + """ + Locate Visual C for versions prior to 2017 + """ + default = r'Microsoft Visual Studio %0.1f\VC' % self.vc_ver + return os.path.join(self.ProgramFilesx86, default) + + @property + def WindowsSdkVersion(self): + """ + Microsoft Windows SDK versions for specified MSVC++ version. + """ + if self.vc_ver <= 9.0: + return ('7.0', '6.1', '6.0a') + elif self.vc_ver == 10.0: + return ('7.1', '7.0a') + elif self.vc_ver == 11.0: + return ('8.0', '8.0a') + elif self.vc_ver == 12.0: + return ('8.1', '8.1a') + elif self.vc_ver >= 14.0: + return ('10.0', '8.1') + + @property + def WindowsSdkLastVersion(self): + """ + Microsoft Windows SDK last version + """ + return self._use_last_dir_name(os.path.join( + self.WindowsSdkDir, 'lib')) + + @property + def WindowsSdkDir(self): + """ + Microsoft Windows SDK directory. + """ + sdkdir = '' + for ver in self.WindowsSdkVersion: + # Try to get it from registry + loc = os.path.join(self.ri.windows_sdk, 'v%s' % ver) + sdkdir = self.ri.lookup(loc, 'installationfolder') + if sdkdir: + break + if not sdkdir or not os.path.isdir(sdkdir): + # Try to get "VC++ for Python" version from registry + path = os.path.join(self.ri.vc_for_python, '%0.1f' % self.vc_ver) + install_base = self.ri.lookup(path, 'installdir') + if install_base: + sdkdir = os.path.join(install_base, 'WinSDK') + if not sdkdir or not os.path.isdir(sdkdir): + # If fail, use default new path + for ver in self.WindowsSdkVersion: + intver = ver[:ver.rfind('.')] + path = r'Microsoft SDKs\Windows Kits\%s' % (intver) + d = os.path.join(self.ProgramFiles, path) + if os.path.isdir(d): + sdkdir = d + if not sdkdir or not os.path.isdir(sdkdir): + # If fail, use default old path + for ver in self.WindowsSdkVersion: + path = r'Microsoft SDKs\Windows\v%s' % ver + d = os.path.join(self.ProgramFiles, path) + if os.path.isdir(d): + sdkdir = d + if not sdkdir: + # If fail, use Platform SDK + sdkdir = os.path.join(self.VCInstallDir, 'PlatformSDK') + return sdkdir + + @property + def WindowsSDKExecutablePath(self): + """ + Microsoft Windows SDK executable directory. + """ + # Find WinSDK NetFx Tools registry dir name + if self.vc_ver <= 11.0: + netfxver = 35 + arch = '' + else: + netfxver = 40 + hidex86 = True if self.vc_ver <= 12.0 else False + arch = self.pi.current_dir(x64=True, hidex86=hidex86) + fx = 'WinSDK-NetFx%dTools%s' % (netfxver, arch.replace('\\', '-')) + + # liste all possibles registry paths + regpaths = [] + if self.vc_ver >= 14.0: + for ver in self.NetFxSdkVersion: + regpaths += [os.path.join(self.ri.netfx_sdk, ver, fx)] + + for ver in self.WindowsSdkVersion: + regpaths += [os.path.join(self.ri.windows_sdk, 'v%sA' % ver, fx)] + + # Return installation folder from the more recent path + for path in regpaths: + execpath = self.ri.lookup(path, 'installationfolder') + if execpath: + break + return execpath + + @property + def FSharpInstallDir(self): + """ + Microsoft Visual F# directory. + """ + path = r'%0.1f\Setup\F#' % self.vc_ver + path = os.path.join(self.ri.visualstudio, path) + return self.ri.lookup(path, 'productdir') or '' + + @property + def UniversalCRTSdkDir(self): + """ + Microsoft Universal CRT SDK directory. + """ + # Set Kit Roots versions for specified MSVC++ version + if self.vc_ver >= 14.0: + vers = ('10', '81') + else: + vers = () + + # Find path of the more recent Kit + for ver in vers: + sdkdir = self.ri.lookup(self.ri.windows_kits_roots, + 'kitsroot%s' % ver) + if sdkdir: + break + return sdkdir or '' + + @property + def UniversalCRTSdkLastVersion(self): + """ + Microsoft Universal C Runtime SDK last version + """ + return self._use_last_dir_name(os.path.join( + self.UniversalCRTSdkDir, 'lib')) + + @property + def NetFxSdkVersion(self): + """ + Microsoft .NET Framework SDK versions. + """ + # Set FxSdk versions for specified MSVC++ version + if self.vc_ver >= 14.0: + return ('4.6.1', '4.6') + else: + return () + + @property + def NetFxSdkDir(self): + """ + Microsoft .NET Framework SDK directory. + """ + for ver in self.NetFxSdkVersion: + loc = os.path.join(self.ri.netfx_sdk, ver) + sdkdir = self.ri.lookup(loc, 'kitsinstallationfolder') + if sdkdir: + break + return sdkdir or '' + + @property + def FrameworkDir32(self): + """ + Microsoft .NET Framework 32bit directory. + """ + # Default path + guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework') + + # Try to get path from registry, if fail use default path + return self.ri.lookup(self.ri.vc, 'frameworkdir32') or guess_fw + + @property + def FrameworkDir64(self): + """ + Microsoft .NET Framework 64bit directory. + """ + # Default path + guess_fw = os.path.join(self.WinDir, r'Microsoft.NET\Framework64') + + # Try to get path from registry, if fail use default path + return self.ri.lookup(self.ri.vc, 'frameworkdir64') or guess_fw + + @property + def FrameworkVersion32(self): + """ + Microsoft .NET Framework 32bit versions. + """ + return self._find_dot_net_versions(32) + + @property + def FrameworkVersion64(self): + """ + Microsoft .NET Framework 64bit versions. + """ + return self._find_dot_net_versions(64) + + def _find_dot_net_versions(self, bits): + """ + Find Microsoft .NET Framework versions. + + Parameters + ---------- + bits: int + Platform number of bits: 32 or 64. + """ + # Find actual .NET version in registry + reg_ver = self.ri.lookup(self.ri.vc, 'frameworkver%d' % bits) + dot_net_dir = getattr(self, 'FrameworkDir%d' % bits) + ver = reg_ver or self._use_last_dir_name(dot_net_dir, 'v') or '' + + # Set .NET versions for specified MSVC++ version + if self.vc_ver >= 12.0: + frameworkver = (ver, 'v4.0') + elif self.vc_ver >= 10.0: + frameworkver = ('v4.0.30319' if ver.lower()[:2] != 'v4' else ver, + 'v3.5') + elif self.vc_ver == 9.0: + frameworkver = ('v3.5', 'v2.0.50727') + if self.vc_ver == 8.0: + frameworkver = ('v3.0', 'v2.0.50727') + return frameworkver + + def _use_last_dir_name(self, path, prefix=''): + """ + Return name of the last dir in path or '' if no dir found. + + Parameters + ---------- + path: str + Use dirs in this path + prefix: str + Use only dirs startings by this prefix + """ + matching_dirs = ( + dir_name + for dir_name in reversed(os.listdir(path)) + if os.path.isdir(os.path.join(path, dir_name)) and + dir_name.startswith(prefix) + ) + return next(matching_dirs, None) or '' + + +class EnvironmentInfo: + """ + Return environment variables for specified Microsoft Visual C++ version + and platform : Lib, Include, Path and libpath. + + This function is compatible with Microsoft Visual C++ 9.0 to 14.0. + + Script created by analysing Microsoft environment configuration files like + "vcvars[...].bat", "SetEnv.Cmd", "vcbuildtools.bat", ... + + Parameters + ---------- + arch: str + Target architecture. + vc_ver: float + Required Microsoft Visual C++ version. If not set, autodetect the last + version. + vc_min_ver: float + Minimum Microsoft Visual C++ version. + """ + + # Variables and properties in this class use originals CamelCase variables + # names from Microsoft source files for more easy comparaison. + + def __init__(self, arch, vc_ver=None, vc_min_ver=0): + self.pi = PlatformInfo(arch) + self.ri = RegistryInfo(self.pi) + self.si = SystemInfo(self.ri, vc_ver) + + if self.vc_ver < vc_min_ver: + err = 'No suitable Microsoft Visual C++ version found' + raise distutils.errors.DistutilsPlatformError(err) + + @property + def vc_ver(self): + """ + Microsoft Visual C++ version. + """ + return self.si.vc_ver + + @property + def VSTools(self): + """ + Microsoft Visual Studio Tools + """ + paths = [r'Common7\IDE', r'Common7\Tools'] + + if self.vc_ver >= 14.0: + arch_subdir = self.pi.current_dir(hidex86=True, x64=True) + paths += [r'Common7\IDE\CommonExtensions\Microsoft\TestWindow'] + paths += [r'Team Tools\Performance Tools'] + paths += [r'Team Tools\Performance Tools%s' % arch_subdir] + + return [os.path.join(self.si.VSInstallDir, path) for path in paths] + + @property + def VCIncludes(self): + """ + Microsoft Visual C++ & Microsoft Foundation Class Includes + """ + return [os.path.join(self.si.VCInstallDir, 'Include'), + os.path.join(self.si.VCInstallDir, r'ATLMFC\Include')] + + @property + def VCLibraries(self): + """ + Microsoft Visual C++ & Microsoft Foundation Class Libraries + """ + if self.vc_ver >= 15.0: + arch_subdir = self.pi.target_dir(x64=True) + else: + arch_subdir = self.pi.target_dir(hidex86=True) + paths = ['Lib%s' % arch_subdir, r'ATLMFC\Lib%s' % arch_subdir] + + if self.vc_ver >= 14.0: + paths += [r'Lib\store%s' % arch_subdir] + + return [os.path.join(self.si.VCInstallDir, path) for path in paths] + + @property + def VCStoreRefs(self): + """ + Microsoft Visual C++ store references Libraries + """ + if self.vc_ver < 14.0: + return [] + return [os.path.join(self.si.VCInstallDir, r'Lib\store\references')] + + @property + def VCTools(self): + """ + Microsoft Visual C++ Tools + """ + si = self.si + tools = [os.path.join(si.VCInstallDir, 'VCPackages')] + + forcex86 = True if self.vc_ver <= 10.0 else False + arch_subdir = self.pi.cross_dir(forcex86) + if arch_subdir: + tools += [os.path.join(si.VCInstallDir, 'Bin%s' % arch_subdir)] + + if self.vc_ver == 14.0: + path = 'Bin%s' % self.pi.current_dir(hidex86=True) + tools += [os.path.join(si.VCInstallDir, path)] + + elif self.vc_ver >= 15.0: + host_dir = (r'bin\HostX86%s' if self.pi.current_is_x86() else + r'bin\HostX64%s') + tools += [os.path.join( + si.VCInstallDir, host_dir % self.pi.target_dir(x64=True))] + + if self.pi.current_cpu != self.pi.target_cpu: + tools += [os.path.join( + si.VCInstallDir, host_dir % self.pi.current_dir(x64=True))] + + else: + tools += [os.path.join(si.VCInstallDir, 'Bin')] + + return tools + + @property + def OSLibraries(self): + """ + Microsoft Windows SDK Libraries + """ + if self.vc_ver <= 10.0: + arch_subdir = self.pi.target_dir(hidex86=True, x64=True) + return [os.path.join(self.si.WindowsSdkDir, 'Lib%s' % arch_subdir)] + + else: + arch_subdir = self.pi.target_dir(x64=True) + lib = os.path.join(self.si.WindowsSdkDir, 'lib') + libver = self._sdk_subdir + return [os.path.join(lib, '%sum%s' % (libver , arch_subdir))] + + @property + def OSIncludes(self): + """ + Microsoft Windows SDK Include + """ + include = os.path.join(self.si.WindowsSdkDir, 'include') + + if self.vc_ver <= 10.0: + return [include, os.path.join(include, 'gl')] + + else: + if self.vc_ver >= 14.0: + sdkver = self._sdk_subdir + else: + sdkver = '' + return [os.path.join(include, '%sshared' % sdkver), + os.path.join(include, '%sum' % sdkver), + os.path.join(include, '%swinrt' % sdkver)] + + @property + def OSLibpath(self): + """ + Microsoft Windows SDK Libraries Paths + """ + ref = os.path.join(self.si.WindowsSdkDir, 'References') + libpath = [] + + if self.vc_ver <= 9.0: + libpath += self.OSLibraries + + if self.vc_ver >= 11.0: + libpath += [os.path.join(ref, r'CommonConfiguration\Neutral')] + + if self.vc_ver >= 14.0: + libpath += [ + ref, + os.path.join(self.si.WindowsSdkDir, 'UnionMetadata'), + os.path.join( + ref, + 'Windows.Foundation.UniversalApiContract', + '1.0.0.0', + ), + os.path.join( + ref, + 'Windows.Foundation.FoundationContract', + '1.0.0.0', + ), + os.path.join( + ref, + 'Windows.Networking.Connectivity.WwanContract', + '1.0.0.0', + ), + os.path.join( + self.si.WindowsSdkDir, + 'ExtensionSDKs', + 'Microsoft.VCLibs', + '%0.1f' % self.vc_ver, + 'References', + 'CommonConfiguration', + 'neutral', + ), + ] + return libpath + + @property + def SdkTools(self): + """ + Microsoft Windows SDK Tools + """ + return list(self._sdk_tools()) + + def _sdk_tools(self): + """ + Microsoft Windows SDK Tools paths generator + """ + if self.vc_ver < 15.0: + bin_dir = 'Bin' if self.vc_ver <= 11.0 else r'Bin\x86' + yield os.path.join(self.si.WindowsSdkDir, bin_dir) + + if not self.pi.current_is_x86(): + arch_subdir = self.pi.current_dir(x64=True) + path = 'Bin%s' % arch_subdir + yield os.path.join(self.si.WindowsSdkDir, path) + + if self.vc_ver == 10.0 or self.vc_ver == 11.0: + if self.pi.target_is_x86(): + arch_subdir = '' + else: + arch_subdir = self.pi.current_dir(hidex86=True, x64=True) + path = r'Bin\NETFX 4.0 Tools%s' % arch_subdir + yield os.path.join(self.si.WindowsSdkDir, path) + + elif self.vc_ver >= 15.0: + path = os.path.join(self.si.WindowsSdkDir, 'Bin') + arch_subdir = self.pi.current_dir(x64=True) + sdkver = self.si.WindowsSdkLastVersion + yield os.path.join(path, '%s%s' % (sdkver, arch_subdir)) + + if self.si.WindowsSDKExecutablePath: + yield self.si.WindowsSDKExecutablePath + + @property + def _sdk_subdir(self): + """ + Microsoft Windows SDK version subdir + """ + ucrtver = self.si.WindowsSdkLastVersion + return ('%s\\' % ucrtver) if ucrtver else '' + + @property + def SdkSetup(self): + """ + Microsoft Windows SDK Setup + """ + if self.vc_ver > 9.0: + return [] + + return [os.path.join(self.si.WindowsSdkDir, 'Setup')] + + @property + def FxTools(self): + """ + Microsoft .NET Framework Tools + """ + pi = self.pi + si = self.si + + if self.vc_ver <= 10.0: + include32 = True + include64 = not pi.target_is_x86() and not pi.current_is_x86() + else: + include32 = pi.target_is_x86() or pi.current_is_x86() + include64 = pi.current_cpu == 'amd64' or pi.target_cpu == 'amd64' + + tools = [] + if include32: + tools += [os.path.join(si.FrameworkDir32, ver) + for ver in si.FrameworkVersion32] + if include64: + tools += [os.path.join(si.FrameworkDir64, ver) + for ver in si.FrameworkVersion64] + return tools + + @property + def NetFxSDKLibraries(self): + """ + Microsoft .Net Framework SDK Libraries + """ + if self.vc_ver < 14.0 or not self.si.NetFxSdkDir: + return [] + + arch_subdir = self.pi.target_dir(x64=True) + return [os.path.join(self.si.NetFxSdkDir, r'lib\um%s' % arch_subdir)] + + @property + def NetFxSDKIncludes(self): + """ + Microsoft .Net Framework SDK Includes + """ + if self.vc_ver < 14.0 or not self.si.NetFxSdkDir: + return [] + + return [os.path.join(self.si.NetFxSdkDir, r'include\um')] + + @property + def VsTDb(self): + """ + Microsoft Visual Studio Team System Database + """ + return [os.path.join(self.si.VSInstallDir, r'VSTSDB\Deploy')] + + @property + def MSBuild(self): + """ + Microsoft Build Engine + """ + if self.vc_ver < 12.0: + return [] + elif self.vc_ver < 15.0: + base_path = self.si.ProgramFilesx86 + arch_subdir = self.pi.current_dir(hidex86=True) + else: + base_path = self.si.VSInstallDir + arch_subdir = '' + + path = r'MSBuild\%0.1f\bin%s' % (self.vc_ver, arch_subdir) + build = [os.path.join(base_path, path)] + + if self.vc_ver >= 15.0: + # Add Roslyn C# & Visual Basic Compiler + build += [os.path.join(base_path, path, 'Roslyn')] + + return build + + @property + def HTMLHelpWorkshop(self): + """ + Microsoft HTML Help Workshop + """ + if self.vc_ver < 11.0: + return [] + + return [os.path.join(self.si.ProgramFilesx86, 'HTML Help Workshop')] + + @property + def UCRTLibraries(self): + """ + Microsoft Universal C Runtime SDK Libraries + """ + if self.vc_ver < 14.0: + return [] + + arch_subdir = self.pi.target_dir(x64=True) + lib = os.path.join(self.si.UniversalCRTSdkDir, 'lib') + ucrtver = self._ucrt_subdir + return [os.path.join(lib, '%sucrt%s' % (ucrtver, arch_subdir))] + + @property + def UCRTIncludes(self): + """ + Microsoft Universal C Runtime SDK Include + """ + if self.vc_ver < 14.0: + return [] + + include = os.path.join(self.si.UniversalCRTSdkDir, 'include') + return [os.path.join(include, '%sucrt' % self._ucrt_subdir)] + + @property + def _ucrt_subdir(self): + """ + Microsoft Universal C Runtime SDK version subdir + """ + ucrtver = self.si.UniversalCRTSdkLastVersion + return ('%s\\' % ucrtver) if ucrtver else '' + + @property + def FSharp(self): + """ + Microsoft Visual F# + """ + if self.vc_ver < 11.0 and self.vc_ver > 12.0: + return [] + + return self.si.FSharpInstallDir + + @property + def VCRuntimeRedist(self): + """ + Microsoft Visual C++ runtime redistribuable dll + """ + arch_subdir = self.pi.target_dir(x64=True) + if self.vc_ver < 15: + redist_path = self.si.VCInstallDir + vcruntime = 'redist%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll' + else: + redist_path = self.si.VCInstallDir.replace('\\Tools', '\\Redist') + vcruntime = 'onecore%s\\Microsoft.VC%d0.CRT\\vcruntime%d0.dll' + + # Visual Studio 2017 is still Visual C++ 14.0 + dll_ver = 14.0 if self.vc_ver == 15 else self.vc_ver + + vcruntime = vcruntime % (arch_subdir, self.vc_ver, dll_ver) + return os.path.join(redist_path, vcruntime) + + def return_env(self, exists=True): + """ + Return environment dict. + + Parameters + ---------- + exists: bool + It True, only return existing paths. + """ + env = dict( + include=self._build_paths('include', + [self.VCIncludes, + self.OSIncludes, + self.UCRTIncludes, + self.NetFxSDKIncludes], + exists), + lib=self._build_paths('lib', + [self.VCLibraries, + self.OSLibraries, + self.FxTools, + self.UCRTLibraries, + self.NetFxSDKLibraries], + exists), + libpath=self._build_paths('libpath', + [self.VCLibraries, + self.FxTools, + self.VCStoreRefs, + self.OSLibpath], + exists), + path=self._build_paths('path', + [self.VCTools, + self.VSTools, + self.VsTDb, + self.SdkTools, + self.SdkSetup, + self.FxTools, + self.MSBuild, + self.HTMLHelpWorkshop, + self.FSharp], + exists), + ) + if self.vc_ver >= 14 and os.path.isfile(self.VCRuntimeRedist): + env['py_vcruntime_redist'] = self.VCRuntimeRedist + return env + + def _build_paths(self, name, spec_path_lists, exists): + """ + Given an environment variable name and specified paths, + return a pathsep-separated string of paths containing + unique, extant, directories from those paths and from + the environment variable. Raise an error if no paths + are resolved. + """ + # flatten spec_path_lists + spec_paths = itertools.chain.from_iterable(spec_path_lists) + env_paths = safe_env.get(name, '').split(os.pathsep) + paths = itertools.chain(spec_paths, env_paths) + extant_paths = list(filter(os.path.isdir, paths)) if exists else paths + if not extant_paths: + msg = "%s environment variable is empty" % name.upper() + raise distutils.errors.DistutilsPlatformError(msg) + unique_paths = self._unique_everseen(extant_paths) + return os.pathsep.join(unique_paths) + + # from Python docs + def _unique_everseen(self, iterable, key=None): + """ + List unique elements, preserving order. + Remember all elements ever seen. + + _unique_everseen('AAAABBBCCDAABBB') --> A B C D + + _unique_everseen('ABBCcAD', str.lower) --> A B C D + """ + seen = set() + seen_add = seen.add + if key is None: + for element in filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element diff --git a/env/lib/python3.7/site-packages/setuptools/namespaces.py b/env/lib/python3.7/site-packages/setuptools/namespaces.py new file mode 100644 index 0000000..dc16106 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/namespaces.py @@ -0,0 +1,107 @@ +import os +from distutils import log +import itertools + +from setuptools.extern.six.moves import map + + +flatten = itertools.chain.from_iterable + + +class Installer: + + nspkg_ext = '-nspkg.pth' + + def install_namespaces(self): + nsp = self._get_all_ns_packages() + if not nsp: + return + filename, ext = os.path.splitext(self._get_target()) + filename += self.nspkg_ext + self.outputs.append(filename) + log.info("Installing %s", filename) + lines = map(self._gen_nspkg_line, nsp) + + if self.dry_run: + # always generate the lines, even in dry run + list(lines) + return + + with open(filename, 'wt') as f: + f.writelines(lines) + + def uninstall_namespaces(self): + filename, ext = os.path.splitext(self._get_target()) + filename += self.nspkg_ext + if not os.path.exists(filename): + return + log.info("Removing %s", filename) + os.remove(filename) + + def _get_target(self): + return self.target + + _nspkg_tmpl = ( + "import sys, types, os", + "has_mfs = sys.version_info > (3, 5)", + "p = os.path.join(%(root)s, *%(pth)r)", + "importlib = has_mfs and __import__('importlib.util')", + "has_mfs and __import__('importlib.machinery')", + "m = has_mfs and " + "sys.modules.setdefault(%(pkg)r, " + "importlib.util.module_from_spec(" + "importlib.machinery.PathFinder.find_spec(%(pkg)r, " + "[os.path.dirname(p)])))", + "m = m or " + "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))", + "mp = (m or []) and m.__dict__.setdefault('__path__',[])", + "(p not in mp) and mp.append(p)", + ) + "lines for the namespace installer" + + _nspkg_tmpl_multi = ( + 'm and setattr(sys.modules[%(parent)r], %(child)r, m)', + ) + "additional line(s) when a parent package is indicated" + + def _get_root(self): + return "sys._getframe(1).f_locals['sitedir']" + + def _gen_nspkg_line(self, pkg): + # ensure pkg is not a unicode string under Python 2.7 + pkg = str(pkg) + pth = tuple(pkg.split('.')) + root = self._get_root() + tmpl_lines = self._nspkg_tmpl + parent, sep, child = pkg.rpartition('.') + if parent: + tmpl_lines += self._nspkg_tmpl_multi + return ';'.join(tmpl_lines) % locals() + '\n' + + def _get_all_ns_packages(self): + """Return sorted list of all package namespaces""" + pkgs = self.distribution.namespace_packages or [] + return sorted(flatten(map(self._pkg_names, pkgs))) + + @staticmethod + def _pkg_names(pkg): + """ + Given a namespace package, yield the components of that + package. + + >>> names = Installer._pkg_names('a.b.c') + >>> set(names) == set(['a', 'a.b', 'a.b.c']) + True + """ + parts = pkg.split('.') + while parts: + yield '.'.join(parts) + parts.pop() + + +class DevelopInstaller(Installer): + def _get_root(self): + return repr(str(self.egg_path)) + + def _get_target(self): + return self.egg_link diff --git a/env/lib/python3.7/site-packages/setuptools/package_index.py b/env/lib/python3.7/site-packages/setuptools/package_index.py new file mode 100644 index 0000000..1608b91 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/package_index.py @@ -0,0 +1,1128 @@ +"""PyPI and direct package downloading""" +import sys +import os +import re +import shutil +import socket +import base64 +import hashlib +import itertools +import warnings +from functools import wraps + +from setuptools.extern import six +from setuptools.extern.six.moves import urllib, http_client, configparser, map + +import setuptools +from pkg_resources import ( + CHECKOUT_DIST, Distribution, BINARY_DIST, normalize_path, SOURCE_DIST, + Environment, find_distributions, safe_name, safe_version, + to_filename, Requirement, DEVELOP_DIST, EGG_DIST, +) +from setuptools import ssl_support +from distutils import log +from distutils.errors import DistutilsError +from fnmatch import translate +from setuptools.py27compat import get_all_headers +from setuptools.py33compat import unescape +from setuptools.wheel import Wheel + +__metaclass__ = type + +EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$') +HREF = re.compile(r"""href\s*=\s*['"]?([^'"> ]+)""", re.I) +PYPI_MD5 = re.compile( + r'<a href="([^"#]+)">([^<]+)</a>\n\s+\(<a (?:title="MD5 hash"\n\s+)' + r'href="[^?]+\?:action=show_md5&digest=([0-9a-f]{32})">md5</a>\)' +) +URL_SCHEME = re.compile('([-+.a-z0-9]{2,}):', re.I).match +EXTENSIONS = ".tar.gz .tar.bz2 .tar .zip .tgz".split() + +__all__ = [ + 'PackageIndex', 'distros_for_url', 'parse_bdist_wininst', + 'interpret_distro_name', +] + +_SOCKET_TIMEOUT = 15 + +_tmpl = "setuptools/{setuptools.__version__} Python-urllib/{py_major}" +user_agent = _tmpl.format(py_major=sys.version[:3], setuptools=setuptools) + + +def parse_requirement_arg(spec): + try: + return Requirement.parse(spec) + except ValueError: + raise DistutilsError( + "Not a URL, existing file, or requirement spec: %r" % (spec,) + ) + + +def parse_bdist_wininst(name): + """Return (base,pyversion) or (None,None) for possible .exe name""" + + lower = name.lower() + base, py_ver, plat = None, None, None + + if lower.endswith('.exe'): + if lower.endswith('.win32.exe'): + base = name[:-10] + plat = 'win32' + elif lower.startswith('.win32-py', -16): + py_ver = name[-7:-4] + base = name[:-16] + plat = 'win32' + elif lower.endswith('.win-amd64.exe'): + base = name[:-14] + plat = 'win-amd64' + elif lower.startswith('.win-amd64-py', -20): + py_ver = name[-7:-4] + base = name[:-20] + plat = 'win-amd64' + return base, py_ver, plat + + +def egg_info_for_url(url): + parts = urllib.parse.urlparse(url) + scheme, server, path, parameters, query, fragment = parts + base = urllib.parse.unquote(path.split('/')[-1]) + if server == 'sourceforge.net' and base == 'download': # XXX Yuck + base = urllib.parse.unquote(path.split('/')[-2]) + if '#' in base: + base, fragment = base.split('#', 1) + return base, fragment + + +def distros_for_url(url, metadata=None): + """Yield egg or source distribution objects that might be found at a URL""" + base, fragment = egg_info_for_url(url) + for dist in distros_for_location(url, base, metadata): + yield dist + if fragment: + match = EGG_FRAGMENT.match(fragment) + if match: + for dist in interpret_distro_name( + url, match.group(1), metadata, precedence=CHECKOUT_DIST + ): + yield dist + + +def distros_for_location(location, basename, metadata=None): + """Yield egg or source distribution objects based on basename""" + if basename.endswith('.egg.zip'): + basename = basename[:-4] # strip the .zip + if basename.endswith('.egg') and '-' in basename: + # only one, unambiguous interpretation + return [Distribution.from_location(location, basename, metadata)] + if basename.endswith('.whl') and '-' in basename: + wheel = Wheel(basename) + if not wheel.is_compatible(): + return [] + return [Distribution( + location=location, + project_name=wheel.project_name, + version=wheel.version, + # Increase priority over eggs. + precedence=EGG_DIST + 1, + )] + if basename.endswith('.exe'): + win_base, py_ver, platform = parse_bdist_wininst(basename) + if win_base is not None: + return interpret_distro_name( + location, win_base, metadata, py_ver, BINARY_DIST, platform + ) + # Try source distro extensions (.zip, .tgz, etc.) + # + for ext in EXTENSIONS: + if basename.endswith(ext): + basename = basename[:-len(ext)] + return interpret_distro_name(location, basename, metadata) + return [] # no extension matched + + +def distros_for_filename(filename, metadata=None): + """Yield possible egg or source distribution objects based on a filename""" + return distros_for_location( + normalize_path(filename), os.path.basename(filename), metadata + ) + + +def interpret_distro_name( + location, basename, metadata, py_version=None, precedence=SOURCE_DIST, + platform=None +): + """Generate alternative interpretations of a source distro name + + Note: if `location` is a filesystem filename, you should call + ``pkg_resources.normalize_path()`` on it before passing it to this + routine! + """ + # Generate alternative interpretations of a source distro name + # Because some packages are ambiguous as to name/versions split + # e.g. "adns-python-1.1.0", "egenix-mx-commercial", etc. + # So, we generate each possible interepretation (e.g. "adns, python-1.1.0" + # "adns-python, 1.1.0", and "adns-python-1.1.0, no version"). In practice, + # the spurious interpretations should be ignored, because in the event + # there's also an "adns" package, the spurious "python-1.1.0" version will + # compare lower than any numeric version number, and is therefore unlikely + # to match a request for it. It's still a potential problem, though, and + # in the long run PyPI and the distutils should go for "safe" names and + # versions in distribution archive names (sdist and bdist). + + parts = basename.split('-') + if not py_version and any(re.match(r'py\d\.\d$', p) for p in parts[2:]): + # it is a bdist_dumb, not an sdist -- bail out + return + + for p in range(1, len(parts) + 1): + yield Distribution( + location, metadata, '-'.join(parts[:p]), '-'.join(parts[p:]), + py_version=py_version, precedence=precedence, + platform=platform + ) + + +# From Python 2.7 docs +def unique_everseen(iterable, key=None): + "List unique elements, preserving order. Remember all elements ever seen." + # unique_everseen('AAAABBBCCDAABBB') --> A B C D + # unique_everseen('ABBCcAD', str.lower) --> A B C D + seen = set() + seen_add = seen.add + if key is None: + for element in six.moves.filterfalse(seen.__contains__, iterable): + seen_add(element) + yield element + else: + for element in iterable: + k = key(element) + if k not in seen: + seen_add(k) + yield element + + +def unique_values(func): + """ + Wrap a function returning an iterable such that the resulting iterable + only ever yields unique items. + """ + + @wraps(func) + def wrapper(*args, **kwargs): + return unique_everseen(func(*args, **kwargs)) + + return wrapper + + +REL = re.compile(r"""<([^>]*\srel\s*=\s*['"]?([^'">]+)[^>]*)>""", re.I) +# this line is here to fix emacs' cruddy broken syntax highlighting + + +@unique_values +def find_external_links(url, page): + """Find rel="homepage" and rel="download" links in `page`, yielding URLs""" + + for match in REL.finditer(page): + tag, rel = match.groups() + rels = set(map(str.strip, rel.lower().split(','))) + if 'homepage' in rels or 'download' in rels: + for match in HREF.finditer(tag): + yield urllib.parse.urljoin(url, htmldecode(match.group(1))) + + for tag in ("<th>Home Page", "<th>Download URL"): + pos = page.find(tag) + if pos != -1: + match = HREF.search(page, pos) + if match: + yield urllib.parse.urljoin(url, htmldecode(match.group(1))) + + +class ContentChecker: + """ + A null content checker that defines the interface for checking content + """ + + def feed(self, block): + """ + Feed a block of data to the hash. + """ + return + + def is_valid(self): + """ + Check the hash. Return False if validation fails. + """ + return True + + def report(self, reporter, template): + """ + Call reporter with information about the checker (hash name) + substituted into the template. + """ + return + + +class HashChecker(ContentChecker): + pattern = re.compile( + r'(?P<hash_name>sha1|sha224|sha384|sha256|sha512|md5)=' + r'(?P<expected>[a-f0-9]+)' + ) + + def __init__(self, hash_name, expected): + self.hash_name = hash_name + self.hash = hashlib.new(hash_name) + self.expected = expected + + @classmethod + def from_url(cls, url): + "Construct a (possibly null) ContentChecker from a URL" + fragment = urllib.parse.urlparse(url)[-1] + if not fragment: + return ContentChecker() + match = cls.pattern.search(fragment) + if not match: + return ContentChecker() + return cls(**match.groupdict()) + + def feed(self, block): + self.hash.update(block) + + def is_valid(self): + return self.hash.hexdigest() == self.expected + + def report(self, reporter, template): + msg = template % self.hash_name + return reporter(msg) + + +class PackageIndex(Environment): + """A distribution index that scans web pages for download URLs""" + + def __init__( + self, index_url="https://pypi.org/simple/", hosts=('*',), + ca_bundle=None, verify_ssl=True, *args, **kw + ): + Environment.__init__(self, *args, **kw) + self.index_url = index_url + "/" [:not index_url.endswith('/')] + self.scanned_urls = {} + self.fetched_urls = {} + self.package_pages = {} + self.allows = re.compile('|'.join(map(translate, hosts))).match + self.to_scan = [] + use_ssl = ( + verify_ssl + and ssl_support.is_available + and (ca_bundle or ssl_support.find_ca_bundle()) + ) + if use_ssl: + self.opener = ssl_support.opener_for(ca_bundle) + else: + self.opener = urllib.request.urlopen + + def process_url(self, url, retrieve=False): + """Evaluate a URL as a possible download, and maybe retrieve it""" + if url in self.scanned_urls and not retrieve: + return + self.scanned_urls[url] = True + if not URL_SCHEME(url): + self.process_filename(url) + return + else: + dists = list(distros_for_url(url)) + if dists: + if not self.url_ok(url): + return + self.debug("Found link: %s", url) + + if dists or not retrieve or url in self.fetched_urls: + list(map(self.add, dists)) + return # don't need the actual page + + if not self.url_ok(url): + self.fetched_urls[url] = True + return + + self.info("Reading %s", url) + self.fetched_urls[url] = True # prevent multiple fetch attempts + tmpl = "Download error on %s: %%s -- Some packages may not be found!" + f = self.open_url(url, tmpl % url) + if f is None: + return + self.fetched_urls[f.url] = True + if 'html' not in f.headers.get('content-type', '').lower(): + f.close() # not html, we can't process it + return + + base = f.url # handle redirects + page = f.read() + if not isinstance(page, str): + # In Python 3 and got bytes but want str. + if isinstance(f, urllib.error.HTTPError): + # Errors have no charset, assume latin1: + charset = 'latin-1' + else: + charset = f.headers.get_param('charset') or 'latin-1' + page = page.decode(charset, "ignore") + f.close() + for match in HREF.finditer(page): + link = urllib.parse.urljoin(base, htmldecode(match.group(1))) + self.process_url(link) + if url.startswith(self.index_url) and getattr(f, 'code', None) != 404: + page = self.process_index(url, page) + + def process_filename(self, fn, nested=False): + # process filenames or directories + if not os.path.exists(fn): + self.warn("Not found: %s", fn) + return + + if os.path.isdir(fn) and not nested: + path = os.path.realpath(fn) + for item in os.listdir(path): + self.process_filename(os.path.join(path, item), True) + + dists = distros_for_filename(fn) + if dists: + self.debug("Found: %s", fn) + list(map(self.add, dists)) + + def url_ok(self, url, fatal=False): + s = URL_SCHEME(url) + is_file = s and s.group(1).lower() == 'file' + if is_file or self.allows(urllib.parse.urlparse(url)[1]): + return True + msg = ( + "\nNote: Bypassing %s (disallowed host; see " + "http://bit.ly/2hrImnY for details).\n") + if fatal: + raise DistutilsError(msg % url) + else: + self.warn(msg, url) + + def scan_egg_links(self, search_path): + dirs = filter(os.path.isdir, search_path) + egg_links = ( + (path, entry) + for path in dirs + for entry in os.listdir(path) + if entry.endswith('.egg-link') + ) + list(itertools.starmap(self.scan_egg_link, egg_links)) + + def scan_egg_link(self, path, entry): + with open(os.path.join(path, entry)) as raw_lines: + # filter non-empty lines + lines = list(filter(None, map(str.strip, raw_lines))) + + if len(lines) != 2: + # format is not recognized; punt + return + + egg_path, setup_path = lines + + for dist in find_distributions(os.path.join(path, egg_path)): + dist.location = os.path.join(path, *lines) + dist.precedence = SOURCE_DIST + self.add(dist) + + def process_index(self, url, page): + """Process the contents of a PyPI page""" + + def scan(link): + # Process a URL to see if it's for a package page + if link.startswith(self.index_url): + parts = list(map( + urllib.parse.unquote, link[len(self.index_url):].split('/') + )) + if len(parts) == 2 and '#' not in parts[1]: + # it's a package page, sanitize and index it + pkg = safe_name(parts[0]) + ver = safe_version(parts[1]) + self.package_pages.setdefault(pkg.lower(), {})[link] = True + return to_filename(pkg), to_filename(ver) + return None, None + + # process an index page into the package-page index + for match in HREF.finditer(page): + try: + scan(urllib.parse.urljoin(url, htmldecode(match.group(1)))) + except ValueError: + pass + + pkg, ver = scan(url) # ensure this page is in the page index + if pkg: + # process individual package page + for new_url in find_external_links(url, page): + # Process the found URL + base, frag = egg_info_for_url(new_url) + if base.endswith('.py') and not frag: + if ver: + new_url += '#egg=%s-%s' % (pkg, ver) + else: + self.need_version_info(url) + self.scan_url(new_url) + + return PYPI_MD5.sub( + lambda m: '<a href="%s#md5=%s">%s</a>' % m.group(1, 3, 2), page + ) + else: + return "" # no sense double-scanning non-package pages + + def need_version_info(self, url): + self.scan_all( + "Page at %s links to .py file(s) without version info; an index " + "scan is required.", url + ) + + def scan_all(self, msg=None, *args): + if self.index_url not in self.fetched_urls: + if msg: + self.warn(msg, *args) + self.info( + "Scanning index of all packages (this may take a while)" + ) + self.scan_url(self.index_url) + + def find_packages(self, requirement): + self.scan_url(self.index_url + requirement.unsafe_name + '/') + + if not self.package_pages.get(requirement.key): + # Fall back to safe version of the name + self.scan_url(self.index_url + requirement.project_name + '/') + + if not self.package_pages.get(requirement.key): + # We couldn't find the target package, so search the index page too + self.not_found_in_index(requirement) + + for url in list(self.package_pages.get(requirement.key, ())): + # scan each page that might be related to the desired package + self.scan_url(url) + + def obtain(self, requirement, installer=None): + self.prescan() + self.find_packages(requirement) + for dist in self[requirement.key]: + if dist in requirement: + return dist + self.debug("%s does not match %s", requirement, dist) + return super(PackageIndex, self).obtain(requirement, installer) + + def check_hash(self, checker, filename, tfp): + """ + checker is a ContentChecker + """ + checker.report( + self.debug, + "Validating %%s checksum for %s" % filename) + if not checker.is_valid(): + tfp.close() + os.unlink(filename) + raise DistutilsError( + "%s validation failed for %s; " + "possible download problem?" + % (checker.hash.name, os.path.basename(filename)) + ) + + def add_find_links(self, urls): + """Add `urls` to the list that will be prescanned for searches""" + for url in urls: + if ( + self.to_scan is None # if we have already "gone online" + or not URL_SCHEME(url) # or it's a local file/directory + or url.startswith('file:') + or list(distros_for_url(url)) # or a direct package link + ): + # then go ahead and process it now + self.scan_url(url) + else: + # otherwise, defer retrieval till later + self.to_scan.append(url) + + def prescan(self): + """Scan urls scheduled for prescanning (e.g. --find-links)""" + if self.to_scan: + list(map(self.scan_url, self.to_scan)) + self.to_scan = None # from now on, go ahead and process immediately + + def not_found_in_index(self, requirement): + if self[requirement.key]: # we've seen at least one distro + meth, msg = self.info, "Couldn't retrieve index page for %r" + else: # no distros seen for this name, might be misspelled + meth, msg = ( + self.warn, + "Couldn't find index page for %r (maybe misspelled?)") + meth(msg, requirement.unsafe_name) + self.scan_all() + + def download(self, spec, tmpdir): + """Locate and/or download `spec` to `tmpdir`, returning a local path + + `spec` may be a ``Requirement`` object, or a string containing a URL, + an existing local filename, or a project/version requirement spec + (i.e. the string form of a ``Requirement`` object). If it is the URL + of a .py file with an unambiguous ``#egg=name-version`` tag (i.e., one + that escapes ``-`` as ``_`` throughout), a trivial ``setup.py`` is + automatically created alongside the downloaded file. + + If `spec` is a ``Requirement`` object or a string containing a + project/version requirement spec, this method returns the location of + a matching distribution (possibly after downloading it to `tmpdir`). + If `spec` is a locally existing file or directory name, it is simply + returned unchanged. If `spec` is a URL, it is downloaded to a subpath + of `tmpdir`, and the local filename is returned. Various errors may be + raised if a problem occurs during downloading. + """ + if not isinstance(spec, Requirement): + scheme = URL_SCHEME(spec) + if scheme: + # It's a url, download it to tmpdir + found = self._download_url(scheme.group(1), spec, tmpdir) + base, fragment = egg_info_for_url(spec) + if base.endswith('.py'): + found = self.gen_setup(found, fragment, tmpdir) + return found + elif os.path.exists(spec): + # Existing file or directory, just return it + return spec + else: + spec = parse_requirement_arg(spec) + return getattr(self.fetch_distribution(spec, tmpdir), 'location', None) + + def fetch_distribution( + self, requirement, tmpdir, force_scan=False, source=False, + develop_ok=False, local_index=None): + """Obtain a distribution suitable for fulfilling `requirement` + + `requirement` must be a ``pkg_resources.Requirement`` instance. + If necessary, or if the `force_scan` flag is set, the requirement is + searched for in the (online) package index as well as the locally + installed packages. If a distribution matching `requirement` is found, + the returned distribution's ``location`` is the value you would have + gotten from calling the ``download()`` method with the matching + distribution's URL or filename. If no matching distribution is found, + ``None`` is returned. + + If the `source` flag is set, only source distributions and source + checkout links will be considered. Unless the `develop_ok` flag is + set, development and system eggs (i.e., those using the ``.egg-info`` + format) will be ignored. + """ + # process a Requirement + self.info("Searching for %s", requirement) + skipped = {} + dist = None + + def find(req, env=None): + if env is None: + env = self + # Find a matching distribution; may be called more than once + + for dist in env[req.key]: + + if dist.precedence == DEVELOP_DIST and not develop_ok: + if dist not in skipped: + self.warn( + "Skipping development or system egg: %s", dist, + ) + skipped[dist] = 1 + continue + + test = ( + dist in req + and (dist.precedence <= SOURCE_DIST or not source) + ) + if test: + loc = self.download(dist.location, tmpdir) + dist.download_location = loc + if os.path.exists(dist.download_location): + return dist + + if force_scan: + self.prescan() + self.find_packages(requirement) + dist = find(requirement) + + if not dist and local_index is not None: + dist = find(requirement, local_index) + + if dist is None: + if self.to_scan is not None: + self.prescan() + dist = find(requirement) + + if dist is None and not force_scan: + self.find_packages(requirement) + dist = find(requirement) + + if dist is None: + self.warn( + "No local packages or working download links found for %s%s", + (source and "a source distribution of " or ""), + requirement, + ) + else: + self.info("Best match: %s", dist) + return dist.clone(location=dist.download_location) + + def fetch(self, requirement, tmpdir, force_scan=False, source=False): + """Obtain a file suitable for fulfilling `requirement` + + DEPRECATED; use the ``fetch_distribution()`` method now instead. For + backward compatibility, this routine is identical but returns the + ``location`` of the downloaded distribution instead of a distribution + object. + """ + dist = self.fetch_distribution(requirement, tmpdir, force_scan, source) + if dist is not None: + return dist.location + return None + + def gen_setup(self, filename, fragment, tmpdir): + match = EGG_FRAGMENT.match(fragment) + dists = match and [ + d for d in + interpret_distro_name(filename, match.group(1), None) if d.version + ] or [] + + if len(dists) == 1: # unambiguous ``#egg`` fragment + basename = os.path.basename(filename) + + # Make sure the file has been downloaded to the temp dir. + if os.path.dirname(filename) != tmpdir: + dst = os.path.join(tmpdir, basename) + from setuptools.command.easy_install import samefile + if not samefile(filename, dst): + shutil.copy2(filename, dst) + filename = dst + + with open(os.path.join(tmpdir, 'setup.py'), 'w') as file: + file.write( + "from setuptools import setup\n" + "setup(name=%r, version=%r, py_modules=[%r])\n" + % ( + dists[0].project_name, dists[0].version, + os.path.splitext(basename)[0] + ) + ) + return filename + + elif match: + raise DistutilsError( + "Can't unambiguously interpret project/version identifier %r; " + "any dashes in the name or version should be escaped using " + "underscores. %r" % (fragment, dists) + ) + else: + raise DistutilsError( + "Can't process plain .py files without an '#egg=name-version'" + " suffix to enable automatic setup script generation." + ) + + dl_blocksize = 8192 + + def _download_to(self, url, filename): + self.info("Downloading %s", url) + # Download the file + fp = None + try: + checker = HashChecker.from_url(url) + fp = self.open_url(url) + if isinstance(fp, urllib.error.HTTPError): + raise DistutilsError( + "Can't download %s: %s %s" % (url, fp.code, fp.msg) + ) + headers = fp.info() + blocknum = 0 + bs = self.dl_blocksize + size = -1 + if "content-length" in headers: + # Some servers return multiple Content-Length headers :( + sizes = get_all_headers(headers, 'Content-Length') + size = max(map(int, sizes)) + self.reporthook(url, filename, blocknum, bs, size) + with open(filename, 'wb') as tfp: + while True: + block = fp.read(bs) + if block: + checker.feed(block) + tfp.write(block) + blocknum += 1 + self.reporthook(url, filename, blocknum, bs, size) + else: + break + self.check_hash(checker, filename, tfp) + return headers + finally: + if fp: + fp.close() + + def reporthook(self, url, filename, blocknum, blksize, size): + pass # no-op + + def open_url(self, url, warning=None): + if url.startswith('file:'): + return local_open(url) + try: + return open_with_auth(url, self.opener) + except (ValueError, http_client.InvalidURL) as v: + msg = ' '.join([str(arg) for arg in v.args]) + if warning: + self.warn(warning, msg) + else: + raise DistutilsError('%s %s' % (url, msg)) + except urllib.error.HTTPError as v: + return v + except urllib.error.URLError as v: + if warning: + self.warn(warning, v.reason) + else: + raise DistutilsError("Download error for %s: %s" + % (url, v.reason)) + except http_client.BadStatusLine as v: + if warning: + self.warn(warning, v.line) + else: + raise DistutilsError( + '%s returned a bad status line. The server might be ' + 'down, %s' % + (url, v.line) + ) + except (http_client.HTTPException, socket.error) as v: + if warning: + self.warn(warning, v) + else: + raise DistutilsError("Download error for %s: %s" + % (url, v)) + + def _download_url(self, scheme, url, tmpdir): + # Determine download filename + # + name, fragment = egg_info_for_url(url) + if name: + while '..' in name: + name = name.replace('..', '.').replace('\\', '_') + else: + name = "__downloaded__" # default if URL has no path contents + + if name.endswith('.egg.zip'): + name = name[:-4] # strip the extra .zip before download + + filename = os.path.join(tmpdir, name) + + # Download the file + # + if scheme == 'svn' or scheme.startswith('svn+'): + return self._download_svn(url, filename) + elif scheme == 'git' or scheme.startswith('git+'): + return self._download_git(url, filename) + elif scheme.startswith('hg+'): + return self._download_hg(url, filename) + elif scheme == 'file': + return urllib.request.url2pathname(urllib.parse.urlparse(url)[2]) + else: + self.url_ok(url, True) # raises error if not allowed + return self._attempt_download(url, filename) + + def scan_url(self, url): + self.process_url(url, True) + + def _attempt_download(self, url, filename): + headers = self._download_to(url, filename) + if 'html' in headers.get('content-type', '').lower(): + return self._download_html(url, headers, filename) + else: + return filename + + def _download_html(self, url, headers, filename): + file = open(filename) + for line in file: + if line.strip(): + # Check for a subversion index page + if re.search(r'<title>([^- ]+ - )?Revision \d+:', line): + # it's a subversion index page: + file.close() + os.unlink(filename) + return self._download_svn(url, filename) + break # not an index page + file.close() + os.unlink(filename) + raise DistutilsError("Unexpected HTML page found at " + url) + + def _download_svn(self, url, filename): + warnings.warn("SVN download support is deprecated", UserWarning) + url = url.split('#', 1)[0] # remove any fragment for svn's sake + creds = '' + if url.lower().startswith('svn:') and '@' in url: + scheme, netloc, path, p, q, f = urllib.parse.urlparse(url) + if not netloc and path.startswith('//') and '/' in path[2:]: + netloc, path = path[2:].split('/', 1) + auth, host = urllib.parse.splituser(netloc) + if auth: + if ':' in auth: + user, pw = auth.split(':', 1) + creds = " --username=%s --password=%s" % (user, pw) + else: + creds = " --username=" + auth + netloc = host + parts = scheme, netloc, url, p, q, f + url = urllib.parse.urlunparse(parts) + self.info("Doing subversion checkout from %s to %s", url, filename) + os.system("svn checkout%s -q %s %s" % (creds, url, filename)) + return filename + + @staticmethod + def _vcs_split_rev_from_url(url, pop_prefix=False): + scheme, netloc, path, query, frag = urllib.parse.urlsplit(url) + + scheme = scheme.split('+', 1)[-1] + + # Some fragment identification fails + path = path.split('#', 1)[0] + + rev = None + if '@' in path: + path, rev = path.rsplit('@', 1) + + # Also, discard fragment + url = urllib.parse.urlunsplit((scheme, netloc, path, query, '')) + + return url, rev + + def _download_git(self, url, filename): + filename = filename.split('#', 1)[0] + url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) + + self.info("Doing git clone from %s to %s", url, filename) + os.system("git clone --quiet %s %s" % (url, filename)) + + if rev is not None: + self.info("Checking out %s", rev) + os.system("(cd %s && git checkout --quiet %s)" % ( + filename, + rev, + )) + + return filename + + def _download_hg(self, url, filename): + filename = filename.split('#', 1)[0] + url, rev = self._vcs_split_rev_from_url(url, pop_prefix=True) + + self.info("Doing hg clone from %s to %s", url, filename) + os.system("hg clone --quiet %s %s" % (url, filename)) + + if rev is not None: + self.info("Updating to %s", rev) + os.system("(cd %s && hg up -C -r %s -q)" % ( + filename, + rev, + )) + + return filename + + def debug(self, msg, *args): + log.debug(msg, *args) + + def info(self, msg, *args): + log.info(msg, *args) + + def warn(self, msg, *args): + log.warn(msg, *args) + + +# This pattern matches a character entity reference (a decimal numeric +# references, a hexadecimal numeric reference, or a named reference). +entity_sub = re.compile(r'&(#(\d+|x[\da-fA-F]+)|[\w.:-]+);?').sub + + +def decode_entity(match): + what = match.group(0) + return unescape(what) + + +def htmldecode(text): + """ + Decode HTML entities in the given text. + + >>> htmldecode( + ... 'https://../package_name-0.1.2.tar.gz' + ... '?tokena=A&tokenb=B">package_name-0.1.2.tar.gz') + 'https://../package_name-0.1.2.tar.gz?tokena=A&tokenb=B">package_name-0.1.2.tar.gz' + """ + return entity_sub(decode_entity, text) + + +def socket_timeout(timeout=15): + def _socket_timeout(func): + def _socket_timeout(*args, **kwargs): + old_timeout = socket.getdefaulttimeout() + socket.setdefaulttimeout(timeout) + try: + return func(*args, **kwargs) + finally: + socket.setdefaulttimeout(old_timeout) + + return _socket_timeout + + return _socket_timeout + + +def _encode_auth(auth): + """ + A function compatible with Python 2.3-3.3 that will encode + auth from a URL suitable for an HTTP header. + >>> str(_encode_auth('username%3Apassword')) + 'dXNlcm5hbWU6cGFzc3dvcmQ=' + + Long auth strings should not cause a newline to be inserted. + >>> long_auth = 'username:' + 'password'*10 + >>> chr(10) in str(_encode_auth(long_auth)) + False + """ + auth_s = urllib.parse.unquote(auth) + # convert to bytes + auth_bytes = auth_s.encode() + encoded_bytes = base64.b64encode(auth_bytes) + # convert back to a string + encoded = encoded_bytes.decode() + # strip the trailing carriage return + return encoded.replace('\n', '') + + +class Credential: + """ + A username/password pair. Use like a namedtuple. + """ + + def __init__(self, username, password): + self.username = username + self.password = password + + def __iter__(self): + yield self.username + yield self.password + + def __str__(self): + return '%(username)s:%(password)s' % vars(self) + + +class PyPIConfig(configparser.RawConfigParser): + def __init__(self): + """ + Load from ~/.pypirc + """ + defaults = dict.fromkeys(['username', 'password', 'repository'], '') + configparser.RawConfigParser.__init__(self, defaults) + + rc = os.path.join(os.path.expanduser('~'), '.pypirc') + if os.path.exists(rc): + self.read(rc) + + @property + def creds_by_repository(self): + sections_with_repositories = [ + section for section in self.sections() + if self.get(section, 'repository').strip() + ] + + return dict(map(self._get_repo_cred, sections_with_repositories)) + + def _get_repo_cred(self, section): + repo = self.get(section, 'repository').strip() + return repo, Credential( + self.get(section, 'username').strip(), + self.get(section, 'password').strip(), + ) + + def find_credential(self, url): + """ + If the URL indicated appears to be a repository defined in this + config, return the credential for that repository. + """ + for repository, cred in self.creds_by_repository.items(): + if url.startswith(repository): + return cred + + +def open_with_auth(url, opener=urllib.request.urlopen): + """Open a urllib2 request, handling HTTP authentication""" + + scheme, netloc, path, params, query, frag = urllib.parse.urlparse(url) + + # Double scheme does not raise on Mac OS X as revealed by a + # failing test. We would expect "nonnumeric port". Refs #20. + if netloc.endswith(':'): + raise http_client.InvalidURL("nonnumeric port: ''") + + if scheme in ('http', 'https'): + auth, host = urllib.parse.splituser(netloc) + else: + auth = None + + if not auth: + cred = PyPIConfig().find_credential(url) + if cred: + auth = str(cred) + info = cred.username, url + log.info('Authenticating as %s for %s (from .pypirc)', *info) + + if auth: + auth = "Basic " + _encode_auth(auth) + parts = scheme, host, path, params, query, frag + new_url = urllib.parse.urlunparse(parts) + request = urllib.request.Request(new_url) + request.add_header("Authorization", auth) + else: + request = urllib.request.Request(url) + + request.add_header('User-Agent', user_agent) + fp = opener(request) + + if auth: + # Put authentication info back into request URL if same host, + # so that links found on the page will work + s2, h2, path2, param2, query2, frag2 = urllib.parse.urlparse(fp.url) + if s2 == scheme and h2 == host: + parts = s2, netloc, path2, param2, query2, frag2 + fp.url = urllib.parse.urlunparse(parts) + + return fp + + +# adding a timeout to avoid freezing package_index +open_with_auth = socket_timeout(_SOCKET_TIMEOUT)(open_with_auth) + + +def fix_sf_url(url): + return url # backward compatibility + + +def local_open(url): + """Read a local path, with special support for directories""" + scheme, server, path, param, query, frag = urllib.parse.urlparse(url) + filename = urllib.request.url2pathname(path) + if os.path.isfile(filename): + return urllib.request.urlopen(url) + elif path.endswith('/') and os.path.isdir(filename): + files = [] + for f in os.listdir(filename): + filepath = os.path.join(filename, f) + if f == 'index.html': + with open(filepath, 'r') as fp: + body = fp.read() + break + elif os.path.isdir(filepath): + f += '/' + files.append('<a href="{name}">{name}</a>'.format(name=f)) + else: + tmpl = ( + "<html><head><title>{url}" + "{files}") + body = tmpl.format(url=url, files='\n'.join(files)) + status, message = 200, "OK" + else: + status, message, body = 404, "Path not found", "Not found" + + headers = {'content-type': 'text/html'} + body_stream = six.StringIO(body) + return urllib.error.HTTPError(url, status, message, headers, body_stream) diff --git a/env/lib/python3.7/site-packages/setuptools/pep425tags.py b/env/lib/python3.7/site-packages/setuptools/pep425tags.py new file mode 100644 index 0000000..8bf4277 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/pep425tags.py @@ -0,0 +1,319 @@ +# This file originally from pip: +# https://github.com/pypa/pip/blob/8f4f15a5a95d7d5b511ceaee9ed261176c181970/src/pip/_internal/pep425tags.py +"""Generate and work with PEP 425 Compatibility Tags.""" +from __future__ import absolute_import + +import distutils.util +from distutils import log +import platform +import re +import sys +import sysconfig +import warnings +from collections import OrderedDict + +from .extern import six + +from . import glibc + +_osx_arch_pat = re.compile(r'(.+)_(\d+)_(\d+)_(.+)') + + +def get_config_var(var): + try: + return sysconfig.get_config_var(var) + except IOError as e: # Issue #1074 + warnings.warn("{}".format(e), RuntimeWarning) + return None + + +def get_abbr_impl(): + """Return abbreviated implementation name.""" + if hasattr(sys, 'pypy_version_info'): + pyimpl = 'pp' + elif sys.platform.startswith('java'): + pyimpl = 'jy' + elif sys.platform == 'cli': + pyimpl = 'ip' + else: + pyimpl = 'cp' + return pyimpl + + +def get_impl_ver(): + """Return implementation version.""" + impl_ver = get_config_var("py_version_nodot") + if not impl_ver or get_abbr_impl() == 'pp': + impl_ver = ''.join(map(str, get_impl_version_info())) + return impl_ver + + +def get_impl_version_info(): + """Return sys.version_info-like tuple for use in decrementing the minor + version.""" + if get_abbr_impl() == 'pp': + # as per https://github.com/pypa/pip/issues/2882 + return (sys.version_info[0], sys.pypy_version_info.major, + sys.pypy_version_info.minor) + else: + return sys.version_info[0], sys.version_info[1] + + +def get_impl_tag(): + """ + Returns the Tag for this specific implementation. + """ + return "{}{}".format(get_abbr_impl(), get_impl_ver()) + + +def get_flag(var, fallback, expected=True, warn=True): + """Use a fallback method for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + log.debug("Config variable '%s' is unset, Python ABI tag may " + "be incorrect", var) + return fallback() + return val == expected + + +def get_abi_tag(): + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = get_abbr_impl() + if not soabi and impl in {'cp', 'pp'} and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + lambda: hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + lambda: impl == 'cp', + warn=(impl == 'cp')): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + six.PY2)) \ + and six.PY2: + u = 'u' + abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + +def _is_running_32bit(): + return sys.maxsize == 2147483647 + + +def get_platform(): + """Return our platform name 'win32', 'linux_x86_64'""" + if sys.platform == 'darwin': + # distutils.util.get_platform() returns the release based on the value + # of MACOSX_DEPLOYMENT_TARGET on which Python was built, which may + # be significantly older than the user's current machine. + release, _, machine = platform.mac_ver() + split_ver = release.split('.') + + if machine == "x86_64" and _is_running_32bit(): + machine = "i386" + elif machine == "ppc64" and _is_running_32bit(): + machine = "ppc" + + return 'macosx_{}_{}_{}'.format(split_ver[0], split_ver[1], machine) + + # XXX remove distutils dependency + result = distutils.util.get_platform().replace('.', '_').replace('-', '_') + if result == "linux_x86_64" and _is_running_32bit(): + # 32 bit Python program (running on a 64 bit Linux): pip should only + # install and run 32 bit compiled extensions in that case. + result = "linux_i686" + + return result + + +def is_manylinux1_compatible(): + # Only Linux, and only x86-64 / i686 + if get_platform() not in {"linux_x86_64", "linux_i686"}: + return False + + # Check for presence of _manylinux module + try: + import _manylinux + return bool(_manylinux.manylinux1_compatible) + except (ImportError, AttributeError): + # Fall through to heuristic check below + pass + + # Check glibc version. CentOS 5 uses glibc 2.5. + return glibc.have_compatible_glibc(2, 5) + + +def get_darwin_arches(major, minor, machine): + """Return a list of supported arches (including group arches) for + the given major, minor and machine architecture of an macOS machine. + """ + arches = [] + + def _supports_arch(major, minor, arch): + # Looking at the application support for macOS versions in the chart + # provided by https://en.wikipedia.org/wiki/OS_X#Versions it appears + # our timeline looks roughly like: + # + # 10.0 - Introduces ppc support. + # 10.4 - Introduces ppc64, i386, and x86_64 support, however the ppc64 + # and x86_64 support is CLI only, and cannot be used for GUI + # applications. + # 10.5 - Extends ppc64 and x86_64 support to cover GUI applications. + # 10.6 - Drops support for ppc64 + # 10.7 - Drops support for ppc + # + # Given that we do not know if we're installing a CLI or a GUI + # application, we must be conservative and assume it might be a GUI + # application and behave as if ppc64 and x86_64 support did not occur + # until 10.5. + # + # Note: The above information is taken from the "Application support" + # column in the chart not the "Processor support" since I believe + # that we care about what instruction sets an application can use + # not which processors the OS supports. + if arch == 'ppc': + return (major, minor) <= (10, 5) + if arch == 'ppc64': + return (major, minor) == (10, 5) + if arch == 'i386': + return (major, minor) >= (10, 4) + if arch == 'x86_64': + return (major, minor) >= (10, 5) + if arch in groups: + for garch in groups[arch]: + if _supports_arch(major, minor, garch): + return True + return False + + groups = OrderedDict([ + ("fat", ("i386", "ppc")), + ("intel", ("x86_64", "i386")), + ("fat64", ("x86_64", "ppc64")), + ("fat32", ("x86_64", "i386", "ppc")), + ]) + + if _supports_arch(major, minor, machine): + arches.append(machine) + + for garch in groups: + if machine in groups[garch] and _supports_arch(major, minor, garch): + arches.append(garch) + + arches.append('universal') + + return arches + + +def get_supported(versions=None, noarch=False, platform=None, + impl=None, abi=None): + """Return a list of supported tags for each version specified in + `versions`. + + :param versions: a list of string versions, of the form ["33", "32"], + or None. The first version will be assumed to support our ABI. + :param platform: specify the exact platform you want valid + tags for, or None. If None, use the local system platform. + :param impl: specify the exact implementation you want valid + tags for, or None. If None, use the local interpreter impl. + :param abi: specify the exact abi you want valid + tags for, or None. If None, use the local interpreter abi. + """ + supported = [] + + # Versions must be given with respect to the preference + if versions is None: + versions = [] + version_info = get_impl_version_info() + major = version_info[:-1] + # Support all previous minor Python versions. + for minor in range(version_info[-1], -1, -1): + versions.append(''.join(map(str, major + (minor,)))) + + impl = impl or get_abbr_impl() + + abis = [] + + abi = abi or get_abi_tag() + if abi: + abis[0:0] = [abi] + + abi3s = set() + import imp + for suffix in imp.get_suffixes(): + if suffix[0].startswith('.abi'): + abi3s.add(suffix[0].split('.', 2)[1]) + + abis.extend(sorted(list(abi3s))) + + abis.append('none') + + if not noarch: + arch = platform or get_platform() + if arch.startswith('macosx'): + # support macosx-10.6-intel on macosx-10.9-x86_64 + match = _osx_arch_pat.match(arch) + if match: + name, major, minor, actual_arch = match.groups() + tpl = '{}_{}_%i_%s'.format(name, major) + arches = [] + for m in reversed(range(int(minor) + 1)): + for a in get_darwin_arches(int(major), m, actual_arch): + arches.append(tpl % (m, a)) + else: + # arch pattern didn't match (?!) + arches = [arch] + elif platform is None and is_manylinux1_compatible(): + arches = [arch.replace('linux', 'manylinux1'), arch] + else: + arches = [arch] + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in arches: + supported.append(('%s%s' % (impl, versions[0]), abi, arch)) + + # abi3 modules compatible with older version of Python + for version in versions[1:]: + # abi3 was introduced in Python 3.2 + if version in {'31', '30'}: + break + for abi in abi3s: # empty set if not Python 3 + for arch in arches: + supported.append(("%s%s" % (impl, version), abi, arch)) + + # Has binaries, does not use the Python API: + for arch in arches: + supported.append(('py%s' % (versions[0][0]), 'none', arch)) + + # No abi / arch, but requires our implementation: + supported.append(('%s%s' % (impl, versions[0]), 'none', 'any')) + # Tagged specifically as being cross-version compatible + # (with just the major version specified) + supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) + + # No abi / arch, generic Python + for i, version in enumerate(versions): + supported.append(('py%s' % (version,), 'none', 'any')) + if i == 0: + supported.append(('py%s' % (version[0]), 'none', 'any')) + + return supported + + +implementation_tag = get_impl_tag() diff --git a/env/lib/python3.7/site-packages/setuptools/py27compat.py b/env/lib/python3.7/site-packages/setuptools/py27compat.py new file mode 100644 index 0000000..2985011 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/py27compat.py @@ -0,0 +1,28 @@ +""" +Compatibility Support for Python 2.7 and earlier +""" + +import platform + +from setuptools.extern import six + + +def get_all_headers(message, key): + """ + Given an HTTPMessage, return all headers matching a given key. + """ + return message.get_all(key) + + +if six.PY2: + def get_all_headers(message, key): + return message.getheaders(key) + + +linux_py2_ascii = ( + platform.system() == 'Linux' and + six.PY2 +) + +rmtree_safe = str if linux_py2_ascii else lambda x: x +"""Workaround for http://bugs.python.org/issue24672""" diff --git a/env/lib/python3.7/site-packages/setuptools/py31compat.py b/env/lib/python3.7/site-packages/setuptools/py31compat.py new file mode 100644 index 0000000..1a0705e --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/py31compat.py @@ -0,0 +1,32 @@ +__all__ = [] + +__metaclass__ = type + + +try: + # Python >=3.2 + from tempfile import TemporaryDirectory +except ImportError: + import shutil + import tempfile + + class TemporaryDirectory: + """ + Very simple temporary directory context manager. + Will try to delete afterward, but will also ignore OS and similar + errors on deletion. + """ + + def __init__(self): + self.name = None # Handle mkdtemp raising an exception + self.name = tempfile.mkdtemp() + + def __enter__(self): + return self.name + + def __exit__(self, exctype, excvalue, exctrace): + try: + shutil.rmtree(self.name, True) + except OSError: # removal errors are not the only possible + pass + self.name = None diff --git a/env/lib/python3.7/site-packages/setuptools/py33compat.py b/env/lib/python3.7/site-packages/setuptools/py33compat.py new file mode 100644 index 0000000..87cf539 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/py33compat.py @@ -0,0 +1,55 @@ +import dis +import array +import collections + +try: + import html +except ImportError: + html = None + +from setuptools.extern import six +from setuptools.extern.six.moves import html_parser + +__metaclass__ = type + +OpArg = collections.namedtuple('OpArg', 'opcode arg') + + +class Bytecode_compat: + def __init__(self, code): + self.code = code + + def __iter__(self): + """Yield '(op,arg)' pair for each operation in code object 'code'""" + + bytes = array.array('b', self.code.co_code) + eof = len(self.code.co_code) + + ptr = 0 + extended_arg = 0 + + while ptr < eof: + + op = bytes[ptr] + + if op >= dis.HAVE_ARGUMENT: + + arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg + ptr += 3 + + if op == dis.EXTENDED_ARG: + long_type = six.integer_types[-1] + extended_arg = arg * long_type(65536) + continue + + else: + arg = None + ptr += 1 + + yield OpArg(op, arg) + + +Bytecode = getattr(dis, 'Bytecode', Bytecode_compat) + + +unescape = getattr(html, 'unescape', html_parser.HTMLParser().unescape) diff --git a/env/lib/python3.7/site-packages/setuptools/py36compat.py b/env/lib/python3.7/site-packages/setuptools/py36compat.py new file mode 100644 index 0000000..f527969 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/py36compat.py @@ -0,0 +1,82 @@ +import sys +from distutils.errors import DistutilsOptionError +from distutils.util import strtobool +from distutils.debug import DEBUG + + +class Distribution_parse_config_files: + """ + Mix-in providing forward-compatibility for functionality to be + included by default on Python 3.7. + + Do not edit the code in this class except to update functionality + as implemented in distutils. + """ + def parse_config_files(self, filenames=None): + from configparser import ConfigParser + + # Ignore install directory options if we have a venv + if sys.prefix != sys.base_prefix: + ignore_options = [ + 'install-base', 'install-platbase', 'install-lib', + 'install-platlib', 'install-purelib', 'install-headers', + 'install-scripts', 'install-data', 'prefix', 'exec-prefix', + 'home', 'user', 'root'] + else: + ignore_options = [] + + ignore_options = frozenset(ignore_options) + + if filenames is None: + filenames = self.find_config_files() + + if DEBUG: + self.announce("Distribution.parse_config_files():") + + parser = ConfigParser(interpolation=None) + for filename in filenames: + if DEBUG: + self.announce(" reading %s" % filename) + parser.read(filename) + for section in parser.sections(): + options = parser.options(section) + opt_dict = self.get_option_dict(section) + + for opt in options: + if opt != '__name__' and opt not in ignore_options: + val = parser.get(section,opt) + opt = opt.replace('-', '_') + opt_dict[opt] = (filename, val) + + # Make the ConfigParser forget everything (so we retain + # the original filenames that options come from) + parser.__init__() + + # If there was a "global" section in the config file, use it + # to set Distribution options. + + if 'global' in self.command_options: + for (opt, (src, val)) in self.command_options['global'].items(): + alias = self.negative_opt.get(opt) + try: + if alias: + setattr(self, alias, not strtobool(val)) + elif opt in ('verbose', 'dry_run'): # ugh! + setattr(self, opt, strtobool(val)) + else: + setattr(self, opt, val) + except ValueError as msg: + raise DistutilsOptionError(msg) + + +if sys.version_info < (3,): + # Python 2 behavior is sufficient + class Distribution_parse_config_files: + pass + + +if False: + # When updated behavior is available upstream, + # disable override here. + class Distribution_parse_config_files: + pass diff --git a/env/lib/python3.7/site-packages/setuptools/sandbox.py b/env/lib/python3.7/site-packages/setuptools/sandbox.py new file mode 100644 index 0000000..685f3f7 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/sandbox.py @@ -0,0 +1,491 @@ +import os +import sys +import tempfile +import operator +import functools +import itertools +import re +import contextlib +import pickle +import textwrap + +from setuptools.extern import six +from setuptools.extern.six.moves import builtins, map + +import pkg_resources.py31compat + +if sys.platform.startswith('java'): + import org.python.modules.posix.PosixModule as _os +else: + _os = sys.modules[os.name] +try: + _file = file +except NameError: + _file = None +_open = open +from distutils.errors import DistutilsError +from pkg_resources import working_set + + +__all__ = [ + "AbstractSandbox", "DirectorySandbox", "SandboxViolation", "run_setup", +] + + +def _execfile(filename, globals, locals=None): + """ + Python 3 implementation of execfile. + """ + mode = 'rb' + with open(filename, mode) as stream: + script = stream.read() + if locals is None: + locals = globals + code = compile(script, filename, 'exec') + exec(code, globals, locals) + + +@contextlib.contextmanager +def save_argv(repl=None): + saved = sys.argv[:] + if repl is not None: + sys.argv[:] = repl + try: + yield saved + finally: + sys.argv[:] = saved + + +@contextlib.contextmanager +def save_path(): + saved = sys.path[:] + try: + yield saved + finally: + sys.path[:] = saved + + +@contextlib.contextmanager +def override_temp(replacement): + """ + Monkey-patch tempfile.tempdir with replacement, ensuring it exists + """ + pkg_resources.py31compat.makedirs(replacement, exist_ok=True) + + saved = tempfile.tempdir + + tempfile.tempdir = replacement + + try: + yield + finally: + tempfile.tempdir = saved + + +@contextlib.contextmanager +def pushd(target): + saved = os.getcwd() + os.chdir(target) + try: + yield saved + finally: + os.chdir(saved) + + +class UnpickleableException(Exception): + """ + An exception representing another Exception that could not be pickled. + """ + + @staticmethod + def dump(type, exc): + """ + Always return a dumped (pickled) type and exc. If exc can't be pickled, + wrap it in UnpickleableException first. + """ + try: + return pickle.dumps(type), pickle.dumps(exc) + except Exception: + # get UnpickleableException inside the sandbox + from setuptools.sandbox import UnpickleableException as cls + return cls.dump(cls, cls(repr(exc))) + + +class ExceptionSaver: + """ + A Context Manager that will save an exception, serialized, and restore it + later. + """ + + def __enter__(self): + return self + + def __exit__(self, type, exc, tb): + if not exc: + return + + # dump the exception + self._saved = UnpickleableException.dump(type, exc) + self._tb = tb + + # suppress the exception + return True + + def resume(self): + "restore and re-raise any exception" + + if '_saved' not in vars(self): + return + + type, exc = map(pickle.loads, self._saved) + six.reraise(type, exc, self._tb) + + +@contextlib.contextmanager +def save_modules(): + """ + Context in which imported modules are saved. + + Translates exceptions internal to the context into the equivalent exception + outside the context. + """ + saved = sys.modules.copy() + with ExceptionSaver() as saved_exc: + yield saved + + sys.modules.update(saved) + # remove any modules imported since + del_modules = ( + mod_name for mod_name in sys.modules + if mod_name not in saved + # exclude any encodings modules. See #285 + and not mod_name.startswith('encodings.') + ) + _clear_modules(del_modules) + + saved_exc.resume() + + +def _clear_modules(module_names): + for mod_name in list(module_names): + del sys.modules[mod_name] + + +@contextlib.contextmanager +def save_pkg_resources_state(): + saved = pkg_resources.__getstate__() + try: + yield saved + finally: + pkg_resources.__setstate__(saved) + + +@contextlib.contextmanager +def setup_context(setup_dir): + temp_dir = os.path.join(setup_dir, 'temp') + with save_pkg_resources_state(): + with save_modules(): + hide_setuptools() + with save_path(): + with save_argv(): + with override_temp(temp_dir): + with pushd(setup_dir): + # ensure setuptools commands are available + __import__('setuptools') + yield + + +def _needs_hiding(mod_name): + """ + >>> _needs_hiding('setuptools') + True + >>> _needs_hiding('pkg_resources') + True + >>> _needs_hiding('setuptools_plugin') + False + >>> _needs_hiding('setuptools.__init__') + True + >>> _needs_hiding('distutils') + True + >>> _needs_hiding('os') + False + >>> _needs_hiding('Cython') + True + """ + pattern = re.compile(r'(setuptools|pkg_resources|distutils|Cython)(\.|$)') + return bool(pattern.match(mod_name)) + + +def hide_setuptools(): + """ + Remove references to setuptools' modules from sys.modules to allow the + invocation to import the most appropriate setuptools. This technique is + necessary to avoid issues such as #315 where setuptools upgrading itself + would fail to find a function declared in the metadata. + """ + modules = filter(_needs_hiding, sys.modules) + _clear_modules(modules) + + +def run_setup(setup_script, args): + """Run a distutils setup script, sandboxed in its directory""" + setup_dir = os.path.abspath(os.path.dirname(setup_script)) + with setup_context(setup_dir): + try: + sys.argv[:] = [setup_script] + list(args) + sys.path.insert(0, setup_dir) + # reset to include setup dir, w/clean callback list + working_set.__init__() + working_set.callbacks.append(lambda dist: dist.activate()) + + # __file__ should be a byte string on Python 2 (#712) + dunder_file = ( + setup_script + if isinstance(setup_script, str) else + setup_script.encode(sys.getfilesystemencoding()) + ) + + with DirectorySandbox(setup_dir): + ns = dict(__file__=dunder_file, __name__='__main__') + _execfile(setup_script, ns) + except SystemExit as v: + if v.args and v.args[0]: + raise + # Normal exit, just return + + +class AbstractSandbox: + """Wrap 'os' module and 'open()' builtin for virtualizing setup scripts""" + + _active = False + + def __init__(self): + self._attrs = [ + name for name in dir(_os) + if not name.startswith('_') and hasattr(self, name) + ] + + def _copy(self, source): + for name in self._attrs: + setattr(os, name, getattr(source, name)) + + def __enter__(self): + self._copy(self) + if _file: + builtins.file = self._file + builtins.open = self._open + self._active = True + + def __exit__(self, exc_type, exc_value, traceback): + self._active = False + if _file: + builtins.file = _file + builtins.open = _open + self._copy(_os) + + def run(self, func): + """Run 'func' under os sandboxing""" + with self: + return func() + + def _mk_dual_path_wrapper(name): + original = getattr(_os, name) + + def wrap(self, src, dst, *args, **kw): + if self._active: + src, dst = self._remap_pair(name, src, dst, *args, **kw) + return original(src, dst, *args, **kw) + + return wrap + + for name in ["rename", "link", "symlink"]: + if hasattr(_os, name): + locals()[name] = _mk_dual_path_wrapper(name) + + def _mk_single_path_wrapper(name, original=None): + original = original or getattr(_os, name) + + def wrap(self, path, *args, **kw): + if self._active: + path = self._remap_input(name, path, *args, **kw) + return original(path, *args, **kw) + + return wrap + + if _file: + _file = _mk_single_path_wrapper('file', _file) + _open = _mk_single_path_wrapper('open', _open) + for name in [ + "stat", "listdir", "chdir", "open", "chmod", "chown", "mkdir", + "remove", "unlink", "rmdir", "utime", "lchown", "chroot", "lstat", + "startfile", "mkfifo", "mknod", "pathconf", "access" + ]: + if hasattr(_os, name): + locals()[name] = _mk_single_path_wrapper(name) + + def _mk_single_with_return(name): + original = getattr(_os, name) + + def wrap(self, path, *args, **kw): + if self._active: + path = self._remap_input(name, path, *args, **kw) + return self._remap_output(name, original(path, *args, **kw)) + return original(path, *args, **kw) + + return wrap + + for name in ['readlink', 'tempnam']: + if hasattr(_os, name): + locals()[name] = _mk_single_with_return(name) + + def _mk_query(name): + original = getattr(_os, name) + + def wrap(self, *args, **kw): + retval = original(*args, **kw) + if self._active: + return self._remap_output(name, retval) + return retval + + return wrap + + for name in ['getcwd', 'tmpnam']: + if hasattr(_os, name): + locals()[name] = _mk_query(name) + + def _validate_path(self, path): + """Called to remap or validate any path, whether input or output""" + return path + + def _remap_input(self, operation, path, *args, **kw): + """Called for path inputs""" + return self._validate_path(path) + + def _remap_output(self, operation, path): + """Called for path outputs""" + return self._validate_path(path) + + def _remap_pair(self, operation, src, dst, *args, **kw): + """Called for path pairs like rename, link, and symlink operations""" + return ( + self._remap_input(operation + '-from', src, *args, **kw), + self._remap_input(operation + '-to', dst, *args, **kw) + ) + + +if hasattr(os, 'devnull'): + _EXCEPTIONS = [os.devnull,] +else: + _EXCEPTIONS = [] + + +class DirectorySandbox(AbstractSandbox): + """Restrict operations to a single subdirectory - pseudo-chroot""" + + write_ops = dict.fromkeys([ + "open", "chmod", "chown", "mkdir", "remove", "unlink", "rmdir", + "utime", "lchown", "chroot", "mkfifo", "mknod", "tempnam", + ]) + + _exception_patterns = [ + # Allow lib2to3 to attempt to save a pickled grammar object (#121) + r'.*lib2to3.*\.pickle$', + ] + "exempt writing to paths that match the pattern" + + def __init__(self, sandbox, exceptions=_EXCEPTIONS): + self._sandbox = os.path.normcase(os.path.realpath(sandbox)) + self._prefix = os.path.join(self._sandbox, '') + self._exceptions = [ + os.path.normcase(os.path.realpath(path)) + for path in exceptions + ] + AbstractSandbox.__init__(self) + + def _violation(self, operation, *args, **kw): + from setuptools.sandbox import SandboxViolation + raise SandboxViolation(operation, args, kw) + + if _file: + + def _file(self, path, mode='r', *args, **kw): + if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): + self._violation("file", path, mode, *args, **kw) + return _file(path, mode, *args, **kw) + + def _open(self, path, mode='r', *args, **kw): + if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): + self._violation("open", path, mode, *args, **kw) + return _open(path, mode, *args, **kw) + + def tmpnam(self): + self._violation("tmpnam") + + def _ok(self, path): + active = self._active + try: + self._active = False + realpath = os.path.normcase(os.path.realpath(path)) + return ( + self._exempted(realpath) + or realpath == self._sandbox + or realpath.startswith(self._prefix) + ) + finally: + self._active = active + + def _exempted(self, filepath): + start_matches = ( + filepath.startswith(exception) + for exception in self._exceptions + ) + pattern_matches = ( + re.match(pattern, filepath) + for pattern in self._exception_patterns + ) + candidates = itertools.chain(start_matches, pattern_matches) + return any(candidates) + + def _remap_input(self, operation, path, *args, **kw): + """Called for path inputs""" + if operation in self.write_ops and not self._ok(path): + self._violation(operation, os.path.realpath(path), *args, **kw) + return path + + def _remap_pair(self, operation, src, dst, *args, **kw): + """Called for path pairs like rename, link, and symlink operations""" + if not self._ok(src) or not self._ok(dst): + self._violation(operation, src, dst, *args, **kw) + return (src, dst) + + def open(self, file, flags, mode=0o777, *args, **kw): + """Called for low-level os.open()""" + if flags & WRITE_FLAGS and not self._ok(file): + self._violation("os.open", file, flags, mode, *args, **kw) + return _os.open(file, flags, mode, *args, **kw) + + +WRITE_FLAGS = functools.reduce( + operator.or_, [getattr(_os, a, 0) for a in + "O_WRONLY O_RDWR O_APPEND O_CREAT O_TRUNC O_TEMPORARY".split()] +) + + +class SandboxViolation(DistutilsError): + """A setup script attempted to modify the filesystem outside the sandbox""" + + tmpl = textwrap.dedent(""" + SandboxViolation: {cmd}{args!r} {kwargs} + + The package setup script has attempted to modify files on your system + that are not within the EasyInstall build area, and has been aborted. + + This package cannot be safely installed by EasyInstall, and may not + support alternate installation locations even if you run its setup + script by hand. Please inform the package's author and the EasyInstall + maintainers to find out if a fix or workaround is available. + """).lstrip() + + def __str__(self): + cmd, args, kwargs = self.args + return self.tmpl.format(**locals()) diff --git a/env/lib/python3.7/site-packages/setuptools/script (dev).tmpl b/env/lib/python3.7/site-packages/setuptools/script (dev).tmpl new file mode 100644 index 0000000..39a24b0 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/script (dev).tmpl @@ -0,0 +1,6 @@ +# EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r +__requires__ = %(spec)r +__import__('pkg_resources').require(%(spec)r) +__file__ = %(dev_path)r +with open(__file__) as f: + exec(compile(f.read(), __file__, 'exec')) diff --git a/env/lib/python3.7/site-packages/setuptools/script.tmpl b/env/lib/python3.7/site-packages/setuptools/script.tmpl new file mode 100644 index 0000000..ff5efbc --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/script.tmpl @@ -0,0 +1,3 @@ +# EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r +__requires__ = %(spec)r +__import__('pkg_resources').run_script(%(spec)r, %(script_name)r) diff --git a/env/lib/python3.7/site-packages/setuptools/site-patch.py b/env/lib/python3.7/site-packages/setuptools/site-patch.py new file mode 100644 index 0000000..40b00de --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/site-patch.py @@ -0,0 +1,74 @@ +def __boot(): + import sys + import os + PYTHONPATH = os.environ.get('PYTHONPATH') + if PYTHONPATH is None or (sys.platform == 'win32' and not PYTHONPATH): + PYTHONPATH = [] + else: + PYTHONPATH = PYTHONPATH.split(os.pathsep) + + pic = getattr(sys, 'path_importer_cache', {}) + stdpath = sys.path[len(PYTHONPATH):] + mydir = os.path.dirname(__file__) + + for item in stdpath: + if item == mydir or not item: + continue # skip if current dir. on Windows, or my own directory + importer = pic.get(item) + if importer is not None: + loader = importer.find_module('site') + if loader is not None: + # This should actually reload the current module + loader.load_module('site') + break + else: + try: + import imp # Avoid import loop in Python 3 + stream, path, descr = imp.find_module('site', [item]) + except ImportError: + continue + if stream is None: + continue + try: + # This should actually reload the current module + imp.load_module('site', stream, path, descr) + finally: + stream.close() + break + else: + raise ImportError("Couldn't find the real 'site' module") + + known_paths = dict([(makepath(item)[1], 1) for item in sys.path]) # 2.2 comp + + oldpos = getattr(sys, '__egginsert', 0) # save old insertion position + sys.__egginsert = 0 # and reset the current one + + for item in PYTHONPATH: + addsitedir(item) + + sys.__egginsert += oldpos # restore effective old position + + d, nd = makepath(stdpath[0]) + insert_at = None + new_path = [] + + for item in sys.path: + p, np = makepath(item) + + if np == nd and insert_at is None: + # We've hit the first 'system' path entry, so added entries go here + insert_at = len(new_path) + + if np in known_paths or insert_at is None: + new_path.append(item) + else: + # new path after the insert point, back-insert it + new_path.insert(insert_at, item) + insert_at += 1 + + sys.path[:] = new_path + + +if __name__ == 'site': + __boot() + del __boot diff --git a/env/lib/python3.7/site-packages/setuptools/ssl_support.py b/env/lib/python3.7/site-packages/setuptools/ssl_support.py new file mode 100644 index 0000000..6362f1f --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/ssl_support.py @@ -0,0 +1,260 @@ +import os +import socket +import atexit +import re +import functools + +from setuptools.extern.six.moves import urllib, http_client, map, filter + +from pkg_resources import ResolutionError, ExtractionError + +try: + import ssl +except ImportError: + ssl = None + +__all__ = [ + 'VerifyingHTTPSHandler', 'find_ca_bundle', 'is_available', 'cert_paths', + 'opener_for' +] + +cert_paths = """ +/etc/pki/tls/certs/ca-bundle.crt +/etc/ssl/certs/ca-certificates.crt +/usr/share/ssl/certs/ca-bundle.crt +/usr/local/share/certs/ca-root.crt +/etc/ssl/cert.pem +/System/Library/OpenSSL/certs/cert.pem +/usr/local/share/certs/ca-root-nss.crt +/etc/ssl/ca-bundle.pem +""".strip().split() + +try: + HTTPSHandler = urllib.request.HTTPSHandler + HTTPSConnection = http_client.HTTPSConnection +except AttributeError: + HTTPSHandler = HTTPSConnection = object + +is_available = ssl is not None and object not in (HTTPSHandler, HTTPSConnection) + + +try: + from ssl import CertificateError, match_hostname +except ImportError: + try: + from backports.ssl_match_hostname import CertificateError + from backports.ssl_match_hostname import match_hostname + except ImportError: + CertificateError = None + match_hostname = None + +if not CertificateError: + + class CertificateError(ValueError): + pass + + +if not match_hostname: + + def _dnsname_match(dn, hostname, max_wildcards=1): + """Matching according to RFC 6125, section 6.4.3 + + http://tools.ietf.org/html/rfc6125#section-6.4.3 + """ + pats = [] + if not dn: + return False + + # Ported from python3-syntax: + # leftmost, *remainder = dn.split(r'.') + parts = dn.split(r'.') + leftmost = parts[0] + remainder = parts[1:] + + wildcards = leftmost.count('*') + if wildcards > max_wildcards: + # Issue #17980: avoid denials of service by refusing more + # than one wildcard per fragment. A survey of established + # policy among SSL implementations showed it to be a + # reasonable choice. + raise CertificateError( + "too many wildcards in certificate DNS name: " + repr(dn)) + + # speed up common case w/o wildcards + if not wildcards: + return dn.lower() == hostname.lower() + + # RFC 6125, section 6.4.3, subitem 1. + # The client SHOULD NOT attempt to match a presented identifier in which + # the wildcard character comprises a label other than the left-most label. + if leftmost == '*': + # When '*' is a fragment by itself, it matches a non-empty dotless + # fragment. + pats.append('[^.]+') + elif leftmost.startswith('xn--') or hostname.startswith('xn--'): + # RFC 6125, section 6.4.3, subitem 3. + # The client SHOULD NOT attempt to match a presented identifier + # where the wildcard character is embedded within an A-label or + # U-label of an internationalized domain name. + pats.append(re.escape(leftmost)) + else: + # Otherwise, '*' matches any dotless string, e.g. www* + pats.append(re.escape(leftmost).replace(r'\*', '[^.]*')) + + # add the remaining fragments, ignore any wildcards + for frag in remainder: + pats.append(re.escape(frag)) + + pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE) + return pat.match(hostname) + + def match_hostname(cert, hostname): + """Verify that *cert* (in decoded format as returned by + SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125 + rules are followed, but IP addresses are not accepted for *hostname*. + + CertificateError is raised on failure. On success, the function + returns nothing. + """ + if not cert: + raise ValueError("empty or no certificate") + dnsnames = [] + san = cert.get('subjectAltName', ()) + for key, value in san: + if key == 'DNS': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if not dnsnames: + # The subject is only checked when there is no dNSName entry + # in subjectAltName + for sub in cert.get('subject', ()): + for key, value in sub: + # XXX according to RFC 2818, the most specific Common Name + # must be used. + if key == 'commonName': + if _dnsname_match(value, hostname): + return + dnsnames.append(value) + if len(dnsnames) > 1: + raise CertificateError("hostname %r " + "doesn't match either of %s" + % (hostname, ', '.join(map(repr, dnsnames)))) + elif len(dnsnames) == 1: + raise CertificateError("hostname %r " + "doesn't match %r" + % (hostname, dnsnames[0])) + else: + raise CertificateError("no appropriate commonName or " + "subjectAltName fields were found") + + +class VerifyingHTTPSHandler(HTTPSHandler): + """Simple verifying handler: no auth, subclasses, timeouts, etc.""" + + def __init__(self, ca_bundle): + self.ca_bundle = ca_bundle + HTTPSHandler.__init__(self) + + def https_open(self, req): + return self.do_open( + lambda host, **kw: VerifyingHTTPSConn(host, self.ca_bundle, **kw), req + ) + + +class VerifyingHTTPSConn(HTTPSConnection): + """Simple verifying connection: no auth, subclasses, timeouts, etc.""" + + def __init__(self, host, ca_bundle, **kw): + HTTPSConnection.__init__(self, host, **kw) + self.ca_bundle = ca_bundle + + def connect(self): + sock = socket.create_connection( + (self.host, self.port), getattr(self, 'source_address', None) + ) + + # Handle the socket if a (proxy) tunnel is present + if hasattr(self, '_tunnel') and getattr(self, '_tunnel_host', None): + self.sock = sock + self._tunnel() + # http://bugs.python.org/issue7776: Python>=3.4.1 and >=2.7.7 + # change self.host to mean the proxy server host when tunneling is + # being used. Adapt, since we are interested in the destination + # host for the match_hostname() comparison. + actual_host = self._tunnel_host + else: + actual_host = self.host + + if hasattr(ssl, 'create_default_context'): + ctx = ssl.create_default_context(cafile=self.ca_bundle) + self.sock = ctx.wrap_socket(sock, server_hostname=actual_host) + else: + # This is for python < 2.7.9 and < 3.4? + self.sock = ssl.wrap_socket( + sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs=self.ca_bundle + ) + try: + match_hostname(self.sock.getpeercert(), actual_host) + except CertificateError: + self.sock.shutdown(socket.SHUT_RDWR) + self.sock.close() + raise + + +def opener_for(ca_bundle=None): + """Get a urlopen() replacement that uses ca_bundle for verification""" + return urllib.request.build_opener( + VerifyingHTTPSHandler(ca_bundle or find_ca_bundle()) + ).open + + +# from jaraco.functools +def once(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + if not hasattr(func, 'always_returns'): + func.always_returns = func(*args, **kwargs) + return func.always_returns + return wrapper + + +@once +def get_win_certfile(): + try: + import wincertstore + except ImportError: + return None + + class CertFile(wincertstore.CertFile): + def __init__(self): + super(CertFile, self).__init__() + atexit.register(self.close) + + def close(self): + try: + super(CertFile, self).close() + except OSError: + pass + + _wincerts = CertFile() + _wincerts.addstore('CA') + _wincerts.addstore('ROOT') + return _wincerts.name + + +def find_ca_bundle(): + """Return an existing CA bundle path, or None""" + extant_cert_paths = filter(os.path.isfile, cert_paths) + return ( + get_win_certfile() + or next(extant_cert_paths, None) + or _certifi_where() + ) + + +def _certifi_where(): + try: + return __import__('certifi').where() + except (ImportError, ResolutionError, ExtractionError): + pass diff --git a/env/lib/python3.7/site-packages/setuptools/unicode_utils.py b/env/lib/python3.7/site-packages/setuptools/unicode_utils.py new file mode 100644 index 0000000..7c63efd --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/unicode_utils.py @@ -0,0 +1,44 @@ +import unicodedata +import sys + +from setuptools.extern import six + + +# HFS Plus uses decomposed UTF-8 +def decompose(path): + if isinstance(path, six.text_type): + return unicodedata.normalize('NFD', path) + try: + path = path.decode('utf-8') + path = unicodedata.normalize('NFD', path) + path = path.encode('utf-8') + except UnicodeError: + pass # Not UTF-8 + return path + + +def filesys_decode(path): + """ + Ensure that the given path is decoded, + NONE when no expected encoding works + """ + + if isinstance(path, six.text_type): + return path + + fs_enc = sys.getfilesystemencoding() or 'utf-8' + candidates = fs_enc, 'utf-8' + + for enc in candidates: + try: + return path.decode(enc) + except UnicodeDecodeError: + continue + + +def try_encode(string, enc): + "turn unicode encoding into a functional routine" + try: + return string.encode(enc) + except UnicodeEncodeError: + return None diff --git a/env/lib/python3.7/site-packages/setuptools/version.py b/env/lib/python3.7/site-packages/setuptools/version.py new file mode 100644 index 0000000..95e1869 --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/version.py @@ -0,0 +1,6 @@ +import pkg_resources + +try: + __version__ = pkg_resources.get_distribution('setuptools').version +except Exception: + __version__ = 'unknown' diff --git a/env/lib/python3.7/site-packages/setuptools/wheel.py b/env/lib/python3.7/site-packages/setuptools/wheel.py new file mode 100644 index 0000000..95a794a --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/wheel.py @@ -0,0 +1,210 @@ +"""Wheels support.""" + +from distutils.util import get_platform +import email +import itertools +import os +import posixpath +import re +import zipfile + +from pkg_resources import Distribution, PathMetadata, parse_version +from setuptools.extern.packaging.utils import canonicalize_name +from setuptools.extern.six import PY3 +from setuptools import Distribution as SetuptoolsDistribution +from setuptools import pep425tags +from setuptools.command.egg_info import write_requirements + + +__metaclass__ = type + + +WHEEL_NAME = re.compile( + r"""^(?P.+?)-(?P\d.*?) + ((-(?P\d.*?))?-(?P.+?)-(?P.+?)-(?P.+?) + )\.whl$""", + re.VERBOSE).match + +NAMESPACE_PACKAGE_INIT = '''\ +try: + __import__('pkg_resources').declare_namespace(__name__) +except ImportError: + __path__ = __import__('pkgutil').extend_path(__path__, __name__) +''' + + +def unpack(src_dir, dst_dir): + '''Move everything under `src_dir` to `dst_dir`, and delete the former.''' + for dirpath, dirnames, filenames in os.walk(src_dir): + subdir = os.path.relpath(dirpath, src_dir) + for f in filenames: + src = os.path.join(dirpath, f) + dst = os.path.join(dst_dir, subdir, f) + os.renames(src, dst) + for n, d in reversed(list(enumerate(dirnames))): + src = os.path.join(dirpath, d) + dst = os.path.join(dst_dir, subdir, d) + if not os.path.exists(dst): + # Directory does not exist in destination, + # rename it and prune it from os.walk list. + os.renames(src, dst) + del dirnames[n] + # Cleanup. + for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True): + assert not filenames + os.rmdir(dirpath) + + +class Wheel: + + def __init__(self, filename): + match = WHEEL_NAME(os.path.basename(filename)) + if match is None: + raise ValueError('invalid wheel name: %r' % filename) + self.filename = filename + for k, v in match.groupdict().items(): + setattr(self, k, v) + + def tags(self): + '''List tags (py_version, abi, platform) supported by this wheel.''' + return itertools.product( + self.py_version.split('.'), + self.abi.split('.'), + self.platform.split('.'), + ) + + def is_compatible(self): + '''Is the wheel is compatible with the current platform?''' + supported_tags = pep425tags.get_supported() + return next((True for t in self.tags() if t in supported_tags), False) + + def egg_name(self): + return Distribution( + project_name=self.project_name, version=self.version, + platform=(None if self.platform == 'any' else get_platform()), + ).egg_name() + '.egg' + + def get_dist_info(self, zf): + # find the correct name of the .dist-info dir in the wheel file + for member in zf.namelist(): + dirname = posixpath.dirname(member) + if (dirname.endswith('.dist-info') and + canonicalize_name(dirname).startswith( + canonicalize_name(self.project_name))): + return dirname + raise ValueError("unsupported wheel format. .dist-info not found") + + def install_as_egg(self, destination_eggdir): + '''Install wheel as an egg directory.''' + with zipfile.ZipFile(self.filename) as zf: + self._install_as_egg(destination_eggdir, zf) + + def _install_as_egg(self, destination_eggdir, zf): + dist_basename = '%s-%s' % (self.project_name, self.version) + dist_info = self.get_dist_info(zf) + dist_data = '%s.data' % dist_basename + egg_info = os.path.join(destination_eggdir, 'EGG-INFO') + + self._convert_metadata(zf, destination_eggdir, dist_info, egg_info) + self._move_data_entries(destination_eggdir, dist_data) + self._fix_namespace_packages(egg_info, destination_eggdir) + + @staticmethod + def _convert_metadata(zf, destination_eggdir, dist_info, egg_info): + def get_metadata(name): + with zf.open(posixpath.join(dist_info, name)) as fp: + value = fp.read().decode('utf-8') if PY3 else fp.read() + return email.parser.Parser().parsestr(value) + + wheel_metadata = get_metadata('WHEEL') + # Check wheel format version is supported. + wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) + wheel_v1 = ( + parse_version('1.0') <= wheel_version < parse_version('2.0dev0') + ) + if not wheel_v1: + raise ValueError( + 'unsupported wheel format version: %s' % wheel_version) + # Extract to target directory. + os.mkdir(destination_eggdir) + zf.extractall(destination_eggdir) + # Convert metadata. + dist_info = os.path.join(destination_eggdir, dist_info) + dist = Distribution.from_location( + destination_eggdir, dist_info, + metadata=PathMetadata(destination_eggdir, dist_info), + ) + + # Note: Evaluate and strip markers now, + # as it's difficult to convert back from the syntax: + # foobar; "linux" in sys_platform and extra == 'test' + def raw_req(req): + req.marker = None + return str(req) + install_requires = list(sorted(map(raw_req, dist.requires()))) + extras_require = { + extra: sorted( + req + for req in map(raw_req, dist.requires((extra,))) + if req not in install_requires + ) + for extra in dist.extras + } + os.rename(dist_info, egg_info) + os.rename( + os.path.join(egg_info, 'METADATA'), + os.path.join(egg_info, 'PKG-INFO'), + ) + setup_dist = SetuptoolsDistribution( + attrs=dict( + install_requires=install_requires, + extras_require=extras_require, + ), + ) + write_requirements( + setup_dist.get_command_obj('egg_info'), + None, + os.path.join(egg_info, 'requires.txt'), + ) + + @staticmethod + def _move_data_entries(destination_eggdir, dist_data): + """Move data entries to their correct location.""" + dist_data = os.path.join(destination_eggdir, dist_data) + dist_data_scripts = os.path.join(dist_data, 'scripts') + if os.path.exists(dist_data_scripts): + egg_info_scripts = os.path.join( + destination_eggdir, 'EGG-INFO', 'scripts') + os.mkdir(egg_info_scripts) + for entry in os.listdir(dist_data_scripts): + # Remove bytecode, as it's not properly handled + # during easy_install scripts install phase. + if entry.endswith('.pyc'): + os.unlink(os.path.join(dist_data_scripts, entry)) + else: + os.rename( + os.path.join(dist_data_scripts, entry), + os.path.join(egg_info_scripts, entry), + ) + os.rmdir(dist_data_scripts) + for subdir in filter(os.path.exists, ( + os.path.join(dist_data, d) + for d in ('data', 'headers', 'purelib', 'platlib') + )): + unpack(subdir, destination_eggdir) + if os.path.exists(dist_data): + os.rmdir(dist_data) + + @staticmethod + def _fix_namespace_packages(egg_info, destination_eggdir): + namespace_packages = os.path.join( + egg_info, 'namespace_packages.txt') + if os.path.exists(namespace_packages): + with open(namespace_packages) as fp: + namespace_packages = fp.read().split() + for mod in namespace_packages: + mod_dir = os.path.join(destination_eggdir, *mod.split('.')) + mod_init = os.path.join(mod_dir, '__init__.py') + if os.path.exists(mod_dir) and not os.path.exists(mod_init): + with open(mod_init, 'w') as fp: + fp.write(NAMESPACE_PACKAGE_INIT) diff --git a/env/lib/python3.7/site-packages/setuptools/windows_support.py b/env/lib/python3.7/site-packages/setuptools/windows_support.py new file mode 100644 index 0000000..cb977cf --- /dev/null +++ b/env/lib/python3.7/site-packages/setuptools/windows_support.py @@ -0,0 +1,29 @@ +import platform +import ctypes + + +def windows_only(func): + if platform.system() != 'Windows': + return lambda *args, **kwargs: None + return func + + +@windows_only +def hide_file(path): + """ + Set the hidden attribute on a file or directory. + + From http://stackoverflow.com/questions/19622133/ + + `path` must be text. + """ + __import__('ctypes.wintypes') + SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW + SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD + SetFileAttributes.restype = ctypes.wintypes.BOOL + + FILE_ATTRIBUTE_HIDDEN = 0x02 + + ret = SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN) + if not ret: + raise ctypes.WinError() diff --git a/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/INSTALLER b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/INSTALLER new file mode 100644 index 0000000..a1b589e --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/INSTALLER @@ -0,0 +1 @@ +pip diff --git a/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/LICENSE.txt b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/LICENSE.txt new file mode 100644 index 0000000..c3441e6 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/LICENSE.txt @@ -0,0 +1,22 @@ +"wheel" copyright (c) 2012-2014 Daniel Holth and +contributors. + +The MIT License + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/METADATA b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/METADATA new file mode 100644 index 0000000..cef8071 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/METADATA @@ -0,0 +1,60 @@ +Metadata-Version: 2.1 +Name: wheel +Version: 0.32.3 +Summary: A built-package format for Python. +Home-page: https://github.com/pypa/wheel +Author: Daniel Holth +Author-email: dholth@fastmail.fm +Maintainer: Alex Grönholm +Maintainer-email: alex.gronholm@nextday.fi +License: MIT +Project-URL: Issue Tracker, https://github.com/pypa/wheel/issues +Project-URL: Documentation, https://wheel.readthedocs.io/ +Project-URL: Changelog, https://wheel.readthedocs.io/en/stable/news.html +Keywords: wheel,packaging +Platform: UNKNOWN +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Developers +Classifier: Topic :: System :: Archiving :: Packaging +Classifier: License :: OSI Approved :: MIT License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2 +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.* +Provides-Extra: test +Requires-Dist: pytest (>=3.0.0) ; extra == 'test' +Requires-Dist: pytest-cov ; extra == 'test' + +wheel +===== + +This library is the reference implementation of the Python wheel packaging +standard, as defined in `PEP 427`_. + +It has two different roles: + +#. A setuptools_ extension for building wheels that provides the + ``bdist_wheel`` setuptools command +#. A command line tool for working with wheel files + +It should be noted that wheel is **not** intended to be used as a library, and +as such there is no stable, public API. + +.. _PEP 427: https://www.python.org/dev/peps/pep-0427/ +.. _setuptools: https://pypi.org/project/setuptools/ + + +Code of Conduct +--------------- + +Everyone interacting in the wheel project's codebases, issue trackers, chat +rooms, and mailing lists is expected to follow the `PyPA Code of Conduct`_. + +.. _PyPA Code of Conduct: https://www.pypa.io/en/latest/code-of-conduct/ + + diff --git a/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/RECORD b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/RECORD new file mode 100644 index 0000000..b535e48 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/RECORD @@ -0,0 +1,34 @@ +wheel/__init__.py,sha256=AgAP7YAmbZj84_nCH9za8R0UXHylXdfKNSyg5g1xLZ4,96 +wheel/__main__.py,sha256=lF-YLO4hdQmoWuh4eWZd8YL1U95RSdm76sNLBXa0vjE,417 +wheel/bdist_wheel.py,sha256=0hM63ZD01ATEMRAr6t0mbmhf2y8pbRkMnWGioed9n-o,14627 +wheel/metadata.py,sha256=a3QgT8C4QOvrS-8RFdNCn7XWUUqEZpcHelmI8XLTDnY,4691 +wheel/pep425tags.py,sha256=Jdjbnq17kqwPRKJCMb2E1VccNgnC3H6iQL7VGaxkPao,5908 +wheel/pkginfo.py,sha256=GR76kupQzn1x9sKDaXuE6B6FsZ4OkfRtG7pndlXPvQ4,1257 +wheel/util.py,sha256=bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI,859 +wheel/wheelfile.py,sha256=mxv8kcRvXMME4xQstpiiQv59bHc42edS6z8kDAco6iw,6990 +wheel/cli/__init__.py,sha256=DsCXkrL_jsTHoR0nhmcwkrlNdkaXw0uV0NL-yYoYQuU,2461 +wheel/cli/convert.py,sha256=me0l6G4gSw-EBVhzjSr7yWYWBp9spMz7mnXlyJTiXso,9497 +wheel/cli/install.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 +wheel/cli/pack.py,sha256=RViq4mnUk8s7R5kcrgX0XntX2zalDTeoTSBzLk31SaI,2145 +wheel/cli/unpack.py,sha256=0VWzT7U_xyenTPwEVavxqvdee93GPvAFHnR3Uu91aRc,673 +wheel-0.32.3.dist-info/LICENSE.txt,sha256=zKniDGrx_Pv2lAjzd3aShsvuvN7TNhAMm0o_NfvmNeQ,1125 +wheel-0.32.3.dist-info/METADATA,sha256=1gweIMsoaCjJWccLOuQJCZqj_cWYVM80LkUQosJ4wC8,2082 +wheel-0.32.3.dist-info/WHEEL,sha256=_wJFdOYk7i3xxT8ElOkUJvOdOvfNGbR9g-bf6UQT6sU,110 +wheel-0.32.3.dist-info/entry_points.txt,sha256=N8HbYFST3yrNQYeB2wXWBEPUhFsEtKNRPaCFGJPyqyc,108 +wheel-0.32.3.dist-info/top_level.txt,sha256=HxSBIbgEstMPe4eFawhA66Mq-QYHMopXVoAncfjb_1c,6 +wheel-0.32.3.dist-info/RECORD,, +../../../bin/wheel,sha256=C2tTqyXPXEVjwHG2wEstUaTSZQqHNo2IvGKL_5xerTw,254 +wheel-0.32.3.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 +wheel/__pycache__/wheelfile.cpython-37.pyc,, +wheel/__pycache__/util.cpython-37.pyc,, +wheel/__pycache__/pkginfo.cpython-37.pyc,, +wheel/__pycache__/pep425tags.cpython-37.pyc,, +wheel/__pycache__/metadata.cpython-37.pyc,, +wheel/__pycache__/bdist_wheel.cpython-37.pyc,, +wheel/__pycache__/__main__.cpython-37.pyc,, +wheel/__pycache__/__init__.cpython-37.pyc,, +wheel/cli/__pycache__/unpack.cpython-37.pyc,, +wheel/cli/__pycache__/pack.cpython-37.pyc,, +wheel/cli/__pycache__/install.cpython-37.pyc,, +wheel/cli/__pycache__/convert.cpython-37.pyc,, +wheel/cli/__pycache__/__init__.cpython-37.pyc,, diff --git a/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/WHEEL b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/WHEEL new file mode 100644 index 0000000..c4bde30 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/WHEEL @@ -0,0 +1,6 @@ +Wheel-Version: 1.0 +Generator: bdist_wheel (0.32.3) +Root-Is-Purelib: true +Tag: py2-none-any +Tag: py3-none-any + diff --git a/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/entry_points.txt b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/entry_points.txt new file mode 100644 index 0000000..b27acad --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/entry_points.txt @@ -0,0 +1,6 @@ +[console_scripts] +wheel = wheel.cli:main + +[distutils.commands] +bdist_wheel = wheel.bdist_wheel:bdist_wheel + diff --git a/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/top_level.txt b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/top_level.txt new file mode 100644 index 0000000..2309722 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel-0.32.3.dist-info/top_level.txt @@ -0,0 +1 @@ +wheel diff --git a/env/lib/python3.7/site-packages/wheel/__init__.py b/env/lib/python3.7/site-packages/wheel/__init__.py new file mode 100644 index 0000000..6938633 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/__init__.py @@ -0,0 +1,2 @@ +# __variables__ with double-quoted values will be available in setup.py: +__version__ = "0.32.3" diff --git a/env/lib/python3.7/site-packages/wheel/__main__.py b/env/lib/python3.7/site-packages/wheel/__main__.py new file mode 100644 index 0000000..b3773a2 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/__main__.py @@ -0,0 +1,19 @@ +""" +Wheel command line tool (enable python -m wheel syntax) +""" + +import sys + + +def main(): # needed for console script + if __package__ == '': + # To be able to run 'python wheel-0.9.whl/wheel': + import os.path + path = os.path.dirname(os.path.dirname(__file__)) + sys.path[0:0] = [path] + import wheel.cli + sys.exit(wheel.cli.main()) + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/env/lib/python3.7/site-packages/wheel/__pycache__/__init__.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/__pycache__/__init__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ada2e521b44aa9e5c27263690f9e46ae203e3bd5 GIT binary patch literal 158 zcmZ?b<>g`kf~fgwF$qBWF^B^Lj6jA15EpX*i4=w?h7`tN22G|aHUm9lBRyk3O~zZ? z@$qG;Ma7xbB0nU`4-AFo$Xd5gm)H$SB`C)EyQN-+>K007P(CXoOD literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/__pycache__/__main__.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/__pycache__/__main__.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cc9b7603c47a1644f86f0cfbed98c4854ec64719 GIT binary patch literal 551 zcmYk2!EV$r5QaT=()Fg4a^L}SLXE`k3aJ;Q3RUG^A#p&8kSr6M-E18v#76B_yQji) zusQNdzH;IfI5ExwVx;-y8UOZt_SMNrMli~6&)yF}$d6e34Tg(LO!pi`k&-A-)IbS} zspJbOsb(s@q5YYLeWK|D832f)Z%J`<|1x{G(%R%z+ceUu+|*X*zHLo@rmg&7blz?J zs6hdjeZsX+{L2_<&0+>eglF-iK74j literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/__pycache__/bdist_wheel.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/__pycache__/bdist_wheel.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6fbc88914340d2cd55d65b5f5255f72a08525454 GIT binary patch literal 9982 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 ByhZ>3 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/__pycache__/metadata.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/__pycache__/metadata.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..90e9a6a6f7660c3c313f15d8a72546add0ce4e33 GIT binary patch literal 3725 zcmZWsOLH5?5uSZuu~>j0Ma5JpWxKW#%OGr$vL#zqWa<%%lI==`VMIl8Ajzl=W7zu1yFy1i($Pxr1N3C;KUnCSRxu+*#M{}+t#;h& zru~OsFW%i)&7#iBXiMB#dGBs>@zdw(J$ec8Jl1jA8@(2XT1MgR+hKz~nkVz2(Y)Jy zr$f@|=c1L+?xU$E=rqfXg^nG$z@41!SeMu)+hPOjFvOF+#$GHuw+HsX$*mJ7w{zzb z8(J3I`^8h1TWXEFn~ayZcjD?&ZXH`gYXSS4<^ID*Lhs97sJBH3Gbkt;s!Vj^ZY-p+ zPZUbAw;xNfD|$MNd*Q}|jqv(MA7B0W#*MHWscmdoDV%+otoNPpURbbxDO|jwny;;; zrdO1=U_z~>q&pQQlC26a$}-X8g}al+y~0ze)PgtNqI&A67Hn+JRc#(CUD#<>I8gCl zOwK~o>kqH$-Rx=>XUlO<=_pB-I|p069liI_)q`yzl5sypFgq$PPbKQKJ)M*Ei)83I zbj+?Avg;RaD1P3CN;kjkz zc3{;kAI(KCe~ve2%uOaY=KcpJhu`Pygbm5$e}%il)Es8ct?W&VAduX8>B$=i0nE8G zw9Ohv+Xx8)#>y?Z!`400S^&Jh@&n7Mq#efl3(Gns!2=Ti=VwJNnb!EC6MxjE;WsA)*#qhX8^bpA- zqMpUZ8R#2JVdIqj8%-lT>TxXGkm;+K3$^@!IE7Xk1RKo|;uE1(0<(Ao>%{nBtf0ZE zGt+MPjahOle0J(2^4`@ebk_7K->z1@J_UmV_^x9hNd(Dt;+n*U7LBx4QH9$0<;@ufjt;1JKu@<|E zSSE?JM9yJFprWp5o888_nx$6VJgJE)MaeuDWiE)6R8g67cB_n3K zM2Lxw_i>m$a!3 z*~_y0E)S4jDywYoJGj0?ezAFQnGLFWRsIL7W^|o`g|ZKQA+0Gi`s)VpNnEUmtt}9D zH-#@suuTg0KZx~qxbd6Mm%m(p_&f4Baf4SsTF;w*QZQFiI)J`BoGJ@O1GC;7MOy;S(miHIIHmlQ~=iDd7toClW6x( zJi0>(TcNT36%a68vW3n+KCc%XJxV;(wvv#sHm<9)sb;VbkLlY4kQ$HDY7K$ zi1s!L4k3{RRpDll-ky>+5(HkQaNWYCszg??Z{+)R69;Vt`$D8Lekb1|u~md~JByBz zG~&fP7aZi?2A52auN5;u$W%92r?*?R$yMm7@F%6usVr@l{g|}7aUu$TOev~$@uxXM z$&hq`)_Y36OViS;DA^Z9^^_*(t$cB!$0?J3j=hQmFc*o$_AJk;Bi;gQ-Xxd0wSas+ zXZwi4y5-sO6Re!Z-nIy||Nd z5vKb(1TjZF@M{z&2m+;0SuQri<#6LjZ=*=NzHygOUpurAT$+xR_P@ zQl?wrD8L$JqF>tA-Q}Ao3rb0P09OiPusBG$*Aaz-3Zp1*N6M6HH%W{qdZbI?aY19# zmDh}P6ov^ZHx1G(Tsr$aLbDTu_D8qj*rpcHF(BXrl>mL65CKj=V+~)Xfk^p)$`Qkc z5|dFNQgTOK1!OeY{~hk&$sVCWY5l|jQuq%6yy)-}*?h>fcTyg|!G8&V0Ww3d5_h}c zN~*zR4=m|(e`uXlc!dXGQ}CwYs(XfF)=XHK{4*|L!in2IYn+PJ#tQ;)jNLe|HK6*# z$AuOA2+Vrn0)d1fXPN?+D3ZKkC+HLxEn!KOphR>YE6ECPNR+TnCm;E>=jV- zH~}KbM;3E|oNt@8&AFo7Zu7L$ZWrZLtr%`}t=vg>GY~|} zfAH1gN55`AdN8U)sr(z!6ve19iaF(!j~RVUVd<~#rhGpUcZew!ZFP-@`L=J@T7(|^mK`#-pi>WKgV literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/__pycache__/pep425tags.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/__pycache__/pep425tags.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e5339c776ee0f9bd31439bd559d069901df4aebc GIT binary patch literal 4669 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 P*LBBHhP@GY#`XROI>LKE literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/__pycache__/pkginfo.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/__pycache__/pkginfo.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5311d5a728c1ea3d4f9c6769cfaebb5dbc0c961e GIT binary patch literal 1529 zcmb_c&yN!~6t+DxnMpRu7Emc5QH`n!DN=X0QaM(Lg|Y}$4NDsd7*(2jV{bArzxwP| zx+r_1hh9+sgu;=3X|6r-FZ9HFo@CK(TlG>$w%MA&dJJ3g$BiG~`HcNZ zAL|yOaT~k&4F|;%rnnM0FGM0ZJML?bGvy`zV^&`AnGT-!;3jAEQ-0zwgH$Eb~D1EU73sNpJVvyD<8{lG>SUQ8xc zm7Dmmf*7<^SviYksp17>mhAm+?{7UA?>&rn;_vQFcE8!3?8b}C&Z{FEPbFYTPae>R zo$FYa(~5T3eup`-5pO#C5{!nu3EJKJy3`km=`Lsib2Q`B; zI4`2hP{xe+`DG4-c+}$+BBifiTBx}$M;?&GfeviK!(3YHoJ1ZB$r%;eN+qp4pU#jZrBCnu6AU(3 zBrYHL7-uARc!$XSyHMyjighe}ipG*Xa|NWlSK=%W?)Lq06G$`7vS!m90aP<-wKh{( zYfLX%%e3ieTmyrYbd*NvYDW~%NtkGW6AWme#LlJTRB|2tD^7;U%0G+d3k+)MSdrlW zhjfB5km7)D2(I9OWpI`3YhHgENn(kN@`W{i*Y_`F(^^@ZS>o{|TlL6&-)_sqM+yF97N%J{{BAO literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/__pycache__/util.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/__pycache__/util.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ce1530e3c6ed4ce23add0997190a567db16fad45 GIT binary patch literal 1225 zcmb_aJx?1!5Z>@cFO}M2>(|Bn8qH#tlL#k_aU|O*$u%b9fdwa-5IdHN@yr!T$)9 z`AgfTqE1JZnLXlwQJN@g?aa=ecjnET_qN@R8Lq*%jgKEZ#(q%ndtuCWaO+QKfC10h zp!R&gB|j3t))P;_L7@e+h}3=N1b*`NVUh|x!|04?-QXhR2m z4E#MymT#~M+r6Qxx532h_g;8#KuEk@EdCPg+HgS4S6$S1;bZ6gdzt6G(b++9WKOpF zXNOYecXnd3e6yU|ut-gIDkH)ZqG3G7pIX4vKY~_1zO}*L)JSbZkTq7-z*|LS9L(C# z#9XOGJlrck;uzB+Kcj021H-O(#jg3407q3K&Yw?IuG4)v+}qx&nOQ%}%;9)q*2@$C zsrgB1UL&31UaIBxmR)}I#D+>6m6Zv%KBOj{2T8S`;?{1ELQyJijN>Qt#lx=W z;S=;{xHTnXqRSQC%o=z=^J7)kR6A9Q-Sb+}iRb35T9`+*(ImVcF^TZcbZwmK;hk{T z@yop-s}+p@0|eVN@{1XoX(<&c_%A>r1mZNgF$ZIefd5j&kdv+TP&7^pj!)N-qI~!GcYKi0ZS?AR43k{GA-Z)JO~fOw!+p^Td=ZCH I5QS0r3w|f@9RL6T literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/__pycache__/wheelfile.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/__pycache__/wheelfile.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..fb9774151b6d614b5b982b9908d6fca99cbba7f1 GIT binary patch literal 5223 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 D&y$U2 literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/cli/__pycache__/install.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/cli/__pycache__/install.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..57f8ba004fbac72765a3ae06aaec29436c8b6a1d GIT binary patch literal 139 zcmZ?b<>g`kf~fgwF(CReh=2h`Aj1KOi&=m~3PUi1CZpd!F21UbT$E9vLC{rTrvCEwa z4Jy3Ai?2vfOOmBX!6!eg z-Th`O3A^HjklUy8?fT8T{yMIZ`h?eS-1Yq@bsj0b9wn{xT9ctH_-fF~(9k$_KneMY zv?!;Xy((!krmx9_-Y3U7bSW6G^(w!EV)ZjWu;JElLNc1E4u`+K}xzqvHO|~Enb>f$Mnthk;BU%j|?3nsW2?4-{3ZPY~x9k@R;z* zw`7leM|6c(c@20A$P0QEfwFLpQUc22IZBx?0pJ(L?hte^V`(;)C$tSRM($LrA?3>; z)gHPNHesWRt_~~w;xT)3YgE-WehKy}aPl(0@-w4EFB~q8mnMXgVRd`~(V*mvrZs-` z7=xn%u3ZW50knG}3!Bfp(95KF5v4s9A9=k5X@Yxwbg;)GDVjQ!M;=5#3ap9f&$e3N z?z-!G@Evr7H+Sa7<1co0zVdM2>-LoPnrWiLDDl!nc&YTdsT7_L+sad^r#qpB4hga? zw7G67+MLHg@|t1dJry1oTF7pc2tE_LnT0a!&UM^0ioDMPbM@&Fp>zXm+w|_kEJ{L* z>-k0A8W*jw7i;B#(WqUsC#6XAoW(cSH33EQVfaFRl8eyPZRpx$NWNbiQE((3Gt*lT zWE31prLFC;19O-S=`ZZLy-)riej#V6%Iz%Fo!p5OsF&M^X_VyE`w#aI8V`3LJZkLi zn{l*( z-mYgyC+=1Z$=FQ0+4fbm!G^9t7#*w_j;%OthOyeN&)MFh?Sq?N158l{uAT?L-zY^w zd9AdUaEKo7MOpLkHJopsDH%TFMPQ!N=>SxjjP2K%x3qJq}9gL;r zxrLmrl3z{K`0RwP8@zlfF9YkT+7_tuj@BpTEhVNNzHvtPtMB;tl;^*xBUj++DZ1wr zlB-BZzny^*ZMz9=2IK#b_!b>;9)kBuyfv3-w9RRKP<}aDe>tl6J8@3?gOzDvjFR@u zN1=k~t=H>0zJ``ac+MVu=`YIyT$L9waWGk}SR@kPt-R1mC1k0@w_8?_;B{su*4kcz6{Qxtz9g8)G$aqHY$epcp=la4#=sai~#opaBEMeeRla z(ZG@vuzt(<4q!(45;Fm-Rr49X*$QDL?h32YC2G?Jt3;QqD|7+o1-fi4Q~Z4hlq!ra zy~HF|Nxzo64ftcBdr~wS61|ugQ&mTSQ*@aW60?ZU6uP literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/cli/__pycache__/unpack.cpython-37.pyc b/env/lib/python3.7/site-packages/wheel/cli/__pycache__/unpack.cpython-37.pyc new file mode 100644 index 0000000000000000000000000000000000000000..59fa601c8a013aa22f51aa03afa6dd1e72fb86a6 GIT binary patch literal 903 zcmYjPOOMkq5VoC1+iY17&#O;}NNjolai|bNfcAp4h?f>cNF~H>o02BMb||}TPRkYX z6KIe8C0{x1UqBp~Neg168QbG|eDip8;X*)w;_o-#ZWtjy@$r`&xI6^b_dp0DXinxd zrWEfiXR*_sZtMz2xVbm?V;}yy!WW${H0}uYl7zi;@FgL&`<2QHGaA=LYO=C8I)`ki z?;TI2%n!3%S{kLOMDl=pz>k6TI}nDf$Qk{1*sv9w(KQovLmS69Gk5K+=*ro!#x=fR z>(0vEPz3aqQDVBY-a6P2N>*&Whd-1Y6X884FUT7L_Wl``;{njl>F?J?m82hd!WRfB z3IYz)!sBUK7+Dy;$nu=Om%MIGrQoLIOChys2FoIu%jRJDNvh^HhES4kb#0tXb2F73 zGb9tq(U>QN;H^E+jOO5|p)$X~UdW{T-B$_^mn+u0$8A%6lgD-vul z7nzc&Db)$TCFD4%bA#S#trQmW?>CHEc(#Lx0K(~&Z5y&;0`^0`Y@#T#I4MUK;>faR zPs6@)VI=WIfT*PyjbV7`ZM}&q>&miHTNi;_cUESF_1e)}e_X10VyvT2wDq+SWo@iC z&TBojf&6S#lA0vXLr?V~x^=Onm@UT2$7Fl>+|~AjsB576b!TAa)u76%gRIc#dypJo^!*XF_|v~6i4wD|rL*U`6oe_o0@mk%hsbQeUQb!nINoj>D> B{15;D literal 0 HcmV?d00001 diff --git a/env/lib/python3.7/site-packages/wheel/cli/convert.py b/env/lib/python3.7/site-packages/wheel/cli/convert.py new file mode 100644 index 0000000..f1a793a --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/cli/convert.py @@ -0,0 +1,269 @@ +import os.path +import re +import shutil +import sys +import tempfile +import zipfile +from distutils import dist +from glob import iglob + +from ..bdist_wheel import bdist_wheel +from ..wheelfile import WheelFile +from . import WheelError, require_pkgresources + +egg_info_re = re.compile(r''' + (?P.+?)-(?P.+?) + (-(?Ppy\d\.\d) + (-(?P.+?))? + )?.egg$''', re.VERBOSE) + + +class _bdist_wheel_tag(bdist_wheel): + # allow the client to override the default generated wheel tag + # The default bdist_wheel implementation uses python and abi tags + # of the running python process. This is not suitable for + # generating/repackaging prebuild binaries. + + full_tag_supplied = False + full_tag = None # None or a (pytag, soabitag, plattag) triple + + def get_tag(self): + if self.full_tag_supplied and self.full_tag is not None: + return self.full_tag + else: + return bdist_wheel.get_tag(self) + + +def egg2wheel(egg_path, dest_dir): + filename = os.path.basename(egg_path) + match = egg_info_re.match(filename) + if not match: + raise WheelError('Invalid egg file name: {}'.format(filename)) + + egg_info = match.groupdict() + dir = tempfile.mkdtemp(suffix="_e2w") + if os.path.isfile(egg_path): + # assume we have a bdist_egg otherwise + with zipfile.ZipFile(egg_path) as egg: + egg.extractall(dir) + else: + # support buildout-style installed eggs directories + for pth in os.listdir(egg_path): + src = os.path.join(egg_path, pth) + if os.path.isfile(src): + shutil.copy2(src, dir) + else: + shutil.copytree(src, os.path.join(dir, pth)) + + pyver = egg_info['pyver'] + if pyver: + pyver = egg_info['pyver'] = pyver.replace('.', '') + + arch = (egg_info['arch'] or 'any').replace('.', '_').replace('-', '_') + + # assume all binary eggs are for CPython + abi = 'cp' + pyver[2:] if arch != 'any' else 'none' + + root_is_purelib = egg_info['arch'] is None + if root_is_purelib: + bw = bdist_wheel(dist.Distribution()) + else: + bw = _bdist_wheel_tag(dist.Distribution()) + + bw.root_is_pure = root_is_purelib + bw.python_tag = pyver + bw.plat_name_supplied = True + bw.plat_name = egg_info['arch'] or 'any' + if not root_is_purelib: + bw.full_tag_supplied = True + bw.full_tag = (pyver, abi, arch) + + dist_info_dir = os.path.join(dir, '{name}-{ver}.dist-info'.format(**egg_info)) + bw.egg2dist(os.path.join(dir, 'EGG-INFO'), dist_info_dir) + bw.write_wheelfile(dist_info_dir, generator='egg2wheel') + wheel_name = '{name}-{ver}-{pyver}-{}-{}.whl'.format(abi, arch, **egg_info) + with WheelFile(os.path.join(dest_dir, wheel_name), 'w') as wf: + wf.write_files(dir) + + shutil.rmtree(dir) + + +def parse_wininst_info(wininfo_name, egginfo_name): + """Extract metadata from filenames. + + Extracts the 4 metadataitems needed (name, version, pyversion, arch) from + the installer filename and the name of the egg-info directory embedded in + the zipfile (if any). + + The egginfo filename has the format:: + + name-ver(-pyver)(-arch).egg-info + + The installer filename has the format:: + + name-ver.arch(-pyver).exe + + Some things to note: + + 1. The installer filename is not definitive. An installer can be renamed + and work perfectly well as an installer. So more reliable data should + be used whenever possible. + 2. The egg-info data should be preferred for the name and version, because + these come straight from the distutils metadata, and are mandatory. + 3. The pyver from the egg-info data should be ignored, as it is + constructed from the version of Python used to build the installer, + which is irrelevant - the installer filename is correct here (even to + the point that when it's not there, any version is implied). + 4. The architecture must be taken from the installer filename, as it is + not included in the egg-info data. + 5. Architecture-neutral installers still have an architecture because the + installer format itself (being executable) is architecture-specific. We + should therefore ignore the architecture if the content is pure-python. + """ + + egginfo = None + if egginfo_name: + egginfo = egg_info_re.search(egginfo_name) + if not egginfo: + raise ValueError("Egg info filename %s is not valid" % (egginfo_name,)) + + # Parse the wininst filename + # 1. Distribution name (up to the first '-') + w_name, sep, rest = wininfo_name.partition('-') + if not sep: + raise ValueError("Installer filename %s is not valid" % (wininfo_name,)) + + # Strip '.exe' + rest = rest[:-4] + # 2. Python version (from the last '-', must start with 'py') + rest2, sep, w_pyver = rest.rpartition('-') + if sep and w_pyver.startswith('py'): + rest = rest2 + w_pyver = w_pyver.replace('.', '') + else: + # Not version specific - use py2.py3. While it is possible that + # pure-Python code is not compatible with both Python 2 and 3, there + # is no way of knowing from the wininst format, so we assume the best + # here (the user can always manually rename the wheel to be more + # restrictive if needed). + w_pyver = 'py2.py3' + # 3. Version and architecture + w_ver, sep, w_arch = rest.rpartition('.') + if not sep: + raise ValueError("Installer filename %s is not valid" % (wininfo_name,)) + + if egginfo: + w_name = egginfo.group('name') + w_ver = egginfo.group('ver') + + return {'name': w_name, 'ver': w_ver, 'arch': w_arch, 'pyver': w_pyver} + + +def wininst2wheel(path, dest_dir): + with zipfile.ZipFile(path) as bdw: + # Search for egg-info in the archive + egginfo_name = None + for filename in bdw.namelist(): + if '.egg-info' in filename: + egginfo_name = filename + break + + info = parse_wininst_info(os.path.basename(path), egginfo_name) + + root_is_purelib = True + for zipinfo in bdw.infolist(): + if zipinfo.filename.startswith('PLATLIB'): + root_is_purelib = False + break + if root_is_purelib: + paths = {'purelib': ''} + else: + paths = {'platlib': ''} + + dist_info = "%(name)s-%(ver)s" % info + datadir = "%s.data/" % dist_info + + # rewrite paths to trick ZipFile into extracting an egg + # XXX grab wininst .ini - between .exe, padding, and first zip file. + members = [] + egginfo_name = '' + for zipinfo in bdw.infolist(): + key, basename = zipinfo.filename.split('/', 1) + key = key.lower() + basepath = paths.get(key, None) + if basepath is None: + basepath = datadir + key.lower() + '/' + oldname = zipinfo.filename + newname = basepath + basename + zipinfo.filename = newname + del bdw.NameToInfo[oldname] + bdw.NameToInfo[newname] = zipinfo + # Collect member names, but omit '' (from an entry like "PLATLIB/" + if newname: + members.append(newname) + # Remember egg-info name for the egg2dist call below + if not egginfo_name: + if newname.endswith('.egg-info'): + egginfo_name = newname + elif '.egg-info/' in newname: + egginfo_name, sep, _ = newname.rpartition('/') + dir = tempfile.mkdtemp(suffix="_b2w") + bdw.extractall(dir, members) + + # egg2wheel + abi = 'none' + pyver = info['pyver'] + arch = (info['arch'] or 'any').replace('.', '_').replace('-', '_') + # Wininst installers always have arch even if they are not + # architecture-specific (because the format itself is). + # So, assume the content is architecture-neutral if root is purelib. + if root_is_purelib: + arch = 'any' + # If the installer is architecture-specific, it's almost certainly also + # CPython-specific. + if arch != 'any': + pyver = pyver.replace('py', 'cp') + wheel_name = '-'.join((dist_info, pyver, abi, arch)) + if root_is_purelib: + bw = bdist_wheel(dist.Distribution()) + else: + bw = _bdist_wheel_tag(dist.Distribution()) + + bw.root_is_pure = root_is_purelib + bw.python_tag = pyver + bw.plat_name_supplied = True + bw.plat_name = info['arch'] or 'any' + + if not root_is_purelib: + bw.full_tag_supplied = True + bw.full_tag = (pyver, abi, arch) + + dist_info_dir = os.path.join(dir, '%s.dist-info' % dist_info) + bw.egg2dist(os.path.join(dir, egginfo_name), dist_info_dir) + bw.write_wheelfile(dist_info_dir, generator='wininst2wheel') + + wheel_path = os.path.join(dest_dir, wheel_name) + with WheelFile(wheel_path, 'w') as wf: + wf.write_files(dir) + + shutil.rmtree(dir) + + +def convert(files, dest_dir, verbose): + # Only support wheel convert if pkg_resources is present + require_pkgresources('wheel convert') + + for pat in files: + for installer in iglob(pat): + if os.path.splitext(installer)[1] == '.egg': + conv = egg2wheel + else: + conv = wininst2wheel + + if verbose: + print("{}... ".format(installer)) + sys.stdout.flush() + + conv(installer, dest_dir) + if verbose: + print("OK") diff --git a/env/lib/python3.7/site-packages/wheel/cli/install.py b/env/lib/python3.7/site-packages/wheel/cli/install.py new file mode 100644 index 0000000..e69de29 diff --git a/env/lib/python3.7/site-packages/wheel/cli/pack.py b/env/lib/python3.7/site-packages/wheel/cli/pack.py new file mode 100644 index 0000000..45c70f2 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/cli/pack.py @@ -0,0 +1,54 @@ +from __future__ import print_function + +import os.path +import re +import sys + +from wheel.cli import WheelError +from wheel.wheelfile import WheelFile + +DIST_INFO_RE = re.compile(r"^(?P(?P.+?)-(?P\d.*?))\.dist-info$") + + +def pack(directory, dest_dir): + """Repack a previously unpacked wheel directory into a new wheel file. + + The .dist-info/WHEEL file must contain one or more tags so that the target + wheel file name can be determined. + + :param directory: The unpacked wheel directory + :param dest_dir: Destination directory (defaults to the current directory) + """ + # Find the .dist-info directory + dist_info_dirs = [fn for fn in os.listdir(directory) + if os.path.isdir(os.path.join(directory, fn)) and DIST_INFO_RE.match(fn)] + if len(dist_info_dirs) > 1: + raise WheelError('Multiple .dist-info directories found in {}'.format(directory)) + elif not dist_info_dirs: + raise WheelError('No .dist-info directories found in {}'.format(directory)) + + # Determine the target wheel filename + dist_info_dir = dist_info_dirs[0] + name_version = DIST_INFO_RE.match(dist_info_dir).group('namever') + + # Read the tags from .dist-info/WHEEL + with open(os.path.join(directory, dist_info_dir, 'WHEEL')) as f: + tags = [line.split(' ')[1].rstrip() for line in f if line.startswith('Tag: ')] + if not tags: + raise WheelError('No tags present in {}/WHEEL; cannot determine target wheel filename' + .format(dist_info_dir)) + + # Reassemble the tags for the wheel file + impls = sorted({tag.split('-')[0] for tag in tags}) + abivers = sorted({tag.split('-')[1] for tag in tags}) + platforms = sorted({tag.split('-')[2] for tag in tags}) + tagline = '-'.join(['.'.join(impls), '.'.join(abivers), '.'.join(platforms)]) + + # Repack the wheel + wheel_path = os.path.join(dest_dir, '{}-{}.whl'.format(name_version, tagline)) + with WheelFile(wheel_path, 'w') as wf: + print("Repacking wheel as {}...".format(wheel_path), end='') + sys.stdout.flush() + wf.write_files(directory) + + print('OK') diff --git a/env/lib/python3.7/site-packages/wheel/cli/unpack.py b/env/lib/python3.7/site-packages/wheel/cli/unpack.py new file mode 100644 index 0000000..2e9857a --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/cli/unpack.py @@ -0,0 +1,25 @@ +from __future__ import print_function + +import os.path +import sys + +from ..wheelfile import WheelFile + + +def unpack(path, dest='.'): + """Unpack a wheel. + + Wheel content will be unpacked to {dest}/{name}-{ver}, where {name} + is the package name and {ver} its version. + + :param path: The path to the wheel. + :param dest: Destination directory (default to current directory). + """ + with WheelFile(path) as wf: + namever = wf.parsed_filename.group('namever') + destination = os.path.join(dest, namever) + print("Unpacking to: {}...".format(destination), end='') + sys.stdout.flush() + wf.extractall(destination) + + print('OK') diff --git a/env/lib/python3.7/site-packages/wheel/metadata.py b/env/lib/python3.7/site-packages/wheel/metadata.py new file mode 100644 index 0000000..3edf6ae --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/metadata.py @@ -0,0 +1,141 @@ +""" +Tools for converting old- to new-style metadata. +""" + +import os.path +import re +import textwrap + +import pkg_resources + +from .pkginfo import read_pkg_info + +# Wheel itself is probably the only program that uses non-extras markers +# in METADATA/PKG-INFO. Support its syntax with the extra at the end only. +EXTRA_RE = re.compile( + r"""^(?P.*?)(;\s*(?P.*?)(extra == '(?P.*?)')?)$""") + + +def requires_to_requires_dist(requirement): + """Return the version specifier for a requirement in PEP 345/566 fashion.""" + if getattr(requirement, 'url', None): + return " @ " + requirement.url + + requires_dist = [] + for op, ver in requirement.specs: + requires_dist.append(op + ver) + if not requires_dist: + return '' + return " (%s)" % ','.join(sorted(requires_dist)) + + +def convert_requirements(requirements): + """Yield Requires-Dist: strings for parsed requirements strings.""" + for req in requirements: + parsed_requirement = pkg_resources.Requirement.parse(req) + spec = requires_to_requires_dist(parsed_requirement) + extras = ",".join(parsed_requirement.extras) + if extras: + extras = "[%s]" % extras + yield (parsed_requirement.project_name + extras + spec) + + +def generate_requirements(extras_require): + """ + Convert requirements from a setup()-style dictionary to ('Requires-Dist', 'requirement') + and ('Provides-Extra', 'extra') tuples. + + extras_require is a dictionary of {extra: [requirements]} as passed to setup(), + using the empty extra {'': [requirements]} to hold install_requires. + """ + for extra, depends in extras_require.items(): + condition = '' + extra = extra or '' + if ':' in extra: # setuptools extra:condition syntax + extra, condition = extra.split(':', 1) + + extra = pkg_resources.safe_extra(extra) + if extra: + yield 'Provides-Extra', extra + if condition: + condition = "(" + condition + ") and " + condition += "extra == '%s'" % extra + + if condition: + condition = ' ; ' + condition + + for new_req in convert_requirements(depends): + yield 'Requires-Dist', new_req + condition + + +def pkginfo_to_metadata(egg_info_path, pkginfo_path): + """ + Convert .egg-info directory with PKG-INFO to the Metadata 2.1 format + """ + pkg_info = read_pkg_info(pkginfo_path) + pkg_info.replace_header('Metadata-Version', '2.1') + # Those will be regenerated from `requires.txt`. + del pkg_info['Provides-Extra'] + del pkg_info['Requires-Dist'] + requires_path = os.path.join(egg_info_path, 'requires.txt') + if os.path.exists(requires_path): + with open(requires_path) as requires_file: + requires = requires_file.read() + + parsed_requirements = sorted(pkg_resources.split_sections(requires), + key=lambda x: x[0] or '') + for extra, reqs in parsed_requirements: + for key, value in generate_requirements({extra: reqs}): + if (key, value) not in pkg_info.items(): + pkg_info[key] = value + + description = pkg_info['Description'] + if description: + pkg_info.set_payload(dedent_description(pkg_info)) + del pkg_info['Description'] + + return pkg_info + + +def pkginfo_unicode(pkg_info, field): + """Hack to coax Unicode out of an email Message() - Python 3.3+""" + text = pkg_info[field] + field = field.lower() + if not isinstance(text, str): + if not hasattr(pkg_info, 'raw_items'): # Python 3.2 + return str(text) + for item in pkg_info.raw_items(): + if item[0].lower() == field: + text = item[1].encode('ascii', 'surrogateescape') \ + .decode('utf-8') + break + + return text + + +def dedent_description(pkg_info): + """ + Dedent and convert pkg_info['Description'] to Unicode. + """ + description = pkg_info['Description'] + + # Python 3 Unicode handling, sorta. + surrogates = False + if not isinstance(description, str): + surrogates = True + description = pkginfo_unicode(pkg_info, 'Description') + + description_lines = description.splitlines() + description_dedent = '\n'.join( + # if the first line of long_description is blank, + # the first line here will be indented. + (description_lines[0].lstrip(), + textwrap.dedent('\n'.join(description_lines[1:])), + '\n')) + + if surrogates: + description_dedent = description_dedent \ + .encode("utf8") \ + .decode("ascii", "surrogateescape") + + return description_dedent diff --git a/env/lib/python3.7/site-packages/wheel/pep425tags.py b/env/lib/python3.7/site-packages/wheel/pep425tags.py new file mode 100644 index 0000000..13b5073 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/pep425tags.py @@ -0,0 +1,185 @@ +"""Generate and work with PEP 425 Compatibility Tags.""" + +import distutils.util +import platform +import sys +import sysconfig +import warnings + +try: + from importlib.machinery import get_all_suffixes +except ImportError: + from imp import get_suffixes as get_all_suffixes + + +def get_config_var(var): + try: + return sysconfig.get_config_var(var) + except IOError as e: # pip Issue #1074 + warnings.warn("{0}".format(e), RuntimeWarning) + return None + + +def get_abbr_impl(): + """Return abbreviated implementation name.""" + impl = platform.python_implementation() + if impl == 'PyPy': + return 'pp' + elif impl == 'Jython': + return 'jy' + elif impl == 'IronPython': + return 'ip' + elif impl == 'CPython': + return 'cp' + + raise LookupError('Unknown Python implementation: ' + impl) + + +def get_impl_ver(): + """Return implementation version.""" + impl_ver = get_config_var("py_version_nodot") + if not impl_ver or get_abbr_impl() == 'pp': + impl_ver = ''.join(map(str, get_impl_version_info())) + return impl_ver + + +def get_impl_version_info(): + """Return sys.version_info-like tuple for use in decrementing the minor + version.""" + if get_abbr_impl() == 'pp': + # as per https://github.com/pypa/pip/issues/2882 + return (sys.version_info[0], sys.pypy_version_info.major, + sys.pypy_version_info.minor) + else: + return sys.version_info[0], sys.version_info[1] + + +def get_flag(var, fallback, expected=True, warn=True): + """Use a fallback method for determining SOABI flags if the needed config + var is unset or unavailable.""" + val = get_config_var(var) + if val is None: + if warn: + warnings.warn("Config variable '{0}' is unset, Python ABI tag may " + "be incorrect".format(var), RuntimeWarning, 2) + return fallback() + return val == expected + + +def get_abi_tag(): + """Return the ABI tag based on SOABI (if available) or emulate SOABI + (CPython 2, PyPy).""" + soabi = get_config_var('SOABI') + impl = get_abbr_impl() + if not soabi and impl in ('cp', 'pp') and hasattr(sys, 'maxunicode'): + d = '' + m = '' + u = '' + if get_flag('Py_DEBUG', + lambda: hasattr(sys, 'gettotalrefcount'), + warn=(impl == 'cp')): + d = 'd' + if get_flag('WITH_PYMALLOC', + lambda: impl == 'cp', + warn=(impl == 'cp')): + m = 'm' + if get_flag('Py_UNICODE_SIZE', + lambda: sys.maxunicode == 0x10ffff, + expected=4, + warn=(impl == 'cp' and + sys.version_info < (3, 3))) \ + and sys.version_info < (3, 3): + u = 'u' + abi = '%s%s%s%s%s' % (impl, get_impl_ver(), d, m, u) + elif soabi and soabi.startswith('cpython-'): + abi = 'cp' + soabi.split('-')[1] + elif soabi: + abi = soabi.replace('.', '_').replace('-', '_') + else: + abi = None + return abi + + +def get_platform(): + """Return our platform name 'win32', 'linux_x86_64'""" + # XXX remove distutils dependency + result = distutils.util.get_platform().replace('.', '_').replace('-', '_') + if result == "linux_x86_64" and sys.maxsize == 2147483647: + # pip pull request #3497 + result = "linux_i686" + return result + + +def get_supported(versions=None, supplied_platform=None): + """Return a list of supported tags for each version specified in + `versions`. + + :param versions: a list of string versions, of the form ["33", "32"], + or None. The first version will be assumed to support our ABI. + """ + supported = [] + + # Versions must be given with respect to the preference + if versions is None: + versions = [] + version_info = get_impl_version_info() + major = version_info[:-1] + # Support all previous minor Python versions. + for minor in range(version_info[-1], -1, -1): + versions.append(''.join(map(str, major + (minor,)))) + + impl = get_abbr_impl() + + abis = [] + + abi = get_abi_tag() + if abi: + abis[0:0] = [abi] + + abi3s = set() + for suffix in get_all_suffixes(): + if suffix[0].startswith('.abi'): + abi3s.add(suffix[0].split('.', 2)[1]) + + abis.extend(sorted(list(abi3s))) + + abis.append('none') + + platforms = [] + if supplied_platform: + platforms.append(supplied_platform) + platforms.append(get_platform()) + + # Current version, current API (built specifically for our Python): + for abi in abis: + for arch in platforms: + supported.append(('%s%s' % (impl, versions[0]), abi, arch)) + + # abi3 modules compatible with older version of Python + for version in versions[1:]: + # abi3 was introduced in Python 3.2 + if version in ('31', '30'): + break + for abi in abi3s: # empty set if not Python 3 + for arch in platforms: + supported.append(("%s%s" % (impl, version), abi, arch)) + + # No abi / arch, but requires our implementation: + for i, version in enumerate(versions): + supported.append(('%s%s' % (impl, version), 'none', 'any')) + if i == 0: + # Tagged specifically as being cross-version compatible + # (with just the major version specified) + supported.append(('%s%s' % (impl, versions[0][0]), 'none', 'any')) + + # Major Python version + platform; e.g. binaries not using the Python API + for arch in platforms: + supported.append(('py%s' % (versions[0][0]), 'none', arch)) + + # No abi / arch, generic Python + for i, version in enumerate(versions): + supported.append(('py%s' % (version,), 'none', 'any')) + if i == 0: + supported.append(('py%s' % (version[0]), 'none', 'any')) + + return supported diff --git a/env/lib/python3.7/site-packages/wheel/pkginfo.py b/env/lib/python3.7/site-packages/wheel/pkginfo.py new file mode 100644 index 0000000..115be45 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/pkginfo.py @@ -0,0 +1,43 @@ +"""Tools for reading and writing PKG-INFO / METADATA without caring +about the encoding.""" + +from email.parser import Parser + +try: + unicode + _PY3 = False +except NameError: + _PY3 = True + +if not _PY3: + from email.generator import Generator + + def read_pkg_info_bytes(bytestr): + return Parser().parsestr(bytestr) + + def read_pkg_info(path): + with open(path, "r") as headers: + message = Parser().parse(headers) + return message + + def write_pkg_info(path, message): + with open(path, 'w') as metadata: + Generator(metadata, mangle_from_=False, maxheaderlen=0).flatten(message) +else: + from email.generator import BytesGenerator + + def read_pkg_info_bytes(bytestr): + headers = bytestr.decode(encoding="ascii", errors="surrogateescape") + message = Parser().parsestr(headers) + return message + + def read_pkg_info(path): + with open(path, "r", + encoding="ascii", + errors="surrogateescape") as headers: + message = Parser().parse(headers) + return message + + def write_pkg_info(path, message): + with open(path, "wb") as out: + BytesGenerator(out, mangle_from_=False, maxheaderlen=0).flatten(message) diff --git a/env/lib/python3.7/site-packages/wheel/util.py b/env/lib/python3.7/site-packages/wheel/util.py new file mode 100644 index 0000000..be0aa9b --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/util.py @@ -0,0 +1,41 @@ +import base64 +import sys + + +if sys.version_info[0] < 3: + text_type = unicode # noqa: F821 + + def native(s, encoding='utf-8'): + if isinstance(s, unicode): + return s.encode(encoding) + return s +else: + text_type = str + + def native(s, encoding='utf-8'): + if isinstance(s, bytes): + return s.decode(encoding) + return s + + +def urlsafe_b64encode(data): + """urlsafe_b64encode without padding""" + return base64.urlsafe_b64encode(data).rstrip(b'=') + + +def urlsafe_b64decode(data): + """urlsafe_b64decode without padding""" + pad = b'=' * (4 - (len(data) & 3)) + return base64.urlsafe_b64decode(data + pad) + + +def as_unicode(s): + if isinstance(s, bytes): + return s.decode('utf-8') + return s + + +def as_bytes(s): + if isinstance(s, text_type): + return s.encode('utf-8') + return s diff --git a/env/lib/python3.7/site-packages/wheel/wheelfile.py b/env/lib/python3.7/site-packages/wheel/wheelfile.py new file mode 100644 index 0000000..635aa77 --- /dev/null +++ b/env/lib/python3.7/site-packages/wheel/wheelfile.py @@ -0,0 +1,160 @@ +from __future__ import print_function + +import hashlib +import os.path +import re +import time +from collections import OrderedDict +from distutils import log as logger +from zipfile import ZIP_DEFLATED, ZipInfo, ZipFile + +from wheel.cli import WheelError +from wheel.util import urlsafe_b64decode, as_unicode, native, urlsafe_b64encode, as_bytes + +# Non-greedy matching of an optional build number may be too clever (more +# invalid wheel filenames will match). Separate regex for .dist-info? +WHEEL_INFO_RE = re.compile( + r"""^(?P(?P.+?)-(?P.+?))(-(?P\d[^-]*))? + -(?P.+?)-(?P.+?)-(?P.+?)\.whl$""", + re.VERBOSE) + + +def get_zipinfo_datetime(timestamp=None): + # Some applications need reproducible .whl files, but they can't do this without forcing + # the timestamp of the individual ZipInfo objects. See issue #143. + timestamp = int(os.environ.get('SOURCE_DATE_EPOCH', timestamp or time.time())) + return time.gmtime(timestamp)[0:6] + + +class WheelFile(ZipFile): + """A ZipFile derivative class that also reads SHA-256 hashes from + .dist-info/RECORD and checks any read files against those. + """ + + _default_algorithm = hashlib.sha256 + + def __init__(self, file, mode='r'): + basename = os.path.basename(file) + self.parsed_filename = WHEEL_INFO_RE.match(basename) + if not basename.endswith('.whl') or self.parsed_filename is None: + raise WheelError("Bad wheel filename {!r}".format(basename)) + + ZipFile.__init__(self, file, mode, compression=ZIP_DEFLATED, allowZip64=True) + + self.dist_info_path = '{}.dist-info'.format(self.parsed_filename.group('namever')) + self.record_path = self.dist_info_path + '/RECORD' + self._file_hashes = OrderedDict() + self._file_sizes = {} + if mode == 'r': + # Ignore RECORD and any embedded wheel signatures + self._file_hashes[self.record_path] = None, None + self._file_hashes[self.record_path + '.jws'] = None, None + self._file_hashes[self.record_path + '.p7s'] = None, None + + # Fill in the expected hashes by reading them from RECORD + try: + record = self.open(self.record_path) + except KeyError: + raise WheelError('Missing {} file'.format(self.record_path)) + + with record: + for line in record: + line = line.decode('utf-8') + path, hash_sum, size = line.rsplit(u',', 2) + if hash_sum: + algorithm, hash_sum = hash_sum.split(u'=') + try: + hashlib.new(algorithm) + except ValueError: + raise WheelError('Unsupported hash algorithm: {}'.format(algorithm)) + + if algorithm.lower() in {'md5', 'sha1'}: + raise WheelError( + 'Weak hash algorithm ({}) is not permitted by PEP 427' + .format(algorithm)) + + self._file_hashes[path] = ( + algorithm, urlsafe_b64decode(hash_sum.encode('ascii'))) + + def open(self, name_or_info, mode="r", pwd=None): + def _update_crc(newdata, eof=None): + if eof is None: + eof = ef._eof + update_crc_orig(newdata) + else: # Python 2 + update_crc_orig(newdata, eof) + + running_hash.update(newdata) + if eof and running_hash.digest() != expected_hash: + raise WheelError("Hash mismatch for file '{}'".format(native(ef_name))) + + ef = ZipFile.open(self, name_or_info, mode, pwd) + ef_name = as_unicode(name_or_info.filename if isinstance(name_or_info, ZipInfo) + else name_or_info) + if mode == 'r' and not ef_name.endswith('/'): + if ef_name not in self._file_hashes: + raise WheelError("No hash found for file '{}'".format(native(ef_name))) + + algorithm, expected_hash = self._file_hashes[ef_name] + if expected_hash is not None: + # Monkey patch the _update_crc method to also check for the hash from RECORD + running_hash = hashlib.new(algorithm) + update_crc_orig, ef._update_crc = ef._update_crc, _update_crc + + return ef + + def write_files(self, base_dir): + logger.info("creating '%s' and adding '%s' to it", self.filename, base_dir) + deferred = [] + for root, dirnames, filenames in os.walk(base_dir): + # Sort the directory names so that `os.walk` will walk them in a + # defined order on the next iteration. + dirnames.sort() + for name in sorted(filenames): + path = os.path.normpath(os.path.join(root, name)) + if os.path.isfile(path): + arcname = os.path.relpath(path, base_dir) + if arcname == self.record_path: + pass + elif root.endswith('.dist-info'): + deferred.append((path, arcname)) + else: + self.write(path, arcname) + + deferred.sort() + for path, arcname in deferred: + self.write(path, arcname) + + def write(self, filename, arcname=None, compress_type=None): + with open(filename, 'rb') as f: + st = os.fstat(f.fileno()) + data = f.read() + + zinfo = ZipInfo(arcname or filename, date_time=get_zipinfo_datetime(st.st_mtime)) + zinfo.external_attr = st.st_mode << 16 + zinfo.compress_type = ZIP_DEFLATED + self.writestr(zinfo, data, compress_type) + + def writestr(self, zinfo_or_arcname, bytes, compress_type=None): + ZipFile.writestr(self, zinfo_or_arcname, bytes, compress_type) + fname = (zinfo_or_arcname.filename if isinstance(zinfo_or_arcname, ZipInfo) + else zinfo_or_arcname) + logger.info("adding '%s'", fname) + if fname != self.record_path: + hash_ = self._default_algorithm(bytes) + self._file_hashes[fname] = hash_.name, native(urlsafe_b64encode(hash_.digest())) + self._file_sizes[fname] = len(bytes) + + def close(self): + # Write RECORD + if self.fp is not None and self.mode == 'w' and self._file_hashes: + content = '\n'.join('{},{}={},{}'.format(fname, algorithm, hash_, + self._file_sizes[fname]) + for fname, (algorithm, hash_) in self._file_hashes.items()) + content += '\n{},,\n'.format(self.record_path) + zinfo = ZipInfo(native(self.record_path), date_time=get_zipinfo_datetime()) + zinfo.compress_type = ZIP_DEFLATED + zinfo.external_attr = 0o664 << 16 + self.writestr(zinfo, as_bytes(content)) + + ZipFile.close(self) diff --git a/env/lib/python3.7/site.py b/env/lib/python3.7/site.py new file mode 100644 index 0000000..7969769 --- /dev/null +++ b/env/lib/python3.7/site.py @@ -0,0 +1,758 @@ +"""Append module search paths for third-party packages to sys.path. + +**************************************************************** +* This module is automatically imported during initialization. * +**************************************************************** + +In earlier versions of Python (up to 1.5a3), scripts or modules that +needed to use site-specific modules would place ``import site'' +somewhere near the top of their code. Because of the automatic +import, this is no longer necessary (but code that does it still +works). + +This will append site-specific paths to the module search path. On +Unix, it starts with sys.prefix and sys.exec_prefix (if different) and +appends lib/python/site-packages as well as lib/site-python. +It also supports the Debian convention of +lib/python/dist-packages. On other platforms (mainly Mac and +Windows), it uses just sys.prefix (and sys.exec_prefix, if different, +but this is unlikely). The resulting directories, if they exist, are +appended to sys.path, and also inspected for path configuration files. + +FOR DEBIAN, this sys.path is augmented with directories in /usr/local. +Local addons go into /usr/local/lib/python/site-packages +(resp. /usr/local/lib/site-python), Debian addons install into +/usr/{lib,share}/python/dist-packages. + +A path configuration file is a file whose name has the form +.pth; its contents are additional directories (one per line) +to be added to sys.path. Non-existing directories (or +non-directories) are never added to sys.path; no directory is added to +sys.path more than once. Blank lines and lines beginning with +'#' are skipped. Lines starting with 'import' are executed. + +For example, suppose sys.prefix and sys.exec_prefix are set to +/usr/local and there is a directory /usr/local/lib/python2.X/site-packages +with three subdirectories, foo, bar and spam, and two path +configuration files, foo.pth and bar.pth. Assume foo.pth contains the +following: + + # foo package configuration + foo + bar + bletch + +and bar.pth contains: + + # bar package configuration + bar + +Then the following directories are added to sys.path, in this order: + + /usr/local/lib/python2.X/site-packages/bar + /usr/local/lib/python2.X/site-packages/foo + +Note that bletch is omitted because it doesn't exist; bar precedes foo +because bar.pth comes alphabetically before foo.pth; and spam is +omitted because it is not mentioned in either path configuration file. + +After these path manipulations, an attempt is made to import a module +named sitecustomize, which can perform arbitrary additional +site-specific customizations. If this import fails with an +ImportError exception, it is silently ignored. + +""" + +import sys +import os +try: + import __builtin__ as builtins +except ImportError: + import builtins +try: + set +except NameError: + from sets import Set as set + +# Prefixes for site-packages; add additional prefixes like /usr/local here +PREFIXES = [sys.prefix, sys.exec_prefix] +# Enable per user site-packages directory +# set it to False to disable the feature or True to force the feature +ENABLE_USER_SITE = None +# for distutils.commands.install +USER_SITE = None +USER_BASE = None + +_is_64bit = (getattr(sys, 'maxsize', None) or getattr(sys, 'maxint')) > 2**32 +_is_pypy = hasattr(sys, 'pypy_version_info') +_is_jython = sys.platform[:4] == 'java' +if _is_jython: + ModuleType = type(os) + +def makepath(*paths): + dir = os.path.join(*paths) + if _is_jython and (dir == '__classpath__' or + dir.startswith('__pyclasspath__')): + return dir, dir + dir = os.path.abspath(dir) + return dir, os.path.normcase(dir) + +def abs__file__(): + """Set all module' __file__ attribute to an absolute path""" + for m in sys.modules.values(): + if ((_is_jython and not isinstance(m, ModuleType)) or + hasattr(m, '__loader__')): + # only modules need the abspath in Jython. and don't mess + # with a PEP 302-supplied __file__ + continue + f = getattr(m, '__file__', None) + if f is None: + continue + m.__file__ = os.path.abspath(f) + +def removeduppaths(): + """ Remove duplicate entries from sys.path along with making them + absolute""" + # This ensures that the initial path provided by the interpreter contains + # only absolute pathnames, even if we're running from the build directory. + L = [] + known_paths = set() + for dir in sys.path: + # Filter out duplicate paths (on case-insensitive file systems also + # if they only differ in case); turn relative paths into absolute + # paths. + dir, dircase = makepath(dir) + if not dircase in known_paths: + L.append(dir) + known_paths.add(dircase) + sys.path[:] = L + return known_paths + +# XXX This should not be part of site.py, since it is needed even when +# using the -S option for Python. See http://www.python.org/sf/586680 +def addbuilddir(): + """Append ./build/lib. in case we're running in the build dir + (especially for Guido :-)""" + from distutils.util import get_platform + s = "build/lib.%s-%.3s" % (get_platform(), sys.version) + if hasattr(sys, 'gettotalrefcount'): + s += '-pydebug' + s = os.path.join(os.path.dirname(sys.path[-1]), s) + sys.path.append(s) + +def _init_pathinfo(): + """Return a set containing all existing directory entries from sys.path""" + d = set() + for dir in sys.path: + try: + if os.path.isdir(dir): + dir, dircase = makepath(dir) + d.add(dircase) + except TypeError: + continue + return d + +def addpackage(sitedir, name, known_paths): + """Add a new path to known_paths by combining sitedir and 'name' or execute + sitedir if it starts with 'import'""" + if known_paths is None: + _init_pathinfo() + reset = 1 + else: + reset = 0 + fullname = os.path.join(sitedir, name) + try: + f = open(fullname, "rU") + except IOError: + return + try: + for line in f: + if line.startswith("#"): + continue + if line.startswith("import"): + exec(line) + continue + line = line.rstrip() + dir, dircase = makepath(sitedir, line) + if not dircase in known_paths and os.path.exists(dir): + sys.path.append(dir) + known_paths.add(dircase) + finally: + f.close() + if reset: + known_paths = None + return known_paths + +def addsitedir(sitedir, known_paths=None): + """Add 'sitedir' argument to sys.path if missing and handle .pth files in + 'sitedir'""" + if known_paths is None: + known_paths = _init_pathinfo() + reset = 1 + else: + reset = 0 + sitedir, sitedircase = makepath(sitedir) + if not sitedircase in known_paths: + sys.path.append(sitedir) # Add path component + try: + names = os.listdir(sitedir) + except os.error: + return + names.sort() + for name in names: + if name.endswith(os.extsep + "pth"): + addpackage(sitedir, name, known_paths) + if reset: + known_paths = None + return known_paths + +def addsitepackages(known_paths, sys_prefix=sys.prefix, exec_prefix=sys.exec_prefix): + """Add site-packages (and possibly site-python) to sys.path""" + prefixes = [os.path.join(sys_prefix, "local"), sys_prefix] + if exec_prefix != sys_prefix: + prefixes.append(os.path.join(exec_prefix, "local")) + + for prefix in prefixes: + if prefix: + if sys.platform in ('os2emx', 'riscos') or _is_jython: + sitedirs = [os.path.join(prefix, "Lib", "site-packages")] + elif _is_pypy: + sitedirs = [os.path.join(prefix, 'site-packages')] + elif sys.platform == 'darwin' and prefix == sys_prefix: + + if prefix.startswith("/System/Library/Frameworks/"): # Apple's Python + + sitedirs = [os.path.join("/Library/Python", sys.version[:3], "site-packages"), + os.path.join(prefix, "Extras", "lib", "python")] + + else: # any other Python distros on OSX work this way + sitedirs = [os.path.join(prefix, "lib", + "python" + sys.version[:3], "site-packages")] + + elif os.sep == '/': + sitedirs = [os.path.join(prefix, + "lib", + "python" + sys.version[:3], + "site-packages"), + os.path.join(prefix, "lib", "site-python"), + os.path.join(prefix, "python" + sys.version[:3], "lib-dynload")] + lib64_dir = os.path.join(prefix, "lib64", "python" + sys.version[:3], "site-packages") + if (os.path.exists(lib64_dir) and + os.path.realpath(lib64_dir) not in [os.path.realpath(p) for p in sitedirs]): + if _is_64bit: + sitedirs.insert(0, lib64_dir) + else: + sitedirs.append(lib64_dir) + try: + # sys.getobjects only available in --with-pydebug build + sys.getobjects + sitedirs.insert(0, os.path.join(sitedirs[0], 'debug')) + except AttributeError: + pass + # Debian-specific dist-packages directories: + sitedirs.append(os.path.join(prefix, "local/lib", + "python" + sys.version[:3], + "dist-packages")) + if sys.version[0] == '2': + sitedirs.append(os.path.join(prefix, "lib", + "python" + sys.version[:3], + "dist-packages")) + else: + sitedirs.append(os.path.join(prefix, "lib", + "python" + sys.version[0], + "dist-packages")) + sitedirs.append(os.path.join(prefix, "lib", "dist-python")) + else: + sitedirs = [prefix, os.path.join(prefix, "lib", "site-packages")] + if sys.platform == 'darwin': + # for framework builds *only* we add the standard Apple + # locations. Currently only per-user, but /Library and + # /Network/Library could be added too + if 'Python.framework' in prefix: + home = os.environ.get('HOME') + if home: + sitedirs.append( + os.path.join(home, + 'Library', + 'Python', + sys.version[:3], + 'site-packages')) + for sitedir in sitedirs: + if os.path.isdir(sitedir): + addsitedir(sitedir, known_paths) + return None + +def check_enableusersite(): + """Check if user site directory is safe for inclusion + + The function tests for the command line flag (including environment var), + process uid/gid equal to effective uid/gid. + + None: Disabled for security reasons + False: Disabled by user (command line option) + True: Safe and enabled + """ + if hasattr(sys, 'flags') and getattr(sys.flags, 'no_user_site', False): + return False + + if hasattr(os, "getuid") and hasattr(os, "geteuid"): + # check process uid == effective uid + if os.geteuid() != os.getuid(): + return None + if hasattr(os, "getgid") and hasattr(os, "getegid"): + # check process gid == effective gid + if os.getegid() != os.getgid(): + return None + + return True + +def addusersitepackages(known_paths): + """Add a per user site-package to sys.path + + Each user has its own python directory with site-packages in the + home directory. + + USER_BASE is the root directory for all Python versions + + USER_SITE is the user specific site-packages directory + + USER_SITE/.. can be used for data. + """ + global USER_BASE, USER_SITE, ENABLE_USER_SITE + env_base = os.environ.get("PYTHONUSERBASE", None) + + def joinuser(*args): + return os.path.expanduser(os.path.join(*args)) + + #if sys.platform in ('os2emx', 'riscos'): + # # Don't know what to put here + # USER_BASE = '' + # USER_SITE = '' + if os.name == "nt": + base = os.environ.get("APPDATA") or "~" + if env_base: + USER_BASE = env_base + else: + USER_BASE = joinuser(base, "Python") + USER_SITE = os.path.join(USER_BASE, + "Python" + sys.version[0] + sys.version[2], + "site-packages") + else: + if env_base: + USER_BASE = env_base + else: + USER_BASE = joinuser("~", ".local") + USER_SITE = os.path.join(USER_BASE, "lib", + "python" + sys.version[:3], + "site-packages") + + if ENABLE_USER_SITE and os.path.isdir(USER_SITE): + addsitedir(USER_SITE, known_paths) + if ENABLE_USER_SITE: + for dist_libdir in ("lib", "local/lib"): + user_site = os.path.join(USER_BASE, dist_libdir, + "python" + sys.version[:3], + "dist-packages") + if os.path.isdir(user_site): + addsitedir(user_site, known_paths) + return known_paths + + + +def setBEGINLIBPATH(): + """The OS/2 EMX port has optional extension modules that do double duty + as DLLs (and must use the .DLL file extension) for other extensions. + The library search path needs to be amended so these will be found + during module import. Use BEGINLIBPATH so that these are at the start + of the library search path. + + """ + dllpath = os.path.join(sys.prefix, "Lib", "lib-dynload") + libpath = os.environ['BEGINLIBPATH'].split(';') + if libpath[-1]: + libpath.append(dllpath) + else: + libpath[-1] = dllpath + os.environ['BEGINLIBPATH'] = ';'.join(libpath) + + +def setquit(): + """Define new built-ins 'quit' and 'exit'. + These are simply strings that display a hint on how to exit. + + """ + if os.sep == ':': + eof = 'Cmd-Q' + elif os.sep == '\\': + eof = 'Ctrl-Z plus Return' + else: + eof = 'Ctrl-D (i.e. EOF)' + + class Quitter(object): + def __init__(self, name): + self.name = name + def __repr__(self): + return 'Use %s() or %s to exit' % (self.name, eof) + def __call__(self, code=None): + # Shells like IDLE catch the SystemExit, but listen when their + # stdin wrapper is closed. + try: + sys.stdin.close() + except: + pass + raise SystemExit(code) + builtins.quit = Quitter('quit') + builtins.exit = Quitter('exit') + + +class _Printer(object): + """interactive prompt objects for printing the license text, a list of + contributors and the copyright notice.""" + + MAXLINES = 23 + + def __init__(self, name, data, files=(), dirs=()): + self.__name = name + self.__data = data + self.__files = files + self.__dirs = dirs + self.__lines = None + + def __setup(self): + if self.__lines: + return + data = None + for dir in self.__dirs: + for filename in self.__files: + filename = os.path.join(dir, filename) + try: + fp = open(filename, "rU") + data = fp.read() + fp.close() + break + except IOError: + pass + if data: + break + if not data: + data = self.__data + self.__lines = data.split('\n') + self.__linecnt = len(self.__lines) + + def __repr__(self): + self.__setup() + if len(self.__lines) <= self.MAXLINES: + return "\n".join(self.__lines) + else: + return "Type %s() to see the full %s text" % ((self.__name,)*2) + + def __call__(self): + self.__setup() + prompt = 'Hit Return for more, or q (and Return) to quit: ' + lineno = 0 + while 1: + try: + for i in range(lineno, lineno + self.MAXLINES): + print(self.__lines[i]) + except IndexError: + break + else: + lineno += self.MAXLINES + key = None + while key is None: + try: + key = raw_input(prompt) + except NameError: + key = input(prompt) + if key not in ('', 'q'): + key = None + if key == 'q': + break + +def setcopyright(): + """Set 'copyright' and 'credits' in __builtin__""" + builtins.copyright = _Printer("copyright", sys.copyright) + if _is_jython: + builtins.credits = _Printer( + "credits", + "Jython is maintained by the Jython developers (www.jython.org).") + elif _is_pypy: + builtins.credits = _Printer( + "credits", + "PyPy is maintained by the PyPy developers: http://pypy.org/") + else: + builtins.credits = _Printer("credits", """\ + Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands + for supporting Python development. See www.python.org for more information.""") + here = os.path.dirname(os.__file__) + builtins.license = _Printer( + "license", "See http://www.python.org/%.3s/license.html" % sys.version, + ["LICENSE.txt", "LICENSE"], + [os.path.join(here, os.pardir), here, os.curdir]) + + +class _Helper(object): + """Define the built-in 'help'. + This is a wrapper around pydoc.help (with a twist). + + """ + + def __repr__(self): + return "Type help() for interactive help, " \ + "or help(object) for help about object." + def __call__(self, *args, **kwds): + import pydoc + return pydoc.help(*args, **kwds) + +def sethelper(): + builtins.help = _Helper() + +def aliasmbcs(): + """On Windows, some default encodings are not provided by Python, + while they are always available as "mbcs" in each locale. Make + them usable by aliasing to "mbcs" in such a case.""" + if sys.platform == 'win32': + import locale, codecs + enc = locale.getdefaultlocale()[1] + if enc.startswith('cp'): # "cp***" ? + try: + codecs.lookup(enc) + except LookupError: + import encodings + encodings._cache[enc] = encodings._unknown + encodings.aliases.aliases[enc] = 'mbcs' + +def setencoding(): + """Set the string encoding used by the Unicode implementation. The + default is 'ascii', but if you're willing to experiment, you can + change this.""" + encoding = "ascii" # Default value set by _PyUnicode_Init() + if 0: + # Enable to support locale aware default string encodings. + import locale + loc = locale.getdefaultlocale() + if loc[1]: + encoding = loc[1] + if 0: + # Enable to switch off string to Unicode coercion and implicit + # Unicode to string conversion. + encoding = "undefined" + if encoding != "ascii": + # On Non-Unicode builds this will raise an AttributeError... + sys.setdefaultencoding(encoding) # Needs Python Unicode build ! + + +def execsitecustomize(): + """Run custom site specific code, if available.""" + try: + import sitecustomize + except ImportError: + pass + +def virtual_install_main_packages(): + f = open(os.path.join(os.path.dirname(__file__), 'orig-prefix.txt')) + sys.real_prefix = f.read().strip() + f.close() + pos = 2 + hardcoded_relative_dirs = [] + if sys.path[0] == '': + pos += 1 + if _is_jython: + paths = [os.path.join(sys.real_prefix, 'Lib')] + elif _is_pypy: + if sys.version_info > (3, 2): + cpyver = '%d' % sys.version_info[0] + elif sys.pypy_version_info >= (1, 5): + cpyver = '%d.%d' % sys.version_info[:2] + else: + cpyver = '%d.%d.%d' % sys.version_info[:3] + paths = [os.path.join(sys.real_prefix, 'lib_pypy'), + os.path.join(sys.real_prefix, 'lib-python', cpyver)] + if sys.pypy_version_info < (1, 9): + paths.insert(1, os.path.join(sys.real_prefix, + 'lib-python', 'modified-%s' % cpyver)) + hardcoded_relative_dirs = paths[:] # for the special 'darwin' case below + # + # This is hardcoded in the Python executable, but relative to sys.prefix: + for path in paths[:]: + plat_path = os.path.join(path, 'plat-%s' % sys.platform) + if os.path.exists(plat_path): + paths.append(plat_path) + elif sys.platform == 'win32': + paths = [os.path.join(sys.real_prefix, 'Lib'), os.path.join(sys.real_prefix, 'DLLs')] + else: + paths = [os.path.join(sys.real_prefix, 'lib', 'python'+sys.version[:3])] + hardcoded_relative_dirs = paths[:] # for the special 'darwin' case below + lib64_path = os.path.join(sys.real_prefix, 'lib64', 'python'+sys.version[:3]) + if os.path.exists(lib64_path): + if _is_64bit: + paths.insert(0, lib64_path) + else: + paths.append(lib64_path) + # This is hardcoded in the Python executable, but relative to + # sys.prefix. Debian change: we need to add the multiarch triplet + # here, which is where the real stuff lives. As per PEP 421, in + # Python 3.3+, this lives in sys.implementation, while in Python 2.7 + # it lives in sys. + try: + arch = getattr(sys, 'implementation', sys)._multiarch + except AttributeError: + # This is a non-multiarch aware Python. Fallback to the old way. + arch = sys.platform + plat_path = os.path.join(sys.real_prefix, 'lib', + 'python'+sys.version[:3], + 'plat-%s' % arch) + if os.path.exists(plat_path): + paths.append(plat_path) + # This is hardcoded in the Python executable, but + # relative to sys.prefix, so we have to fix up: + for path in list(paths): + tk_dir = os.path.join(path, 'lib-tk') + if os.path.exists(tk_dir): + paths.append(tk_dir) + + # These are hardcoded in the Apple's Python executable, + # but relative to sys.prefix, so we have to fix them up: + if sys.platform == 'darwin': + hardcoded_paths = [os.path.join(relative_dir, module) + for relative_dir in hardcoded_relative_dirs + for module in ('plat-darwin', 'plat-mac', 'plat-mac/lib-scriptpackages')] + + for path in hardcoded_paths: + if os.path.exists(path): + paths.append(path) + + sys.path.extend(paths) + +def force_global_eggs_after_local_site_packages(): + """ + Force easy_installed eggs in the global environment to get placed + in sys.path after all packages inside the virtualenv. This + maintains the "least surprise" result that packages in the + virtualenv always mask global packages, never the other way + around. + + """ + egginsert = getattr(sys, '__egginsert', 0) + for i, path in enumerate(sys.path): + if i > egginsert and path.startswith(sys.prefix): + egginsert = i + sys.__egginsert = egginsert + 1 + +def virtual_addsitepackages(known_paths): + force_global_eggs_after_local_site_packages() + return addsitepackages(known_paths, sys_prefix=sys.real_prefix) + +def fixclasspath(): + """Adjust the special classpath sys.path entries for Jython. These + entries should follow the base virtualenv lib directories. + """ + paths = [] + classpaths = [] + for path in sys.path: + if path == '__classpath__' or path.startswith('__pyclasspath__'): + classpaths.append(path) + else: + paths.append(path) + sys.path = paths + sys.path.extend(classpaths) + +def execusercustomize(): + """Run custom user specific code, if available.""" + try: + import usercustomize + except ImportError: + pass + + +def main(): + global ENABLE_USER_SITE + virtual_install_main_packages() + abs__file__() + paths_in_sys = removeduppaths() + if (os.name == "posix" and sys.path and + os.path.basename(sys.path[-1]) == "Modules"): + addbuilddir() + if _is_jython: + fixclasspath() + GLOBAL_SITE_PACKAGES = not os.path.exists(os.path.join(os.path.dirname(__file__), 'no-global-site-packages.txt')) + if not GLOBAL_SITE_PACKAGES: + ENABLE_USER_SITE = False + if ENABLE_USER_SITE is None: + ENABLE_USER_SITE = check_enableusersite() + paths_in_sys = addsitepackages(paths_in_sys) + paths_in_sys = addusersitepackages(paths_in_sys) + if GLOBAL_SITE_PACKAGES: + paths_in_sys = virtual_addsitepackages(paths_in_sys) + if sys.platform == 'os2emx': + setBEGINLIBPATH() + setquit() + setcopyright() + sethelper() + aliasmbcs() + setencoding() + execsitecustomize() + if ENABLE_USER_SITE: + execusercustomize() + # Remove sys.setdefaultencoding() so that users cannot change the + # encoding after initialization. The test for presence is needed when + # this module is run as a script, because this code is executed twice. + if hasattr(sys, "setdefaultencoding"): + del sys.setdefaultencoding + +main() + +def _script(): + help = """\ + %s [--user-base] [--user-site] + + Without arguments print some useful information + With arguments print the value of USER_BASE and/or USER_SITE separated + by '%s'. + + Exit codes with --user-base or --user-site: + 0 - user site directory is enabled + 1 - user site directory is disabled by user + 2 - uses site directory is disabled by super user + or for security reasons + >2 - unknown error + """ + args = sys.argv[1:] + if not args: + print("sys.path = [") + for dir in sys.path: + print(" %r," % (dir,)) + print("]") + def exists(path): + if os.path.isdir(path): + return "exists" + else: + return "doesn't exist" + print("USER_BASE: %r (%s)" % (USER_BASE, exists(USER_BASE))) + print("USER_SITE: %r (%s)" % (USER_SITE, exists(USER_BASE))) + print("ENABLE_USER_SITE: %r" % ENABLE_USER_SITE) + sys.exit(0) + + buffer = [] + if '--user-base' in args: + buffer.append(USER_BASE) + if '--user-site' in args: + buffer.append(USER_SITE) + + if buffer: + print(os.pathsep.join(buffer)) + if ENABLE_USER_SITE: + sys.exit(0) + elif ENABLE_USER_SITE is False: + sys.exit(1) + elif ENABLE_USER_SITE is None: + sys.exit(2) + else: + sys.exit(3) + else: + import textwrap + print(textwrap.dedent(help % (sys.argv[0], os.pathsep))) + sys.exit(10) + +if __name__ == '__main__': + _script() diff --git a/env/lib/python3.7/sre_compile.py b/env/lib/python3.7/sre_compile.py new file mode 120000 index 0000000..8df75bd --- /dev/null +++ b/env/lib/python3.7/sre_compile.py @@ -0,0 +1 @@ +/usr/lib/python3.7/sre_compile.py \ No newline at end of file diff --git a/env/lib/python3.7/sre_constants.py b/env/lib/python3.7/sre_constants.py new file mode 120000 index 0000000..c08169c --- /dev/null +++ b/env/lib/python3.7/sre_constants.py @@ -0,0 +1 @@ +/usr/lib/python3.7/sre_constants.py \ No newline at end of file diff --git a/env/lib/python3.7/sre_parse.py b/env/lib/python3.7/sre_parse.py new file mode 120000 index 0000000..481f82d --- /dev/null +++ b/env/lib/python3.7/sre_parse.py @@ -0,0 +1 @@ +/usr/lib/python3.7/sre_parse.py \ No newline at end of file diff --git a/env/lib/python3.7/stat.py b/env/lib/python3.7/stat.py new file mode 120000 index 0000000..5d1b626 --- /dev/null +++ b/env/lib/python3.7/stat.py @@ -0,0 +1 @@ +/usr/lib/python3.7/stat.py \ No newline at end of file diff --git a/env/lib/python3.7/struct.py b/env/lib/python3.7/struct.py new file mode 120000 index 0000000..af49495 --- /dev/null +++ b/env/lib/python3.7/struct.py @@ -0,0 +1 @@ +/usr/lib/python3.7/struct.py \ No newline at end of file diff --git a/env/lib/python3.7/tarfile.py b/env/lib/python3.7/tarfile.py new file mode 120000 index 0000000..b7fa773 --- /dev/null +++ b/env/lib/python3.7/tarfile.py @@ -0,0 +1 @@ +/usr/lib/python3.7/tarfile.py \ No newline at end of file diff --git a/env/lib/python3.7/tempfile.py b/env/lib/python3.7/tempfile.py new file mode 120000 index 0000000..570b094 --- /dev/null +++ b/env/lib/python3.7/tempfile.py @@ -0,0 +1 @@ +/usr/lib/python3.7/tempfile.py \ No newline at end of file diff --git a/env/lib/python3.7/token.py b/env/lib/python3.7/token.py new file mode 120000 index 0000000..d67b104 --- /dev/null +++ b/env/lib/python3.7/token.py @@ -0,0 +1 @@ +/usr/lib/python3.7/token.py \ No newline at end of file diff --git a/env/lib/python3.7/tokenize.py b/env/lib/python3.7/tokenize.py new file mode 120000 index 0000000..55e6050 --- /dev/null +++ b/env/lib/python3.7/tokenize.py @@ -0,0 +1 @@ +/usr/lib/python3.7/tokenize.py \ No newline at end of file diff --git a/env/lib/python3.7/types.py b/env/lib/python3.7/types.py new file mode 120000 index 0000000..aa3096f --- /dev/null +++ b/env/lib/python3.7/types.py @@ -0,0 +1 @@ +/usr/lib/python3.7/types.py \ No newline at end of file diff --git a/env/lib/python3.7/warnings.py b/env/lib/python3.7/warnings.py new file mode 120000 index 0000000..8dd72e2 --- /dev/null +++ b/env/lib/python3.7/warnings.py @@ -0,0 +1 @@ +/usr/lib/python3.7/warnings.py \ No newline at end of file diff --git a/env/lib/python3.7/weakref.py b/env/lib/python3.7/weakref.py new file mode 120000 index 0000000..c02784d --- /dev/null +++ b/env/lib/python3.7/weakref.py @@ -0,0 +1 @@ +/usr/lib/python3.7/weakref.py \ No newline at end of file diff --git a/env/pip-selfcheck.json b/env/pip-selfcheck.json new file mode 100644 index 0000000..7b9f0fe --- /dev/null +++ b/env/pip-selfcheck.json @@ -0,0 +1 @@ +{"last_check":"2018-12-28T22:10:35Z","pypi_version":"18.1"} \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f2590b2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +ipwhois diff --git a/testData.txt b/testData.txt new file mode 100644 index 0000000..db9e002 --- /dev/null +++ b/testData.txt @@ -0,0 +1,183 @@ + 1 101.166.225.40 + 1 101.187.223.112 + 1 10.2.0.243 + 1 103.10.99.234 + 1 103.227.21.224 + 1 104.154.198.228 + 1 104.47.117.68 + 1 109.123.101.103 + 1 110.249.143.106 + 1 111.38.216.5 + 1 111.67.31.6 + 1 1.121.101.134 + 1 1.126.108.83 + 1 112.91.108.190 + 1 1.132.107.219 + 1 1.136.108.33 + 1 1.136.108.5 + 1 115.84.112.138 + 1 120.148.65.182 + 1 120.150.221.35 + 1 120.209.233.191 + 1 121.221.69.135 + 1 122.106.224.146 + 1 124.185.119.95 + 1 124.193.199.202 + 1 127.0.0.1 + 1 132.3.9.79 + 1 132.3.9.80 + 1 137.147.147.70 + 1 139.130.182.134 + 1 151.231.79.195 + 1 162.158.255.83 + 1 162.158.78.101 + 1 162.158.78.113 + 1 162.158.78.143 + 1 162.158.78.155 + 1 162.158.78.5 + 1 162.158.78.83 + 1 162.158.79.108 + 1 162.158.79.132 + 1 162.158.79.144 + 1 162.158.79.168 + 1 162.158.79.48 + 1 162.158.79.66 + 1 172.68.211.227 + 1 172.68.65.211 + 1 172.68.65.217 + 1 172.68.65.223 + 1 172.68.65.241 + 1 172.68.65.37 + 1 172.69.22.213 + 1 172.69.33.192 + 1 172.69.62.11 + 1 172.69.62.131 + 1 172.69.62.143 + 1 172.69.62.149 + 1 172.69.62.185 + 1 172.69.62.53 + 1 172.69.62.65 + 1 173.245.54.26 + 1 173.245.54.44 + 1 173.252.98.201 + 1 175.36.210.207 + 1 176.10.125.27 + 1 178.140.233.218 + 1 178.234.35.42 + 1 185.30.176.187 + 1 185.30.177.73 + 1 185.86.149.131 + 1 192.0.101.226 + 1 192.88.134.14 + 1 199.101.132.161 + 1 202.153.70.141 + 1 202.9.16.14 + 1 204.11.32.249 + 1 207.46.13.0 + 1 207.46.13.132 + 1 207.46.13.174 + 1 207.46.13.61 + 1 208.64.39.184 + 1 208.79.209.58 + 1 211.118.26.122 + 1 218.22.206.178 + 1 218.66.84.85 + 1 219.88.246.28 + 1 220.171.28.146 + 1 220.174.209.154 + 1 2400 + 1 27.151.116.18 + 1 35.185.103.191 + 1 35.185.113.230 + 1 35.227.63.41 + 1 37.9.113.95 + 1 43.248.55.247 + 1 45.126.47.164 + 1 49.195.118.215 + 1 49.195.204.239 + 1 5.41.10.110 + 1 5.45.207.18 + 1 58.108.204.108 + 1 58.111.149.182 + 1 60.166.52.51 + 1 60.215.144.50 + 1 63.143.42.250 + 1 66.249.69.126 + 1 66.249.79.144 + 1 66.249.79.158 + 1 66.249.79.27 + 1 66.249.79.61 + 1 66.249.79.7 + 1 66.249.79.90 + 1 69.171.225.86 + 1 69.175.3.11 + 1 73.248.226.154 + 1 77.101.195.157 + 1 77.75.78.170 + 1 98.101.54.102 + 2 10.10.9.238 + 2 101.178.3.124 + 2 103.75.205.28 + 2 110.141.40.11 + 2 1.132.111.146 + 2 118.209.106.244 + 2 120.203.25.58 + 2 120.22.58.32 + 2 124.149.207.123 + 2 124.183.205.152 + 2 1.255.70.114 + 2 13.69.78.34 + 2 13.84.48.123 + 2 13.89.226.135 + 2 13.89.234.94 + 2 13.89.236.228 + 2 144.139.70.151 + 2 162.158.79.228 + 2 168.62.184.200 + 2 180.95.27.37 + 2 185.29.10.31 + 2 185.93.231.14 + 2 194.187.248.52 + 2 203.196.37.229 + 2 210.10.173.195 + 2 213.44.246.57 + 2 23.101.146.22 + 2 40.123.42.42 + 2 40.123.46.104 + 2 40.123.47.194 + 2 40.69.140.47 + 2 40.69.171.237 + 2 40.76.12.12 + 2 40.76.1.22 + 2 50.4.140.177 + 2 52.165.154.70 + 2 52.165.158.40 + 2 58.106.133.27 + 2 66.249.79.3 + 2 89.40.123.219 + 2 90.94.38.162 + 3 103.217.166.29 + 3 114.198.9.220 + 3 66.249.79.159 + 4 101.183.140.224 + 4 103.224.160.194 + 4 138.217.43.170 + 4 13.89.233.10 + 4 203.173.31.104 + 4 203.220.162.117 + 6 103.42.110.4 + 6 120.150.133.75 + 6 203.5.82.2 + 6 58.111.132.93 + 6 60.241.198.14 + 7 121.218.164.246 + 8 1.129.107.203 + 8 194.6.231.240 + 11 12.216.166.60 + 11 165.228.5.225 + 12 153.107.192.207 + 13 120.154.177.224 + 21 203.206.172.110 + 42 + 53 0.0.0.0 + 56 39.42.184.251 \ No newline at end of file diff --git a/untitled b/untitled new file mode 100644 index 0000000..e69de29