├── .eggs ├── README.txt └── setuptools-46.0.0-py3.6.egg │ ├── EGG-INFO │ ├── LICENSE │ ├── PKG-INFO │ ├── RECORD │ ├── WHEEL │ ├── dependency_links.txt │ ├── entry_points.txt │ ├── top_level.txt │ └── zip-safe │ ├── easy_install.py │ ├── pkg_resources │ ├── __init__.py │ ├── _vendor │ │ ├── __init__.py │ │ ├── appdirs.py │ │ ├── packaging │ │ │ ├── __about__.py │ │ │ ├── __init__.py │ │ │ ├── _compat.py │ │ │ ├── _structures.py │ │ │ ├── markers.py │ │ │ ├── requirements.py │ │ │ ├── specifiers.py │ │ │ ├── utils.py │ │ │ └── version.py │ │ ├── pyparsing.py │ │ └── six.py │ ├── extern │ │ └── __init__.py │ ├── py2_warn.py │ └── py31compat.py │ └── setuptools │ ├── __init__.py │ ├── _deprecation_warning.py │ ├── _imp.py │ ├── _vendor │ ├── __init__.py │ ├── ordered_set.py │ ├── packaging │ │ ├── __about__.py │ │ ├── __init__.py │ │ ├── _compat.py │ │ ├── _structures.py │ │ ├── markers.py │ │ ├── requirements.py │ │ ├── specifiers.py │ │ ├── tags.py │ │ ├── utils.py │ │ └── version.py │ ├── pyparsing.py │ └── six.py │ ├── archive_util.py │ ├── build_meta.py │ ├── cli-32.exe │ ├── cli-64.exe │ ├── cli.exe │ ├── command │ ├── __init__.py │ ├── alias.py │ ├── bdist_egg.py │ ├── bdist_rpm.py │ ├── bdist_wininst.py │ ├── build_clib.py │ ├── build_ext.py │ ├── build_py.py │ ├── develop.py │ ├── dist_info.py │ ├── easy_install.py │ ├── egg_info.py │ ├── install.py │ ├── install_egg_info.py │ ├── install_lib.py │ ├── install_scripts.py │ ├── launcher manifest.xml │ ├── py36compat.py │ ├── register.py │ ├── rotate.py │ ├── saveopts.py │ ├── sdist.py │ ├── setopt.py │ ├── test.py │ ├── upload.py │ └── upload_docs.py │ ├── config.py │ ├── dep_util.py │ ├── depends.py │ ├── dist.py │ ├── errors.py │ ├── extension.py │ ├── extern │ └── __init__.py │ ├── glob.py │ ├── gui-32.exe │ ├── gui-64.exe │ ├── gui.exe │ ├── installer.py │ ├── launch.py │ ├── lib2to3_ex.py │ ├── monkey.py │ ├── msvc.py │ ├── namespaces.py │ ├── package_index.py │ ├── py27compat.py │ ├── py31compat.py │ ├── py33compat.py │ ├── py34compat.py │ ├── sandbox.py │ ├── script (dev).tmpl │ ├── script.tmpl │ ├── site-patch.py │ ├── ssl_support.py │ ├── unicode_utils.py │ ├── version.py │ ├── wheel.py │ └── windows_support.py ├── .github └── workflows │ └── pythonpackage.yml ├── .gitignore ├── LICENSE ├── README.md ├── build └── lib │ └── simpledorff │ ├── __init__.py │ ├── data_transforms.py │ ├── metrics.py │ └── simpledorff.py ├── requirements.txt ├── setup.py ├── simpledorff ├── __init__.py ├── data_transforms.py ├── metrics.py └── simpledorff.py └── tests ├── _trial_temp ├── _trial_marker └── test.log └── test_simpledorff.py /.eggs/README.txt: -------------------------------------------------------------------------------- 1 | This directory contains eggs that were downloaded by setuptools to build, test, and run plug-ins. 2 | 3 | This directory caches those eggs to prevent repeated downloads. 4 | 5 | However, it is safe to delete this directory. 6 | 7 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/EGG-INFO/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2016 Jason R Coombs 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/EGG-INFO/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 2.1 2 | Name: setuptools 3 | Version: 46.0.0 4 | Summary: Easily download, build, install, upgrade, and uninstall Python packages 5 | Home-page: https://github.com/pypa/setuptools 6 | Author: Python Packaging Authority 7 | Author-email: distutils-sig@python.org 8 | License: UNKNOWN 9 | Project-URL: Documentation, https://setuptools.readthedocs.io/ 10 | Keywords: CPAN PyPI distutils eggs package management 11 | Platform: UNKNOWN 12 | Classifier: Development Status :: 5 - Production/Stable 13 | Classifier: Intended Audience :: Developers 14 | Classifier: License :: OSI Approved :: MIT License 15 | Classifier: Operating System :: OS Independent 16 | Classifier: Programming Language :: Python :: 3 17 | Classifier: Programming Language :: Python :: 3 :: Only 18 | Classifier: Programming Language :: Python :: 3.5 19 | Classifier: Programming Language :: Python :: 3.6 20 | Classifier: Programming Language :: Python :: 3.7 21 | Classifier: Programming Language :: Python :: 3.8 22 | Classifier: Topic :: Software Development :: Libraries :: Python Modules 23 | Classifier: Topic :: System :: Archiving :: Packaging 24 | Classifier: Topic :: System :: Systems Administration 25 | Classifier: Topic :: Utilities 26 | Requires-Python: >=3.5 27 | Description-Content-Type: text/x-rst; charset=UTF-8 28 | Provides-Extra: certs 29 | Requires-Dist: certifi (==2016.9.26) ; extra == 'certs' 30 | Provides-Extra: docs 31 | Requires-Dist: sphinx ; extra == 'docs' 32 | Requires-Dist: jaraco.packaging (>=6.1) ; extra == 'docs' 33 | Requires-Dist: rst.linker (>=1.9) ; extra == 'docs' 34 | Provides-Extra: ssl 35 | Requires-Dist: wincertstore (==0.2) ; (sys_platform == "win32") and extra == 'ssl' 36 | Provides-Extra: tests 37 | Requires-Dist: mock ; extra == 'tests' 38 | Requires-Dist: pytest-flake8 ; extra == 'tests' 39 | Requires-Dist: virtualenv (>=13.0.0) ; extra == 'tests' 40 | Requires-Dist: pytest-virtualenv (>=1.2.7) ; extra == 'tests' 41 | Requires-Dist: pytest (>=3.7) ; extra == 'tests' 42 | Requires-Dist: wheel ; extra == 'tests' 43 | Requires-Dist: coverage (>=4.5.1) ; extra == 'tests' 44 | Requires-Dist: pytest-cov (>=2.5.1) ; extra == 'tests' 45 | Requires-Dist: pip (>=19.1) ; extra == 'tests' 46 | Requires-Dist: futures ; (python_version == "2.7") and extra == 'tests' 47 | Requires-Dist: flake8-2020 ; (python_version >= "3.6") and extra == 'tests' 48 | Requires-Dist: paver ; (python_version >= "3.6") and extra == 'tests' 49 | 50 | .. image:: https://img.shields.io/pypi/v/setuptools.svg 51 | :target: https://pypi.org/project/setuptools 52 | 53 | .. image:: https://img.shields.io/readthedocs/setuptools/latest.svg 54 | :target: https://setuptools.readthedocs.io 55 | 56 | .. image:: https://img.shields.io/travis/pypa/setuptools/master.svg?label=Linux%20CI&logo=travis&logoColor=white 57 | :target: https://travis-ci.org/pypa/setuptools 58 | 59 | .. image:: https://img.shields.io/appveyor/ci/pypa/setuptools/master.svg?label=Windows%20CI&logo=appveyor&logoColor=white 60 | :target: https://ci.appveyor.com/project/pypa/setuptools/branch/master 61 | 62 | .. image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white 63 | :target: https://codecov.io/gh/pypa/setuptools 64 | 65 | .. image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat 66 | :target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme 67 | 68 | .. image:: https://img.shields.io/pypi/pyversions/setuptools.svg 69 | 70 | See the `Installation Instructions 71 | `_ in the Python Packaging 72 | User's Guide for instructions on installing, upgrading, and uninstalling 73 | Setuptools. 74 | 75 | Questions and comments should be directed to the `distutils-sig 76 | mailing list `_. 77 | Bug reports and especially tested patches may be 78 | submitted directly to the `bug tracker 79 | `_. 80 | 81 | To report a security vulnerability, please use the 82 | `Tidelift security contact `_. 83 | Tidelift will coordinate the fix and disclosure. 84 | 85 | 86 | For Enterprise 87 | ============== 88 | 89 | Available as part of the Tidelift Subscription. 90 | 91 | Setuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use. 92 | 93 | `Learn more `_. 94 | 95 | Code of Conduct 96 | =============== 97 | 98 | Everyone interacting in the setuptools project's codebases, issue trackers, 99 | chat rooms, and mailing lists is expected to follow the 100 | `PyPA Code of Conduct `_. 101 | 102 | 103 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/EGG-INFO/RECORD: -------------------------------------------------------------------------------- 1 | easy_install.py,sha256=MDC9vt5AxDsXX5qcKlBz2TnW6Tpuv_AobnfhCJ9X3PM,126 2 | pkg_resources/__init__.py,sha256=nho0LS-Xp9yHF0G4oWfaTiNh8W5KDBzEYxpBmlcKBak,108449 3 | pkg_resources/py2_warn.py,sha256=dxh7Vp_65dnpVzV-MtdsQsxqksgBD6CKpda2nZAtti0,723 4 | pkg_resources/py31compat.py,sha256=-WQ0e4c3RG_acdhwC3gLiXhP_lg4G5q7XYkZkQg0gxU,558 5 | pkg_resources/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 6 | pkg_resources/_vendor/appdirs.py,sha256=MievUEuv3l_mQISH5SF0shDk_BNhHHzYiAPrT3ITN4I,24701 7 | pkg_resources/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055 8 | pkg_resources/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 9 | pkg_resources/_vendor/packaging/__about__.py,sha256=zkcCPTN_6TcLW0Nrlg0176-R1QQ_WVPTm8sz1R4-HjM,720 10 | pkg_resources/_vendor/packaging/__init__.py,sha256=_vNac5TrzwsrzbOFIbF-5cHqc_Y2aPT2D7zrIR06BOo,513 11 | pkg_resources/_vendor/packaging/_compat.py,sha256=Vi_A0rAQeHbU-a9X0tt1yQm9RqkgQbDSxzRw8WlU9kA,860 12 | pkg_resources/_vendor/packaging/_structures.py,sha256=RImECJ4c_wTlaTYYwZYLHEiebDMaAJmK1oPARhw1T5o,1416 13 | pkg_resources/_vendor/packaging/markers.py,sha256=uEcBBtGvzqltgnArqb9c4RrcInXezDLos14zbBHhWJo,8248 14 | pkg_resources/_vendor/packaging/requirements.py,sha256=SikL2UynbsT0qtY9ltqngndha_sfo0w6XGFhAhoSoaQ,4355 15 | pkg_resources/_vendor/packaging/specifiers.py,sha256=SAMRerzO3fK2IkFZCaZkuwZaL_EGqHNOz4pni4vhnN0,28025 16 | pkg_resources/_vendor/packaging/utils.py,sha256=3m6WvPm6NNxE8rkTGmn0r75B_GZSGg7ikafxHsBN1WA,421 17 | pkg_resources/_vendor/packaging/version.py,sha256=OwGnxYfr2ghNzYx59qWIBkrK3SnB6n-Zfd1XaLpnnM0,11556 18 | pkg_resources/extern/__init__.py,sha256=w_3T8ntsvFFioQYOgYoGGqafDiv4sLzecQRDjsB5yeE,2101 19 | setuptools/__init__.py,sha256=LYVITYWdaVURtuV7shz0Xv-0BVb6emZXp2Hm6JzuBp4,7253 20 | setuptools/_deprecation_warning.py,sha256=jU9-dtfv6cKmtQJOXN8nP1mm7gONw5kKEtiPtbwnZyI,218 21 | setuptools/_imp.py,sha256=Qx0LJzEBaWk_6PfICamJtfBN2rh5K9sJq1wXvtZW-mc,2388 22 | setuptools/archive_util.py,sha256=2VqSBaoRomeA2al-hYnyB-33ehP4exrknpZNy7qWin0,6626 23 | setuptools/build_meta.py,sha256=n3-3HF0uKfFAzNP02yz2V7q1ydlPaQ1b_IxHG33yWjU,9960 24 | setuptools/cli-32.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536 25 | setuptools/cli-64.exe,sha256=KLABu5pyrnokJCv6skjXZ6GsXeyYHGcqOUT3oHI3Xpo,74752 26 | setuptools/cli.exe,sha256=dfEuovMNnA2HLa3jRfMPVi5tk4R7alCbpTvuxtCyw0Y,65536 27 | setuptools/config.py,sha256=6SB2OY3qcooOJmG_rsK_s0pKBsorBlDpfMJUyzjQIGk,20575 28 | setuptools/dep_util.py,sha256=BDx1BkzNQntvAB4alypHbW5UVBzjqths000PrUL4Zqc,949 29 | setuptools/depends.py,sha256=qt2RWllArRvhnm8lxsyRpcthEZYp4GHQgREl1q0LkFw,5517 30 | setuptools/dist.py,sha256=bzpZX_xqMtSj0Bbn_q-sbzASjJEd86oZbriXJfkTOj8,39027 31 | setuptools/errors.py,sha256=MVOcv381HNSajDgEUWzOQ4J6B5BHCBMSjHfaWcEwA1o,524 32 | setuptools/extension.py,sha256=uc6nHI-MxwmNCNPbUiBnybSyqhpJqjbhvOQ-emdvt_E,1729 33 | setuptools/glob.py,sha256=o75cHrOxYsvn854thSxE0x9k8JrKDuhP_rRXlVB00Q4,5084 34 | setuptools/gui-32.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536 35 | setuptools/gui-64.exe,sha256=aYKMhX1IJLn4ULHgWX0sE0yREUt6B3TEHf_jOw6yNyE,75264 36 | setuptools/gui.exe,sha256=XBr0bHMA6Hpz2s9s9Bzjl-PwXfa9nH4ie0rFn4V2kWA,65536 37 | setuptools/installer.py,sha256=8_Anc1VxnB92XKZjVmEAf8zfTfmjdv1cUPuTxHX_Q1I,5336 38 | setuptools/launch.py,sha256=sd7ejwhBocCDx_wG9rIs0OaZ8HtmmFU8ZC6IR_S0Lvg,787 39 | setuptools/lib2to3_ex.py,sha256=t5e12hbR2pi9V4ezWDTB4JM-AISUnGOkmcnYHek3xjg,2013 40 | setuptools/monkey.py,sha256=FGc9fffh7gAxMLFmJs2DW_OYWpBjkdbNS2n14UAK4NA,5264 41 | setuptools/msvc.py,sha256=Np7hXrKnn3EzqV3TQBOVDejhrveWrOQOgflAWgI2PGU,50989 42 | setuptools/namespaces.py,sha256=QuvIR8S5-u_S8_fLjPpn_utruUIsu2twdRu_KJPrKU0,3223 43 | setuptools/package_index.py,sha256=Q_pxXudgWZbQW_XJly42JHFPf73IKX-y0ZQOEB_cLM4,40740 44 | setuptools/py27compat.py,sha256=CWHkWWAYodu3QgiIAr8-34T-G6fiSgiVF0y7h11Ld7U,1504 45 | setuptools/py31compat.py,sha256=h2rtZghOfwoGYd8sQ0-auaKiF3TcL3qX0bX3VessqcE,838 46 | setuptools/py33compat.py,sha256=SMF9Z8wnGicTOkU1uRNwZ_kz5Z_bj29PUBbqdqeeNsc,1330 47 | setuptools/py34compat.py,sha256=KYOd6ybRxjBW8NJmYD8t_UyyVmysppFXqHpFLdslGXU,245 48 | setuptools/sandbox.py,sha256=TbqKGiEXwfLYrpQhd863Dch3_yGhOmlAkhCiBYaw-ec,14284 49 | setuptools/script (dev).tmpl,sha256=RUzQzCQUaXtwdLtYHWYbIQmOaES5Brqq1FvUA_tu-5I,218 50 | setuptools/script.tmpl,sha256=WGTt5piezO27c-Dbx6l5Q4T3Ff20A5z7872hv3aAhYY,138 51 | setuptools/site-patch.py,sha256=25aScCA0GXCqUtSCbv386cTSbBl_u_kp_DJTnJssh-E,2346 52 | setuptools/ssl_support.py,sha256=TNNOq3VyV-4wkRwm0dmyIzF-iXBeWv4yIQ99eWa_bV8,8543 53 | setuptools/unicode_utils.py,sha256=NOiZ_5hD72A6w-4wVj8awHFM3n51Kmw1Ic_vx15XFqw,996 54 | setuptools/version.py,sha256=og_cuZQb0QI6ukKZFfZWPlr1HgJBPPn2vO2m_bI9ZTE,144 55 | setuptools/wheel.py,sha256=AUmt2W6wL2ZEo4opbgV_uISonAVDILbhm8E7nr3Ysl0,8468 56 | setuptools/windows_support.py,sha256=5GrfqSP2-dLGJoZTq2g6dCKkyQxxa2n5IQiXlJCoYEE,714 57 | setuptools/_vendor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 58 | setuptools/_vendor/ordered_set.py,sha256=dbaCcs27dyN9gnMWGF5nA_BrVn6Q-NrjKYJpV9_fgBs,15130 59 | setuptools/_vendor/pyparsing.py,sha256=tmrp-lu-qO1i75ZzIN5A12nKRRD1Cm4Vpk-5LR9rims,232055 60 | setuptools/_vendor/six.py,sha256=A6hdJZVjI3t_geebZ9BzUvwRrIXo0lfwzQlM2LcKyas,30098 61 | setuptools/_vendor/packaging/__about__.py,sha256=CpuMSyh1V7adw8QMjWKkY3LtdqRUkRX4MgJ6nF4stM0,744 62 | setuptools/_vendor/packaging/__init__.py,sha256=6enbp5XgRfjBjsI9-bn00HjHf5TH21PDMOKkJW8xw-w,562 63 | setuptools/_vendor/packaging/_compat.py,sha256=Ugdm-qcneSchW25JrtMIKgUxfEEBcCAz6WrEeXeqz9o,865 64 | setuptools/_vendor/packaging/_structures.py,sha256=pVd90XcXRGwpZRB_qdFuVEibhCHpX_bL5zYr9-N0mc8,1416 65 | setuptools/_vendor/packaging/markers.py,sha256=-meFl9Fr9V8rF5Rduzgett5EHK9wBYRUqssAV2pj0lw,8268 66 | setuptools/_vendor/packaging/requirements.py,sha256=3dwIJekt8RRGCUbgxX8reeAbgmZYjb0wcCRtmH63kxI,4742 67 | setuptools/_vendor/packaging/specifiers.py,sha256=0ZzQpcUnvrQ6LjR-mQRLzMr8G6hdRv-mY0VSf_amFtI,27778 68 | setuptools/_vendor/packaging/tags.py,sha256=EPLXhO6GTD7_oiWEO1U0l0PkfR8R_xivpMDHXnsTlts,12933 69 | setuptools/_vendor/packaging/utils.py,sha256=VaTC0Ei7zO2xl9ARiWmz2YFLFt89PuuhLbAlXMyAGms,1520 70 | setuptools/_vendor/packaging/version.py,sha256=Npdwnb8OHedj_2L86yiUqscujb7w_i5gmSK1PhOAFzg,11978 71 | setuptools/command/__init__.py,sha256=QCAuA9whnq8Bnoc0bBaS6Lw_KAUO0DiHYZQXEMNn5hg,568 72 | setuptools/command/alias.py,sha256=KjpE0sz_SDIHv3fpZcIQK-sCkJz-SrC6Gmug6b9Nkc8,2426 73 | setuptools/command/bdist_egg.py,sha256=ozITJYsQaxztvsQYZisp9CJqken1ed_EIYci8qgmorU,18406 74 | setuptools/command/bdist_rpm.py,sha256=B7l0TnzCGb-0nLlm6rS00jWLkojASwVmdhW2w5Qz_Ak,1508 75 | setuptools/command/bdist_wininst.py,sha256=_6dz3lpB1tY200LxKPLM7qgwTCceOMgaWFF-jW2-pm0,637 76 | setuptools/command/build_clib.py,sha256=fWHSFGkk10VCddBWCszvNhowbG9Z9CZXVjQ2uSInoOs,4415 77 | setuptools/command/build_ext.py,sha256=X7dGN2BEoRGvm2jkIcPQvLnKzdDiqhHvVXb5uNY9cdw,13048 78 | setuptools/command/build_py.py,sha256=yWyYaaS9F3o9JbIczn064A5g1C5_UiKRDxGaTqYbtLE,9596 79 | setuptools/command/develop.py,sha256=B3-ImHP30Bxnqx-s_9Dp-fxtHhE245ACE1W5hmKY9xE,8188 80 | setuptools/command/dist_info.py,sha256=5t6kOfrdgALT-P3ogss6PF9k-Leyesueycuk3dUyZnI,960 81 | setuptools/command/easy_install.py,sha256=5gA9SUxksPHyYJTONcnfhiMtQqg0mdBumxg3t2qY3ds,87501 82 | setuptools/command/egg_info.py,sha256=0mb9iAyE5yEMoIQxLcW_PSPEqTZOX2POFxaXGJHuvT8,25548 83 | setuptools/command/install.py,sha256=8doMxeQEDoK4Eco0mO2WlXXzzp9QnsGJQ7Z7yWkZPG8,4705 84 | setuptools/command/install_egg_info.py,sha256=bMgeIeRiXzQ4DAGPV1328kcjwQjHjOWU4FngAWLV78Q,2203 85 | setuptools/command/install_lib.py,sha256=Uz42McsyHZAjrB6cw9E7Bz0xsaTbzxnM1PI9CBhiPtE,3875 86 | setuptools/command/install_scripts.py,sha256=x7sdEICuyFpaf5LuWXcTp49oYt8EeNbwKkW2Pv-TVXI,2519 87 | setuptools/command/launcher manifest.xml,sha256=xlLbjWrB01tKC0-hlVkOKkiSPbzMml2eOPtJ_ucCnbE,628 88 | setuptools/command/py36compat.py,sha256=TKqF6CPv-vsEFpOJUYmjBzmck-mCv_zHJMXO500PEAI,4994 89 | setuptools/command/register.py,sha256=kk3DxXCb5lXTvqnhfwx2g6q7iwbUmgTyXUCaBooBOUk,468 90 | setuptools/command/rotate.py,sha256=co5C1EkI7P0GGT6Tqz-T2SIj2LBJTZXYELpmao6d4KQ,2164 91 | setuptools/command/saveopts.py,sha256=za7QCBcQimKKriWcoCcbhxPjUz30gSB74zuTL47xpP4,658 92 | setuptools/command/sdist.py,sha256=14kBw_QOZ9L_RQDqgf9DAlEuoj0zC30X5mfDWeiyZwU,8092 93 | setuptools/command/setopt.py,sha256=NTWDyx-gjDF-txf4dO577s7LOzHVoKR0Mq33rFxaRr8,5085 94 | setuptools/command/test.py,sha256=okVw2id6qYh8hFAVGziX6dEYekAbaYfMtEx7XhgsSbg,9623 95 | setuptools/command/upload.py,sha256=XT3YFVfYPAmA5qhGg0euluU98ftxRUW-PzKcODMLxUs,462 96 | setuptools/command/upload_docs.py,sha256=G2gHjeNPcUGe_pr3EEk_6AoVD0E6nCp52mZgU2nkCpU,7314 97 | setuptools/extern/__init__.py,sha256=BilMS9Hq18nBaUOzcCrzoI9HnIhju45iVJBscqTqlDI,2128 98 | setuptools-46.0.0.dist-info/LICENSE,sha256=wyo6w5WvYyHv0ovnPQagDw22q4h9HCHU_sRhKNIFbVo,1078 99 | setuptools-46.0.0.dist-info/METADATA,sha256=ebIAbwQ5R6RjMOxTJQxTq2UINSV-DzEKaSFm6N1YY5w,4482 100 | setuptools-46.0.0.dist-info/WHEEL,sha256=p46_5Uhzqz6AzeSosiOnxK-zmFja1i22CrQCjmYe8ec,92 101 | setuptools-46.0.0.dist-info/dependency_links.txt,sha256=HlkCFkoK5TbZ5EMLbLKYhLcY_E31kBWD8TqW2EgmatQ,239 102 | setuptools-46.0.0.dist-info/entry_points.txt,sha256=1K5Fr0-5Ph3ZRZFuwNaw8ERGiNLVqHvdKDNt3oXGS6w,3143 103 | setuptools-46.0.0.dist-info/top_level.txt,sha256=2HUXVVwA4Pff1xgTFr3GsTXXKaPaO6vlG6oNJ_4u4Tg,38 104 | setuptools-46.0.0.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1 105 | setuptools-46.0.0.dist-info/RECORD,, 106 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/EGG-INFO/WHEEL: -------------------------------------------------------------------------------- 1 | Wheel-Version: 1.0 2 | Generator: bdist_wheel (0.33.6) 3 | Root-Is-Purelib: true 4 | Tag: py3-none-any 5 | 6 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/EGG-INFO/dependency_links.txt: -------------------------------------------------------------------------------- 1 | https://files.pythonhosted.org/packages/source/c/certifi/certifi-2016.9.26.tar.gz#md5=baa81e951a29958563689d868ef1064d 2 | https://files.pythonhosted.org/packages/source/w/wincertstore/wincertstore-0.2.zip#md5=ae728f2f007185648d0c7a8679b361e2 3 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/EGG-INFO/entry_points.txt: -------------------------------------------------------------------------------- 1 | [console_scripts] 2 | easy_install = setuptools.command.easy_install:main 3 | easy_install-3.8 = setuptools.command.easy_install:main 4 | 5 | [distutils.commands] 6 | alias = setuptools.command.alias:alias 7 | bdist_egg = setuptools.command.bdist_egg:bdist_egg 8 | bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm 9 | bdist_wininst = setuptools.command.bdist_wininst:bdist_wininst 10 | build_clib = setuptools.command.build_clib:build_clib 11 | build_ext = setuptools.command.build_ext:build_ext 12 | build_py = setuptools.command.build_py:build_py 13 | develop = setuptools.command.develop:develop 14 | dist_info = setuptools.command.dist_info:dist_info 15 | easy_install = setuptools.command.easy_install:easy_install 16 | egg_info = setuptools.command.egg_info:egg_info 17 | install = setuptools.command.install:install 18 | install_egg_info = setuptools.command.install_egg_info:install_egg_info 19 | install_lib = setuptools.command.install_lib:install_lib 20 | install_scripts = setuptools.command.install_scripts:install_scripts 21 | rotate = setuptools.command.rotate:rotate 22 | saveopts = setuptools.command.saveopts:saveopts 23 | sdist = setuptools.command.sdist:sdist 24 | setopt = setuptools.command.setopt:setopt 25 | test = setuptools.command.test:test 26 | upload_docs = setuptools.command.upload_docs:upload_docs 27 | 28 | [distutils.setup_keywords] 29 | convert_2to3_doctests = setuptools.dist:assert_string_list 30 | dependency_links = setuptools.dist:assert_string_list 31 | eager_resources = setuptools.dist:assert_string_list 32 | entry_points = setuptools.dist:check_entry_points 33 | exclude_package_data = setuptools.dist:check_package_data 34 | extras_require = setuptools.dist:check_extras 35 | include_package_data = setuptools.dist:assert_bool 36 | install_requires = setuptools.dist:check_requirements 37 | namespace_packages = setuptools.dist:check_nsp 38 | package_data = setuptools.dist:check_package_data 39 | packages = setuptools.dist:check_packages 40 | python_requires = setuptools.dist:check_specifier 41 | setup_requires = setuptools.dist:check_requirements 42 | test_loader = setuptools.dist:check_importable 43 | test_runner = setuptools.dist:check_importable 44 | test_suite = setuptools.dist:check_test_suite 45 | tests_require = setuptools.dist:check_requirements 46 | use_2to3 = setuptools.dist:assert_bool 47 | use_2to3_exclude_fixers = setuptools.dist:assert_string_list 48 | use_2to3_fixers = setuptools.dist:assert_string_list 49 | zip_safe = setuptools.dist:assert_bool 50 | 51 | [egg_info.writers] 52 | PKG-INFO = setuptools.command.egg_info:write_pkg_info 53 | dependency_links.txt = setuptools.command.egg_info:overwrite_arg 54 | depends.txt = setuptools.command.egg_info:warn_depends_obsolete 55 | eager_resources.txt = setuptools.command.egg_info:overwrite_arg 56 | entry_points.txt = setuptools.command.egg_info:write_entries 57 | namespace_packages.txt = setuptools.command.egg_info:overwrite_arg 58 | requires.txt = setuptools.command.egg_info:write_requirements 59 | top_level.txt = setuptools.command.egg_info:write_toplevel_names 60 | 61 | [setuptools.finalize_distribution_options] 62 | 2to3_doctests = setuptools.dist:Distribution._finalize_2to3_doctests 63 | keywords = setuptools.dist:Distribution._finalize_setup_keywords 64 | parent_finalize = setuptools.dist:_Distribution.finalize_options 65 | 66 | [setuptools.installation] 67 | eggsecutable = setuptools.command.easy_install:bootstrap 68 | 69 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/EGG-INFO/top_level.txt: -------------------------------------------------------------------------------- 1 | easy_install 2 | pkg_resources 3 | setuptools 4 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/EGG-INFO/zip-safe: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/easy_install.py: -------------------------------------------------------------------------------- 1 | """Run the EasyInstall command""" 2 | 3 | if __name__ == '__main__': 4 | from setuptools.command.easy_install import main 5 | main() 6 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/_vendor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/_vendor/__init__.py -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/_vendor/packaging/__about__.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | __all__ = [ 7 | "__title__", "__summary__", "__uri__", "__version__", "__author__", 8 | "__email__", "__license__", "__copyright__", 9 | ] 10 | 11 | __title__ = "packaging" 12 | __summary__ = "Core utilities for Python packages" 13 | __uri__ = "https://github.com/pypa/packaging" 14 | 15 | __version__ = "16.8" 16 | 17 | __author__ = "Donald Stufft and individual contributors" 18 | __email__ = "donald@stufft.io" 19 | 20 | __license__ = "BSD or Apache License, Version 2.0" 21 | __copyright__ = "Copyright 2014-2016 %s" % __author__ 22 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/_vendor/packaging/__init__.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | from .__about__ import ( 7 | __author__, __copyright__, __email__, __license__, __summary__, __title__, 8 | __uri__, __version__ 9 | ) 10 | 11 | __all__ = [ 12 | "__title__", "__summary__", "__uri__", "__version__", "__author__", 13 | "__email__", "__license__", "__copyright__", 14 | ] 15 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/_vendor/packaging/_compat.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | import sys 7 | 8 | 9 | PY2 = sys.version_info[0] == 2 10 | PY3 = sys.version_info[0] == 3 11 | 12 | # flake8: noqa 13 | 14 | if PY3: 15 | string_types = str, 16 | else: 17 | string_types = basestring, 18 | 19 | 20 | def with_metaclass(meta, *bases): 21 | """ 22 | Create a base class with a metaclass. 23 | """ 24 | # This requires a bit of explanation: the basic idea is to make a dummy 25 | # metaclass for one level of class instantiation that replaces itself with 26 | # the actual metaclass. 27 | class metaclass(meta): 28 | def __new__(cls, name, this_bases, d): 29 | return meta(name, bases, d) 30 | return type.__new__(metaclass, 'temporary_class', (), {}) 31 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/_vendor/packaging/_structures.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | 7 | class Infinity(object): 8 | 9 | def __repr__(self): 10 | return "Infinity" 11 | 12 | def __hash__(self): 13 | return hash(repr(self)) 14 | 15 | def __lt__(self, other): 16 | return False 17 | 18 | def __le__(self, other): 19 | return False 20 | 21 | def __eq__(self, other): 22 | return isinstance(other, self.__class__) 23 | 24 | def __ne__(self, other): 25 | return not isinstance(other, self.__class__) 26 | 27 | def __gt__(self, other): 28 | return True 29 | 30 | def __ge__(self, other): 31 | return True 32 | 33 | def __neg__(self): 34 | return NegativeInfinity 35 | 36 | Infinity = Infinity() 37 | 38 | 39 | class NegativeInfinity(object): 40 | 41 | def __repr__(self): 42 | return "-Infinity" 43 | 44 | def __hash__(self): 45 | return hash(repr(self)) 46 | 47 | def __lt__(self, other): 48 | return True 49 | 50 | def __le__(self, other): 51 | return True 52 | 53 | def __eq__(self, other): 54 | return isinstance(other, self.__class__) 55 | 56 | def __ne__(self, other): 57 | return not isinstance(other, self.__class__) 58 | 59 | def __gt__(self, other): 60 | return False 61 | 62 | def __ge__(self, other): 63 | return False 64 | 65 | def __neg__(self): 66 | return Infinity 67 | 68 | NegativeInfinity = NegativeInfinity() 69 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/_vendor/packaging/requirements.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | import string 7 | import re 8 | 9 | from pkg_resources.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException 10 | from pkg_resources.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine 11 | from pkg_resources.extern.pyparsing import Literal as L # noqa 12 | from pkg_resources.extern.six.moves.urllib import parse as urlparse 13 | 14 | from .markers import MARKER_EXPR, Marker 15 | from .specifiers import LegacySpecifier, Specifier, SpecifierSet 16 | 17 | 18 | class InvalidRequirement(ValueError): 19 | """ 20 | An invalid requirement was found, users should refer to PEP 508. 21 | """ 22 | 23 | 24 | ALPHANUM = Word(string.ascii_letters + string.digits) 25 | 26 | LBRACKET = L("[").suppress() 27 | RBRACKET = L("]").suppress() 28 | LPAREN = L("(").suppress() 29 | RPAREN = L(")").suppress() 30 | COMMA = L(",").suppress() 31 | SEMICOLON = L(";").suppress() 32 | AT = L("@").suppress() 33 | 34 | PUNCTUATION = Word("-_.") 35 | IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) 36 | IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) 37 | 38 | NAME = IDENTIFIER("name") 39 | EXTRA = IDENTIFIER 40 | 41 | URI = Regex(r'[^ ]+')("url") 42 | URL = (AT + URI) 43 | 44 | EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) 45 | EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") 46 | 47 | VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) 48 | VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) 49 | 50 | VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY 51 | VERSION_MANY = Combine(VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), 52 | joinString=",", adjacent=False)("_raw_spec") 53 | _VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) 54 | _VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or '') 55 | 56 | VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") 57 | VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) 58 | 59 | MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") 60 | MARKER_EXPR.setParseAction( 61 | lambda s, l, t: Marker(s[t._original_start:t._original_end]) 62 | ) 63 | MARKER_SEPERATOR = SEMICOLON 64 | MARKER = MARKER_SEPERATOR + MARKER_EXPR 65 | 66 | VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) 67 | URL_AND_MARKER = URL + Optional(MARKER) 68 | 69 | NAMED_REQUIREMENT = \ 70 | NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) 71 | 72 | REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd 73 | 74 | 75 | class Requirement(object): 76 | """Parse a requirement. 77 | 78 | Parse a given requirement string into its parts, such as name, specifier, 79 | URL, and extras. Raises InvalidRequirement on a badly-formed requirement 80 | string. 81 | """ 82 | 83 | # TODO: Can we test whether something is contained within a requirement? 84 | # If so how do we do that? Do we need to test against the _name_ of 85 | # the thing as well as the version? What about the markers? 86 | # TODO: Can we normalize the name and extra name? 87 | 88 | def __init__(self, requirement_string): 89 | try: 90 | req = REQUIREMENT.parseString(requirement_string) 91 | except ParseException as e: 92 | raise InvalidRequirement( 93 | "Invalid requirement, parse error at \"{0!r}\"".format( 94 | requirement_string[e.loc:e.loc + 8])) 95 | 96 | self.name = req.name 97 | if req.url: 98 | parsed_url = urlparse.urlparse(req.url) 99 | if not (parsed_url.scheme and parsed_url.netloc) or ( 100 | not parsed_url.scheme and not parsed_url.netloc): 101 | raise InvalidRequirement("Invalid URL given") 102 | self.url = req.url 103 | else: 104 | self.url = None 105 | self.extras = set(req.extras.asList() if req.extras else []) 106 | self.specifier = SpecifierSet(req.specifier) 107 | self.marker = req.marker if req.marker else None 108 | 109 | def __str__(self): 110 | parts = [self.name] 111 | 112 | if self.extras: 113 | parts.append("[{0}]".format(",".join(sorted(self.extras)))) 114 | 115 | if self.specifier: 116 | parts.append(str(self.specifier)) 117 | 118 | if self.url: 119 | parts.append("@ {0}".format(self.url)) 120 | 121 | if self.marker: 122 | parts.append("; {0}".format(self.marker)) 123 | 124 | return "".join(parts) 125 | 126 | def __repr__(self): 127 | return "".format(str(self)) 128 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/_vendor/packaging/utils.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | import re 7 | 8 | 9 | _canonicalize_regex = re.compile(r"[-_.]+") 10 | 11 | 12 | def canonicalize_name(name): 13 | # This is taken from PEP 503. 14 | return _canonicalize_regex.sub("-", name).lower() 15 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/extern/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | class VendorImporter: 5 | """ 6 | A PEP 302 meta path importer for finding optionally-vendored 7 | or otherwise naturally-installed packages from root_name. 8 | """ 9 | 10 | def __init__(self, root_name, vendored_names=(), vendor_pkg=None): 11 | self.root_name = root_name 12 | self.vendored_names = set(vendored_names) 13 | self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') 14 | 15 | @property 16 | def search_path(self): 17 | """ 18 | Search first the vendor package then as a natural package. 19 | """ 20 | yield self.vendor_pkg + '.' 21 | yield '' 22 | 23 | def find_module(self, fullname, path=None): 24 | """ 25 | Return self when fullname starts with root_name and the 26 | target module is one vendored through this importer. 27 | """ 28 | root, base, target = fullname.partition(self.root_name + '.') 29 | if root: 30 | return 31 | if not any(map(target.startswith, self.vendored_names)): 32 | return 33 | return self 34 | 35 | def load_module(self, fullname): 36 | """ 37 | Iterate over the search path to locate and load fullname. 38 | """ 39 | root, base, target = fullname.partition(self.root_name + '.') 40 | for prefix in self.search_path: 41 | try: 42 | extant = prefix + target 43 | __import__(extant) 44 | mod = sys.modules[extant] 45 | sys.modules[fullname] = mod 46 | return mod 47 | except ImportError: 48 | pass 49 | else: 50 | raise ImportError( 51 | "The '{target}' package is required; " 52 | "normally this is bundled with this package so if you get " 53 | "this warning, consult the packager of your " 54 | "distribution.".format(**locals()) 55 | ) 56 | 57 | def install(self): 58 | """ 59 | Install this importer into sys.meta_path if not already present. 60 | """ 61 | if self not in sys.meta_path: 62 | sys.meta_path.append(self) 63 | 64 | 65 | names = 'packaging', 'pyparsing', 'six', 'appdirs' 66 | VendorImporter(__name__, names).install() 67 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/py2_warn.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import warnings 3 | import textwrap 4 | 5 | 6 | msg = textwrap.dedent(""" 7 | You are running Setuptools on Python 2, which is no longer 8 | supported and 9 | >>> SETUPTOOLS WILL STOP WORKING <<< 10 | in a subsequent release (no sooner than 2020-04-20). 11 | Please ensure you are installing 12 | Setuptools using pip 9.x or later or pin to `setuptools<45` 13 | in your environment. 14 | If you have done those things and are still encountering 15 | this message, please comment in 16 | https://github.com/pypa/setuptools/issues/1458 17 | about the steps that led to this unsupported combination. 18 | """) 19 | 20 | pre = "Setuptools will stop working on Python 2\n" 21 | 22 | sys.version_info < (3,) and warnings.warn(pre + "*" * 60 + msg + "*" * 60) 23 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/pkg_resources/py31compat.py: -------------------------------------------------------------------------------- 1 | import os 2 | import errno 3 | import sys 4 | 5 | from .extern import six 6 | 7 | 8 | def _makedirs_31(path, exist_ok=False): 9 | try: 10 | os.makedirs(path) 11 | except OSError as exc: 12 | if not exist_ok or exc.errno != errno.EEXIST: 13 | raise 14 | 15 | 16 | # rely on compatibility behavior until mode considerations 17 | # and exists_ok considerations are disentangled. 18 | # See https://github.com/pypa/setuptools/pull/1083#issuecomment-315168663 19 | needs_makedirs = ( 20 | six.PY2 or 21 | (3, 4) <= sys.version_info < (3, 4, 1) 22 | ) 23 | makedirs = _makedirs_31 if needs_makedirs else os.makedirs 24 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/__init__.py: -------------------------------------------------------------------------------- 1 | """Extensions to the 'distutils' for large or complex distributions""" 2 | 3 | import os 4 | import functools 5 | import distutils.core 6 | import distutils.filelist 7 | import re 8 | from distutils.errors import DistutilsOptionError 9 | from distutils.util import convert_path 10 | from fnmatch import fnmatchcase 11 | 12 | from ._deprecation_warning import SetuptoolsDeprecationWarning 13 | 14 | from setuptools.extern.six import PY3, string_types 15 | from setuptools.extern.six.moves import filter, map 16 | 17 | import setuptools.version 18 | from setuptools.extension import Extension 19 | from setuptools.dist import Distribution 20 | from setuptools.depends import Require 21 | from . import monkey 22 | 23 | __metaclass__ = type 24 | 25 | 26 | __all__ = [ 27 | 'setup', 'Distribution', 'Command', 'Extension', 'Require', 28 | 'SetuptoolsDeprecationWarning', 29 | 'find_packages' 30 | ] 31 | 32 | if PY3: 33 | __all__.append('find_namespace_packages') 34 | 35 | __version__ = setuptools.version.__version__ 36 | 37 | bootstrap_install_from = None 38 | 39 | # If we run 2to3 on .py files, should we also convert docstrings? 40 | # Default: yes; assume that we can detect doctests reliably 41 | run_2to3_on_doctests = True 42 | # Standard package names for fixer packages 43 | lib2to3_fixer_packages = ['lib2to3.fixes'] 44 | 45 | 46 | class PackageFinder: 47 | """ 48 | Generate a list of all Python packages found within a directory 49 | """ 50 | 51 | @classmethod 52 | def find(cls, where='.', exclude=(), include=('*',)): 53 | """Return a list all Python packages found within directory 'where' 54 | 55 | 'where' is the root directory which will be searched for packages. It 56 | should be supplied as a "cross-platform" (i.e. URL-style) path; it will 57 | be converted to the appropriate local path syntax. 58 | 59 | 'exclude' is a sequence of package names to exclude; '*' can be used 60 | as a wildcard in the names, such that 'foo.*' will exclude all 61 | subpackages of 'foo' (but not 'foo' itself). 62 | 63 | 'include' is a sequence of package names to include. If it's 64 | specified, only the named packages will be included. If it's not 65 | specified, all found packages will be included. 'include' can contain 66 | shell style wildcard patterns just like 'exclude'. 67 | """ 68 | 69 | return list(cls._find_packages_iter( 70 | convert_path(where), 71 | cls._build_filter('ez_setup', '*__pycache__', *exclude), 72 | cls._build_filter(*include))) 73 | 74 | @classmethod 75 | def _find_packages_iter(cls, where, exclude, include): 76 | """ 77 | All the packages found in 'where' that pass the 'include' filter, but 78 | not the 'exclude' filter. 79 | """ 80 | for root, dirs, files in os.walk(where, followlinks=True): 81 | # Copy dirs to iterate over it, then empty dirs. 82 | all_dirs = dirs[:] 83 | dirs[:] = [] 84 | 85 | for dir in all_dirs: 86 | full_path = os.path.join(root, dir) 87 | rel_path = os.path.relpath(full_path, where) 88 | package = rel_path.replace(os.path.sep, '.') 89 | 90 | # Skip directory trees that are not valid packages 91 | if ('.' in dir or not cls._looks_like_package(full_path)): 92 | continue 93 | 94 | # Should this package be included? 95 | if include(package) and not exclude(package): 96 | yield package 97 | 98 | # Keep searching subdirectories, as there may be more packages 99 | # down there, even if the parent was excluded. 100 | dirs.append(dir) 101 | 102 | @staticmethod 103 | def _looks_like_package(path): 104 | """Does a directory look like a package?""" 105 | return os.path.isfile(os.path.join(path, '__init__.py')) 106 | 107 | @staticmethod 108 | def _build_filter(*patterns): 109 | """ 110 | Given a list of patterns, return a callable that will be true only if 111 | the input matches at least one of the patterns. 112 | """ 113 | return lambda name: any(fnmatchcase(name, pat=pat) for pat in patterns) 114 | 115 | 116 | class PEP420PackageFinder(PackageFinder): 117 | @staticmethod 118 | def _looks_like_package(path): 119 | return True 120 | 121 | 122 | find_packages = PackageFinder.find 123 | 124 | if PY3: 125 | find_namespace_packages = PEP420PackageFinder.find 126 | 127 | 128 | def _install_setup_requires(attrs): 129 | # Note: do not use `setuptools.Distribution` directly, as 130 | # our PEP 517 backend patch `distutils.core.Distribution`. 131 | dist = distutils.core.Distribution(dict( 132 | (k, v) for k, v in attrs.items() 133 | if k in ('dependency_links', 'setup_requires') 134 | )) 135 | # Honor setup.cfg's options. 136 | dist.parse_config_files(ignore_option_errors=True) 137 | if dist.setup_requires: 138 | dist.fetch_build_eggs(dist.setup_requires) 139 | 140 | 141 | def setup(**attrs): 142 | # Make sure we have any requirements needed to interpret 'attrs'. 143 | _install_setup_requires(attrs) 144 | return distutils.core.setup(**attrs) 145 | 146 | 147 | setup.__doc__ = distutils.core.setup.__doc__ 148 | 149 | 150 | _Command = monkey.get_unpatched(distutils.core.Command) 151 | 152 | 153 | class Command(_Command): 154 | __doc__ = _Command.__doc__ 155 | 156 | command_consumes_arguments = False 157 | 158 | def __init__(self, dist, **kw): 159 | """ 160 | Construct the command for dist, updating 161 | vars(self) with any keyword parameters. 162 | """ 163 | _Command.__init__(self, dist) 164 | vars(self).update(kw) 165 | 166 | def _ensure_stringlike(self, option, what, default=None): 167 | val = getattr(self, option) 168 | if val is None: 169 | setattr(self, option, default) 170 | return default 171 | elif not isinstance(val, string_types): 172 | raise DistutilsOptionError("'%s' must be a %s (got `%s`)" 173 | % (option, what, val)) 174 | return val 175 | 176 | def ensure_string_list(self, option): 177 | r"""Ensure that 'option' is a list of strings. If 'option' is 178 | currently a string, we split it either on /,\s*/ or /\s+/, so 179 | "foo bar baz", "foo,bar,baz", and "foo, bar baz" all become 180 | ["foo", "bar", "baz"]. 181 | """ 182 | val = getattr(self, option) 183 | if val is None: 184 | return 185 | elif isinstance(val, string_types): 186 | setattr(self, option, re.split(r',\s*|\s+', val)) 187 | else: 188 | if isinstance(val, list): 189 | ok = all(isinstance(v, string_types) for v in val) 190 | else: 191 | ok = False 192 | if not ok: 193 | raise DistutilsOptionError( 194 | "'%s' must be a list of strings (got %r)" 195 | % (option, val)) 196 | 197 | def reinitialize_command(self, command, reinit_subcommands=0, **kw): 198 | cmd = _Command.reinitialize_command(self, command, reinit_subcommands) 199 | vars(cmd).update(kw) 200 | return cmd 201 | 202 | 203 | def _find_all_simple(path): 204 | """ 205 | Find all files under 'path' 206 | """ 207 | results = ( 208 | os.path.join(base, file) 209 | for base, dirs, files in os.walk(path, followlinks=True) 210 | for file in files 211 | ) 212 | return filter(os.path.isfile, results) 213 | 214 | 215 | def findall(dir=os.curdir): 216 | """ 217 | Find all files under 'dir' and return the list of full filenames. 218 | Unless dir is '.', return full filenames with dir prepended. 219 | """ 220 | files = _find_all_simple(dir) 221 | if dir == os.curdir: 222 | make_rel = functools.partial(os.path.relpath, start=dir) 223 | files = map(make_rel, files) 224 | return list(files) 225 | 226 | 227 | # Apply monkey patches 228 | monkey.patch_all() 229 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_deprecation_warning.py: -------------------------------------------------------------------------------- 1 | class SetuptoolsDeprecationWarning(Warning): 2 | """ 3 | Base class for warning deprecations in ``setuptools`` 4 | 5 | This class is not derived from ``DeprecationWarning``, and as such is 6 | visible by default. 7 | """ 8 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_imp.py: -------------------------------------------------------------------------------- 1 | """ 2 | Re-implementation of find_module and get_frozen_object 3 | from the deprecated imp module. 4 | """ 5 | 6 | import os 7 | import importlib.util 8 | import importlib.machinery 9 | 10 | from .py34compat import module_from_spec 11 | 12 | 13 | PY_SOURCE = 1 14 | PY_COMPILED = 2 15 | C_EXTENSION = 3 16 | C_BUILTIN = 6 17 | PY_FROZEN = 7 18 | 19 | 20 | def find_spec(module, paths): 21 | finder = ( 22 | importlib.machinery.PathFinder().find_spec 23 | if isinstance(paths, list) else 24 | importlib.util.find_spec 25 | ) 26 | return finder(module, paths) 27 | 28 | 29 | def find_module(module, paths=None): 30 | """Just like 'imp.find_module()', but with package support""" 31 | spec = find_spec(module, paths) 32 | if spec is None: 33 | raise ImportError("Can't find %s" % module) 34 | if not spec.has_location and hasattr(spec, 'submodule_search_locations'): 35 | spec = importlib.util.spec_from_loader('__init__.py', spec.loader) 36 | 37 | kind = -1 38 | file = None 39 | static = isinstance(spec.loader, type) 40 | if spec.origin == 'frozen' or static and issubclass( 41 | spec.loader, importlib.machinery.FrozenImporter): 42 | kind = PY_FROZEN 43 | path = None # imp compabilty 44 | suffix = mode = '' # imp compability 45 | elif spec.origin == 'built-in' or static and issubclass( 46 | spec.loader, importlib.machinery.BuiltinImporter): 47 | kind = C_BUILTIN 48 | path = None # imp compabilty 49 | suffix = mode = '' # imp compability 50 | elif spec.has_location: 51 | path = spec.origin 52 | suffix = os.path.splitext(path)[1] 53 | mode = 'r' if suffix in importlib.machinery.SOURCE_SUFFIXES else 'rb' 54 | 55 | if suffix in importlib.machinery.SOURCE_SUFFIXES: 56 | kind = PY_SOURCE 57 | elif suffix in importlib.machinery.BYTECODE_SUFFIXES: 58 | kind = PY_COMPILED 59 | elif suffix in importlib.machinery.EXTENSION_SUFFIXES: 60 | kind = C_EXTENSION 61 | 62 | if kind in {PY_SOURCE, PY_COMPILED}: 63 | file = open(path, mode) 64 | else: 65 | path = None 66 | suffix = mode = '' 67 | 68 | return file, path, (suffix, mode, kind) 69 | 70 | 71 | def get_frozen_object(module, paths=None): 72 | spec = find_spec(module, paths) 73 | if not spec: 74 | raise ImportError("Can't find %s" % module) 75 | return spec.loader.get_code(module) 76 | 77 | 78 | def get_module(module, paths, info): 79 | spec = find_spec(module, paths) 80 | if not spec: 81 | raise ImportError("Can't find %s" % module) 82 | return module_from_spec(spec) 83 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_vendor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_vendor/__init__.py -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_vendor/packaging/__about__.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | __all__ = [ 7 | "__title__", 8 | "__summary__", 9 | "__uri__", 10 | "__version__", 11 | "__author__", 12 | "__email__", 13 | "__license__", 14 | "__copyright__", 15 | ] 16 | 17 | __title__ = "packaging" 18 | __summary__ = "Core utilities for Python packages" 19 | __uri__ = "https://github.com/pypa/packaging" 20 | 21 | __version__ = "19.2" 22 | 23 | __author__ = "Donald Stufft and individual contributors" 24 | __email__ = "donald@stufft.io" 25 | 26 | __license__ = "BSD or Apache License, Version 2.0" 27 | __copyright__ = "Copyright 2014-2019 %s" % __author__ 28 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_vendor/packaging/__init__.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | from .__about__ import ( 7 | __author__, 8 | __copyright__, 9 | __email__, 10 | __license__, 11 | __summary__, 12 | __title__, 13 | __uri__, 14 | __version__, 15 | ) 16 | 17 | __all__ = [ 18 | "__title__", 19 | "__summary__", 20 | "__uri__", 21 | "__version__", 22 | "__author__", 23 | "__email__", 24 | "__license__", 25 | "__copyright__", 26 | ] 27 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_vendor/packaging/_compat.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | import sys 7 | 8 | 9 | PY2 = sys.version_info[0] == 2 10 | PY3 = sys.version_info[0] == 3 11 | 12 | # flake8: noqa 13 | 14 | if PY3: 15 | string_types = (str,) 16 | else: 17 | string_types = (basestring,) 18 | 19 | 20 | def with_metaclass(meta, *bases): 21 | """ 22 | Create a base class with a metaclass. 23 | """ 24 | # This requires a bit of explanation: the basic idea is to make a dummy 25 | # metaclass for one level of class instantiation that replaces itself with 26 | # the actual metaclass. 27 | class metaclass(meta): 28 | def __new__(cls, name, this_bases, d): 29 | return meta(name, bases, d) 30 | 31 | return type.__new__(metaclass, "temporary_class", (), {}) 32 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_vendor/packaging/_structures.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | 7 | class Infinity(object): 8 | def __repr__(self): 9 | return "Infinity" 10 | 11 | def __hash__(self): 12 | return hash(repr(self)) 13 | 14 | def __lt__(self, other): 15 | return False 16 | 17 | def __le__(self, other): 18 | return False 19 | 20 | def __eq__(self, other): 21 | return isinstance(other, self.__class__) 22 | 23 | def __ne__(self, other): 24 | return not isinstance(other, self.__class__) 25 | 26 | def __gt__(self, other): 27 | return True 28 | 29 | def __ge__(self, other): 30 | return True 31 | 32 | def __neg__(self): 33 | return NegativeInfinity 34 | 35 | 36 | Infinity = Infinity() 37 | 38 | 39 | class NegativeInfinity(object): 40 | def __repr__(self): 41 | return "-Infinity" 42 | 43 | def __hash__(self): 44 | return hash(repr(self)) 45 | 46 | def __lt__(self, other): 47 | return True 48 | 49 | def __le__(self, other): 50 | return True 51 | 52 | def __eq__(self, other): 53 | return isinstance(other, self.__class__) 54 | 55 | def __ne__(self, other): 56 | return not isinstance(other, self.__class__) 57 | 58 | def __gt__(self, other): 59 | return False 60 | 61 | def __ge__(self, other): 62 | return False 63 | 64 | def __neg__(self): 65 | return Infinity 66 | 67 | 68 | NegativeInfinity = NegativeInfinity() 69 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_vendor/packaging/requirements.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | import string 7 | import re 8 | 9 | from setuptools.extern.pyparsing import stringStart, stringEnd, originalTextFor, ParseException 10 | from setuptools.extern.pyparsing import ZeroOrMore, Word, Optional, Regex, Combine 11 | from setuptools.extern.pyparsing import Literal as L # noqa 12 | from setuptools.extern.six.moves.urllib import parse as urlparse 13 | 14 | from .markers import MARKER_EXPR, Marker 15 | from .specifiers import LegacySpecifier, Specifier, SpecifierSet 16 | 17 | 18 | class InvalidRequirement(ValueError): 19 | """ 20 | An invalid requirement was found, users should refer to PEP 508. 21 | """ 22 | 23 | 24 | ALPHANUM = Word(string.ascii_letters + string.digits) 25 | 26 | LBRACKET = L("[").suppress() 27 | RBRACKET = L("]").suppress() 28 | LPAREN = L("(").suppress() 29 | RPAREN = L(")").suppress() 30 | COMMA = L(",").suppress() 31 | SEMICOLON = L(";").suppress() 32 | AT = L("@").suppress() 33 | 34 | PUNCTUATION = Word("-_.") 35 | IDENTIFIER_END = ALPHANUM | (ZeroOrMore(PUNCTUATION) + ALPHANUM) 36 | IDENTIFIER = Combine(ALPHANUM + ZeroOrMore(IDENTIFIER_END)) 37 | 38 | NAME = IDENTIFIER("name") 39 | EXTRA = IDENTIFIER 40 | 41 | URI = Regex(r"[^ ]+")("url") 42 | URL = AT + URI 43 | 44 | EXTRAS_LIST = EXTRA + ZeroOrMore(COMMA + EXTRA) 45 | EXTRAS = (LBRACKET + Optional(EXTRAS_LIST) + RBRACKET)("extras") 46 | 47 | VERSION_PEP440 = Regex(Specifier._regex_str, re.VERBOSE | re.IGNORECASE) 48 | VERSION_LEGACY = Regex(LegacySpecifier._regex_str, re.VERBOSE | re.IGNORECASE) 49 | 50 | VERSION_ONE = VERSION_PEP440 ^ VERSION_LEGACY 51 | VERSION_MANY = Combine( 52 | VERSION_ONE + ZeroOrMore(COMMA + VERSION_ONE), joinString=",", adjacent=False 53 | )("_raw_spec") 54 | _VERSION_SPEC = Optional(((LPAREN + VERSION_MANY + RPAREN) | VERSION_MANY)) 55 | _VERSION_SPEC.setParseAction(lambda s, l, t: t._raw_spec or "") 56 | 57 | VERSION_SPEC = originalTextFor(_VERSION_SPEC)("specifier") 58 | VERSION_SPEC.setParseAction(lambda s, l, t: t[1]) 59 | 60 | MARKER_EXPR = originalTextFor(MARKER_EXPR())("marker") 61 | MARKER_EXPR.setParseAction( 62 | lambda s, l, t: Marker(s[t._original_start : t._original_end]) 63 | ) 64 | MARKER_SEPARATOR = SEMICOLON 65 | MARKER = MARKER_SEPARATOR + MARKER_EXPR 66 | 67 | VERSION_AND_MARKER = VERSION_SPEC + Optional(MARKER) 68 | URL_AND_MARKER = URL + Optional(MARKER) 69 | 70 | NAMED_REQUIREMENT = NAME + Optional(EXTRAS) + (URL_AND_MARKER | VERSION_AND_MARKER) 71 | 72 | REQUIREMENT = stringStart + NAMED_REQUIREMENT + stringEnd 73 | # setuptools.extern.pyparsing isn't thread safe during initialization, so we do it eagerly, see 74 | # issue #104 75 | REQUIREMENT.parseString("x[]") 76 | 77 | 78 | class Requirement(object): 79 | """Parse a requirement. 80 | 81 | Parse a given requirement string into its parts, such as name, specifier, 82 | URL, and extras. Raises InvalidRequirement on a badly-formed requirement 83 | string. 84 | """ 85 | 86 | # TODO: Can we test whether something is contained within a requirement? 87 | # If so how do we do that? Do we need to test against the _name_ of 88 | # the thing as well as the version? What about the markers? 89 | # TODO: Can we normalize the name and extra name? 90 | 91 | def __init__(self, requirement_string): 92 | try: 93 | req = REQUIREMENT.parseString(requirement_string) 94 | except ParseException as e: 95 | raise InvalidRequirement( 96 | 'Parse error at "{0!r}": {1}'.format( 97 | requirement_string[e.loc : e.loc + 8], e.msg 98 | ) 99 | ) 100 | 101 | self.name = req.name 102 | if req.url: 103 | parsed_url = urlparse.urlparse(req.url) 104 | if parsed_url.scheme == "file": 105 | if urlparse.urlunparse(parsed_url) != req.url: 106 | raise InvalidRequirement("Invalid URL given") 107 | elif not (parsed_url.scheme and parsed_url.netloc) or ( 108 | not parsed_url.scheme and not parsed_url.netloc 109 | ): 110 | raise InvalidRequirement("Invalid URL: {0}".format(req.url)) 111 | self.url = req.url 112 | else: 113 | self.url = None 114 | self.extras = set(req.extras.asList() if req.extras else []) 115 | self.specifier = SpecifierSet(req.specifier) 116 | self.marker = req.marker if req.marker else None 117 | 118 | def __str__(self): 119 | parts = [self.name] 120 | 121 | if self.extras: 122 | parts.append("[{0}]".format(",".join(sorted(self.extras)))) 123 | 124 | if self.specifier: 125 | parts.append(str(self.specifier)) 126 | 127 | if self.url: 128 | parts.append("@ {0}".format(self.url)) 129 | if self.marker: 130 | parts.append(" ") 131 | 132 | if self.marker: 133 | parts.append("; {0}".format(self.marker)) 134 | 135 | return "".join(parts) 136 | 137 | def __repr__(self): 138 | return "".format(str(self)) 139 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/_vendor/packaging/utils.py: -------------------------------------------------------------------------------- 1 | # This file is dual licensed under the terms of the Apache License, Version 2 | # 2.0, and the BSD License. See the LICENSE file in the root of this repository 3 | # for complete details. 4 | from __future__ import absolute_import, division, print_function 5 | 6 | import re 7 | 8 | from .version import InvalidVersion, Version 9 | 10 | 11 | _canonicalize_regex = re.compile(r"[-_.]+") 12 | 13 | 14 | def canonicalize_name(name): 15 | # This is taken from PEP 503. 16 | return _canonicalize_regex.sub("-", name).lower() 17 | 18 | 19 | def canonicalize_version(version): 20 | """ 21 | This is very similar to Version.__str__, but has one subtle differences 22 | with the way it handles the release segment. 23 | """ 24 | 25 | try: 26 | version = Version(version) 27 | except InvalidVersion: 28 | # Legacy versions cannot be normalized 29 | return version 30 | 31 | parts = [] 32 | 33 | # Epoch 34 | if version.epoch != 0: 35 | parts.append("{0}!".format(version.epoch)) 36 | 37 | # Release segment 38 | # NB: This strips trailing '.0's to normalize 39 | parts.append(re.sub(r"(\.0)+$", "", ".".join(str(x) for x in version.release))) 40 | 41 | # Pre-release 42 | if version.pre is not None: 43 | parts.append("".join(str(x) for x in version.pre)) 44 | 45 | # Post-release 46 | if version.post is not None: 47 | parts.append(".post{0}".format(version.post)) 48 | 49 | # Development release 50 | if version.dev is not None: 51 | parts.append(".dev{0}".format(version.dev)) 52 | 53 | # Local version segment 54 | if version.local is not None: 55 | parts.append("+{0}".format(version.local)) 56 | 57 | return "".join(parts) 58 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/archive_util.py: -------------------------------------------------------------------------------- 1 | """Utilities for extracting common archive formats""" 2 | 3 | import zipfile 4 | import tarfile 5 | import os 6 | import shutil 7 | import posixpath 8 | import contextlib 9 | from distutils.errors import DistutilsError 10 | 11 | from pkg_resources import ensure_directory 12 | 13 | __all__ = [ 14 | "unpack_archive", "unpack_zipfile", "unpack_tarfile", "default_filter", 15 | "UnrecognizedFormat", "extraction_drivers", "unpack_directory", 16 | ] 17 | 18 | 19 | class UnrecognizedFormat(DistutilsError): 20 | """Couldn't recognize the archive type""" 21 | 22 | 23 | def default_filter(src, dst): 24 | """The default progress/filter callback; returns True for all files""" 25 | return dst 26 | 27 | 28 | def unpack_archive( 29 | filename, extract_dir, progress_filter=default_filter, 30 | drivers=None): 31 | """Unpack `filename` to `extract_dir`, or raise ``UnrecognizedFormat`` 32 | 33 | `progress_filter` is a function taking two arguments: a source path 34 | internal to the archive ('/'-separated), and a filesystem path where it 35 | will be extracted. The callback must return the desired extract path 36 | (which may be the same as the one passed in), or else ``None`` to skip 37 | that file or directory. The callback can thus be used to report on the 38 | progress of the extraction, as well as to filter the items extracted or 39 | alter their extraction paths. 40 | 41 | `drivers`, if supplied, must be a non-empty sequence of functions with the 42 | same signature as this function (minus the `drivers` argument), that raise 43 | ``UnrecognizedFormat`` if they do not support extracting the designated 44 | archive type. The `drivers` are tried in sequence until one is found that 45 | does not raise an error, or until all are exhausted (in which case 46 | ``UnrecognizedFormat`` is raised). If you do not supply a sequence of 47 | drivers, the module's ``extraction_drivers`` constant will be used, which 48 | means that ``unpack_zipfile`` and ``unpack_tarfile`` will be tried, in that 49 | order. 50 | """ 51 | for driver in drivers or extraction_drivers: 52 | try: 53 | driver(filename, extract_dir, progress_filter) 54 | except UnrecognizedFormat: 55 | continue 56 | else: 57 | return 58 | else: 59 | raise UnrecognizedFormat( 60 | "Not a recognized archive type: %s" % filename 61 | ) 62 | 63 | 64 | def unpack_directory(filename, extract_dir, progress_filter=default_filter): 65 | """"Unpack" a directory, using the same interface as for archives 66 | 67 | Raises ``UnrecognizedFormat`` if `filename` is not a directory 68 | """ 69 | if not os.path.isdir(filename): 70 | raise UnrecognizedFormat("%s is not a directory" % filename) 71 | 72 | paths = { 73 | filename: ('', extract_dir), 74 | } 75 | for base, dirs, files in os.walk(filename): 76 | src, dst = paths[base] 77 | for d in dirs: 78 | paths[os.path.join(base, d)] = src + d + '/', os.path.join(dst, d) 79 | for f in files: 80 | target = os.path.join(dst, f) 81 | target = progress_filter(src + f, target) 82 | if not target: 83 | # skip non-files 84 | continue 85 | ensure_directory(target) 86 | f = os.path.join(base, f) 87 | shutil.copyfile(f, target) 88 | shutil.copystat(f, target) 89 | 90 | 91 | def unpack_zipfile(filename, extract_dir, progress_filter=default_filter): 92 | """Unpack zip `filename` to `extract_dir` 93 | 94 | Raises ``UnrecognizedFormat`` if `filename` is not a zipfile (as determined 95 | by ``zipfile.is_zipfile()``). See ``unpack_archive()`` for an explanation 96 | of the `progress_filter` argument. 97 | """ 98 | 99 | if not zipfile.is_zipfile(filename): 100 | raise UnrecognizedFormat("%s is not a zip file" % (filename,)) 101 | 102 | with zipfile.ZipFile(filename) as z: 103 | for info in z.infolist(): 104 | name = info.filename 105 | 106 | # don't extract absolute paths or ones with .. in them 107 | if name.startswith('/') or '..' in name.split('/'): 108 | continue 109 | 110 | target = os.path.join(extract_dir, *name.split('/')) 111 | target = progress_filter(name, target) 112 | if not target: 113 | continue 114 | if name.endswith('/'): 115 | # directory 116 | ensure_directory(target) 117 | else: 118 | # file 119 | ensure_directory(target) 120 | data = z.read(info.filename) 121 | with open(target, 'wb') as f: 122 | f.write(data) 123 | unix_attributes = info.external_attr >> 16 124 | if unix_attributes: 125 | os.chmod(target, unix_attributes) 126 | 127 | 128 | def unpack_tarfile(filename, extract_dir, progress_filter=default_filter): 129 | """Unpack tar/tar.gz/tar.bz2 `filename` to `extract_dir` 130 | 131 | Raises ``UnrecognizedFormat`` if `filename` is not a tarfile (as determined 132 | by ``tarfile.open()``). See ``unpack_archive()`` for an explanation 133 | of the `progress_filter` argument. 134 | """ 135 | try: 136 | tarobj = tarfile.open(filename) 137 | except tarfile.TarError: 138 | raise UnrecognizedFormat( 139 | "%s is not a compressed or uncompressed tar file" % (filename,) 140 | ) 141 | with contextlib.closing(tarobj): 142 | # don't do any chowning! 143 | tarobj.chown = lambda *args: None 144 | for member in tarobj: 145 | name = member.name 146 | # don't extract absolute paths or ones with .. in them 147 | if not name.startswith('/') and '..' not in name.split('/'): 148 | prelim_dst = os.path.join(extract_dir, *name.split('/')) 149 | 150 | # resolve any links and to extract the link targets as normal 151 | # files 152 | while member is not None and ( 153 | member.islnk() or member.issym()): 154 | linkpath = member.linkname 155 | if member.issym(): 156 | base = posixpath.dirname(member.name) 157 | linkpath = posixpath.join(base, linkpath) 158 | linkpath = posixpath.normpath(linkpath) 159 | member = tarobj._getmember(linkpath) 160 | 161 | if member is not None and (member.isfile() or member.isdir()): 162 | final_dst = progress_filter(name, prelim_dst) 163 | if final_dst: 164 | if final_dst.endswith(os.sep): 165 | final_dst = final_dst[:-1] 166 | try: 167 | # XXX Ugh 168 | tarobj._extract_member(member, final_dst) 169 | except tarfile.ExtractError: 170 | # chown/chmod/mkfifo/mknode/makedev failed 171 | pass 172 | return True 173 | 174 | 175 | extraction_drivers = unpack_directory, unpack_zipfile, unpack_tarfile 176 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/cli-32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/.eggs/setuptools-46.0.0-py3.6.egg/setuptools/cli-32.exe -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/cli-64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/.eggs/setuptools-46.0.0-py3.6.egg/setuptools/cli-64.exe -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/cli.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/.eggs/setuptools-46.0.0-py3.6.egg/setuptools/cli.exe -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/__init__.py: -------------------------------------------------------------------------------- 1 | __all__ = [ 2 | 'alias', 'bdist_egg', 'bdist_rpm', 'build_ext', 'build_py', 'develop', 3 | 'easy_install', 'egg_info', 'install', 'install_lib', 'rotate', 'saveopts', 4 | 'sdist', 'setopt', 'test', 'install_egg_info', 'install_scripts', 5 | 'bdist_wininst', 'upload_docs', 'build_clib', 'dist_info', 6 | ] 7 | 8 | from distutils.command.bdist import bdist 9 | import sys 10 | 11 | from setuptools.command import install_scripts 12 | 13 | if 'egg' not in bdist.format_commands: 14 | bdist.format_command['egg'] = ('bdist_egg', "Python .egg file") 15 | bdist.format_commands.append('egg') 16 | 17 | del bdist, sys 18 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/alias.py: -------------------------------------------------------------------------------- 1 | from distutils.errors import DistutilsOptionError 2 | 3 | from setuptools.extern.six.moves import map 4 | 5 | from setuptools.command.setopt import edit_config, option_base, config_file 6 | 7 | 8 | def shquote(arg): 9 | """Quote an argument for later parsing by shlex.split()""" 10 | for c in '"', "'", "\\", "#": 11 | if c in arg: 12 | return repr(arg) 13 | if arg.split() != [arg]: 14 | return repr(arg) 15 | return arg 16 | 17 | 18 | class alias(option_base): 19 | """Define a shortcut that invokes one or more commands""" 20 | 21 | description = "define a shortcut to invoke one or more commands" 22 | command_consumes_arguments = True 23 | 24 | user_options = [ 25 | ('remove', 'r', 'remove (unset) the alias'), 26 | ] + option_base.user_options 27 | 28 | boolean_options = option_base.boolean_options + ['remove'] 29 | 30 | def initialize_options(self): 31 | option_base.initialize_options(self) 32 | self.args = None 33 | self.remove = None 34 | 35 | def finalize_options(self): 36 | option_base.finalize_options(self) 37 | if self.remove and len(self.args) != 1: 38 | raise DistutilsOptionError( 39 | "Must specify exactly one argument (the alias name) when " 40 | "using --remove" 41 | ) 42 | 43 | def run(self): 44 | aliases = self.distribution.get_option_dict('aliases') 45 | 46 | if not self.args: 47 | print("Command Aliases") 48 | print("---------------") 49 | for alias in aliases: 50 | print("setup.py alias", format_alias(alias, aliases)) 51 | return 52 | 53 | elif len(self.args) == 1: 54 | alias, = self.args 55 | if self.remove: 56 | command = None 57 | elif alias in aliases: 58 | print("setup.py alias", format_alias(alias, aliases)) 59 | return 60 | else: 61 | print("No alias definition found for %r" % alias) 62 | return 63 | else: 64 | alias = self.args[0] 65 | command = ' '.join(map(shquote, self.args[1:])) 66 | 67 | edit_config(self.filename, {'aliases': {alias: command}}, self.dry_run) 68 | 69 | 70 | def format_alias(name, aliases): 71 | source, command = aliases[name] 72 | if source == config_file('global'): 73 | source = '--global-config ' 74 | elif source == config_file('user'): 75 | source = '--user-config ' 76 | elif source == config_file('local'): 77 | source = '' 78 | else: 79 | source = '--filename=%r' % source 80 | return source + name + ' ' + command 81 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/bdist_rpm.py: -------------------------------------------------------------------------------- 1 | import distutils.command.bdist_rpm as orig 2 | 3 | 4 | class bdist_rpm(orig.bdist_rpm): 5 | """ 6 | Override the default bdist_rpm behavior to do the following: 7 | 8 | 1. Run egg_info to ensure the name and version are properly calculated. 9 | 2. Always run 'install' using --single-version-externally-managed to 10 | disable eggs in RPM distributions. 11 | 3. Replace dash with underscore in the version numbers for better RPM 12 | compatibility. 13 | """ 14 | 15 | def run(self): 16 | # ensure distro name is up-to-date 17 | self.run_command('egg_info') 18 | 19 | orig.bdist_rpm.run(self) 20 | 21 | def _make_spec_file(self): 22 | version = self.distribution.get_version() 23 | rpmversion = version.replace('-', '_') 24 | spec = orig.bdist_rpm._make_spec_file(self) 25 | line23 = '%define version ' + version 26 | line24 = '%define version ' + rpmversion 27 | spec = [ 28 | line.replace( 29 | "Source0: %{name}-%{version}.tar", 30 | "Source0: %{name}-%{unmangled_version}.tar" 31 | ).replace( 32 | "setup.py install ", 33 | "setup.py install --single-version-externally-managed " 34 | ).replace( 35 | "%setup", 36 | "%setup -n %{name}-%{unmangled_version}" 37 | ).replace(line23, line24) 38 | for line in spec 39 | ] 40 | insert_loc = spec.index(line24) + 1 41 | unmangled_version = "%define unmangled_version " + version 42 | spec.insert(insert_loc, unmangled_version) 43 | return spec 44 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/bdist_wininst.py: -------------------------------------------------------------------------------- 1 | import distutils.command.bdist_wininst as orig 2 | 3 | 4 | class bdist_wininst(orig.bdist_wininst): 5 | def reinitialize_command(self, command, reinit_subcommands=0): 6 | """ 7 | Supplement reinitialize_command to work around 8 | http://bugs.python.org/issue20819 9 | """ 10 | cmd = self.distribution.reinitialize_command( 11 | command, reinit_subcommands) 12 | if command in ('install', 'install_lib'): 13 | cmd.install_lib = None 14 | return cmd 15 | 16 | def run(self): 17 | self._is_running = True 18 | try: 19 | orig.bdist_wininst.run(self) 20 | finally: 21 | self._is_running = False 22 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/build_clib.py: -------------------------------------------------------------------------------- 1 | import distutils.command.build_clib as orig 2 | from distutils.errors import DistutilsSetupError 3 | from distutils import log 4 | from setuptools.dep_util import newer_pairwise_group 5 | 6 | 7 | class build_clib(orig.build_clib): 8 | """ 9 | Override the default build_clib behaviour to do the following: 10 | 11 | 1. Implement a rudimentary timestamp-based dependency system 12 | so 'compile()' doesn't run every time. 13 | 2. Add more keys to the 'build_info' dictionary: 14 | * obj_deps - specify dependencies for each object compiled. 15 | this should be a dictionary mapping a key 16 | with the source filename to a list of 17 | dependencies. Use an empty string for global 18 | dependencies. 19 | * cflags - specify a list of additional flags to pass to 20 | the compiler. 21 | """ 22 | 23 | def build_libraries(self, libraries): 24 | for (lib_name, build_info) in libraries: 25 | sources = build_info.get('sources') 26 | if sources is None or not isinstance(sources, (list, tuple)): 27 | raise DistutilsSetupError( 28 | "in 'libraries' option (library '%s'), " 29 | "'sources' must be present and must be " 30 | "a list of source filenames" % lib_name) 31 | sources = list(sources) 32 | 33 | log.info("building '%s' library", lib_name) 34 | 35 | # Make sure everything is the correct type. 36 | # obj_deps should be a dictionary of keys as sources 37 | # and a list/tuple of files that are its dependencies. 38 | obj_deps = build_info.get('obj_deps', dict()) 39 | if not isinstance(obj_deps, dict): 40 | raise DistutilsSetupError( 41 | "in 'libraries' option (library '%s'), " 42 | "'obj_deps' must be a dictionary of " 43 | "type 'source: list'" % lib_name) 44 | dependencies = [] 45 | 46 | # Get the global dependencies that are specified by the '' key. 47 | # These will go into every source's dependency list. 48 | global_deps = obj_deps.get('', list()) 49 | if not isinstance(global_deps, (list, tuple)): 50 | raise DistutilsSetupError( 51 | "in 'libraries' option (library '%s'), " 52 | "'obj_deps' must be a dictionary of " 53 | "type 'source: list'" % lib_name) 54 | 55 | # Build the list to be used by newer_pairwise_group 56 | # each source will be auto-added to its dependencies. 57 | for source in sources: 58 | src_deps = [source] 59 | src_deps.extend(global_deps) 60 | extra_deps = obj_deps.get(source, list()) 61 | if not isinstance(extra_deps, (list, tuple)): 62 | raise DistutilsSetupError( 63 | "in 'libraries' option (library '%s'), " 64 | "'obj_deps' must be a dictionary of " 65 | "type 'source: list'" % lib_name) 66 | src_deps.extend(extra_deps) 67 | dependencies.append(src_deps) 68 | 69 | expected_objects = self.compiler.object_filenames( 70 | sources, 71 | output_dir=self.build_temp, 72 | ) 73 | 74 | if ( 75 | newer_pairwise_group(dependencies, expected_objects) 76 | != ([], []) 77 | ): 78 | # First, compile the source code to object files in the library 79 | # directory. (This should probably change to putting object 80 | # files in a temporary build directory.) 81 | macros = build_info.get('macros') 82 | include_dirs = build_info.get('include_dirs') 83 | cflags = build_info.get('cflags') 84 | self.compiler.compile( 85 | sources, 86 | output_dir=self.build_temp, 87 | macros=macros, 88 | include_dirs=include_dirs, 89 | extra_postargs=cflags, 90 | debug=self.debug 91 | ) 92 | 93 | # Now "link" the object files together into a static library. 94 | # (On Unix at least, this isn't really linking -- it just 95 | # builds an archive. Whatever.) 96 | self.compiler.create_static_lib( 97 | expected_objects, 98 | lib_name, 99 | output_dir=self.build_clib, 100 | debug=self.debug 101 | ) 102 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/develop.py: -------------------------------------------------------------------------------- 1 | from distutils.util import convert_path 2 | from distutils import log 3 | from distutils.errors import DistutilsError, DistutilsOptionError 4 | import os 5 | import glob 6 | import io 7 | 8 | from setuptools.extern import six 9 | 10 | import pkg_resources 11 | from setuptools.command.easy_install import easy_install 12 | from setuptools import namespaces 13 | import setuptools 14 | 15 | __metaclass__ = type 16 | 17 | 18 | class develop(namespaces.DevelopInstaller, easy_install): 19 | """Set up package for development""" 20 | 21 | description = "install package in 'development mode'" 22 | 23 | user_options = easy_install.user_options + [ 24 | ("uninstall", "u", "Uninstall this source package"), 25 | ("egg-path=", None, "Set the path to be used in the .egg-link file"), 26 | ] 27 | 28 | boolean_options = easy_install.boolean_options + ['uninstall'] 29 | 30 | command_consumes_arguments = False # override base 31 | 32 | def run(self): 33 | if self.uninstall: 34 | self.multi_version = True 35 | self.uninstall_link() 36 | self.uninstall_namespaces() 37 | else: 38 | self.install_for_development() 39 | self.warn_deprecated_options() 40 | 41 | def initialize_options(self): 42 | self.uninstall = None 43 | self.egg_path = None 44 | easy_install.initialize_options(self) 45 | self.setup_path = None 46 | self.always_copy_from = '.' # always copy eggs installed in curdir 47 | 48 | def finalize_options(self): 49 | ei = self.get_finalized_command("egg_info") 50 | if ei.broken_egg_info: 51 | template = "Please rename %r to %r before using 'develop'" 52 | args = ei.egg_info, ei.broken_egg_info 53 | raise DistutilsError(template % args) 54 | self.args = [ei.egg_name] 55 | 56 | easy_install.finalize_options(self) 57 | self.expand_basedirs() 58 | self.expand_dirs() 59 | # pick up setup-dir .egg files only: no .egg-info 60 | self.package_index.scan(glob.glob('*.egg')) 61 | 62 | egg_link_fn = ei.egg_name + '.egg-link' 63 | self.egg_link = os.path.join(self.install_dir, egg_link_fn) 64 | self.egg_base = ei.egg_base 65 | if self.egg_path is None: 66 | self.egg_path = os.path.abspath(ei.egg_base) 67 | 68 | target = pkg_resources.normalize_path(self.egg_base) 69 | egg_path = pkg_resources.normalize_path( 70 | os.path.join(self.install_dir, self.egg_path)) 71 | if egg_path != target: 72 | raise DistutilsOptionError( 73 | "--egg-path must be a relative path from the install" 74 | " directory to " + target 75 | ) 76 | 77 | # Make a distribution for the package's source 78 | self.dist = pkg_resources.Distribution( 79 | target, 80 | pkg_resources.PathMetadata(target, os.path.abspath(ei.egg_info)), 81 | project_name=ei.egg_name 82 | ) 83 | 84 | self.setup_path = self._resolve_setup_path( 85 | self.egg_base, 86 | self.install_dir, 87 | self.egg_path, 88 | ) 89 | 90 | @staticmethod 91 | def _resolve_setup_path(egg_base, install_dir, egg_path): 92 | """ 93 | Generate a path from egg_base back to '.' where the 94 | setup script resides and ensure that path points to the 95 | setup path from $install_dir/$egg_path. 96 | """ 97 | path_to_setup = egg_base.replace(os.sep, '/').rstrip('/') 98 | if path_to_setup != os.curdir: 99 | path_to_setup = '../' * (path_to_setup.count('/') + 1) 100 | resolved = pkg_resources.normalize_path( 101 | os.path.join(install_dir, egg_path, path_to_setup) 102 | ) 103 | if resolved != pkg_resources.normalize_path(os.curdir): 104 | raise DistutilsOptionError( 105 | "Can't get a consistent path to setup script from" 106 | " installation directory", resolved, 107 | pkg_resources.normalize_path(os.curdir)) 108 | return path_to_setup 109 | 110 | def install_for_development(self): 111 | if not six.PY2 and getattr(self.distribution, 'use_2to3', False): 112 | # If we run 2to3 we can not do this inplace: 113 | 114 | # Ensure metadata is up-to-date 115 | self.reinitialize_command('build_py', inplace=0) 116 | self.run_command('build_py') 117 | bpy_cmd = self.get_finalized_command("build_py") 118 | build_path = pkg_resources.normalize_path(bpy_cmd.build_lib) 119 | 120 | # Build extensions 121 | self.reinitialize_command('egg_info', egg_base=build_path) 122 | self.run_command('egg_info') 123 | 124 | self.reinitialize_command('build_ext', inplace=0) 125 | self.run_command('build_ext') 126 | 127 | # Fixup egg-link and easy-install.pth 128 | ei_cmd = self.get_finalized_command("egg_info") 129 | self.egg_path = build_path 130 | self.dist.location = build_path 131 | # XXX 132 | self.dist._provider = pkg_resources.PathMetadata( 133 | build_path, ei_cmd.egg_info) 134 | else: 135 | # Without 2to3 inplace works fine: 136 | self.run_command('egg_info') 137 | 138 | # Build extensions in-place 139 | self.reinitialize_command('build_ext', inplace=1) 140 | self.run_command('build_ext') 141 | 142 | self.install_site_py() # ensure that target dir is site-safe 143 | if setuptools.bootstrap_install_from: 144 | self.easy_install(setuptools.bootstrap_install_from) 145 | setuptools.bootstrap_install_from = None 146 | 147 | self.install_namespaces() 148 | 149 | # create an .egg-link in the installation dir, pointing to our egg 150 | log.info("Creating %s (link to %s)", self.egg_link, self.egg_base) 151 | if not self.dry_run: 152 | with open(self.egg_link, "w") as f: 153 | f.write(self.egg_path + "\n" + self.setup_path) 154 | # postprocess the installed distro, fixing up .pth, installing scripts, 155 | # and handling requirements 156 | self.process_distribution(None, self.dist, not self.no_deps) 157 | 158 | def uninstall_link(self): 159 | if os.path.exists(self.egg_link): 160 | log.info("Removing %s (link to %s)", self.egg_link, self.egg_base) 161 | egg_link_file = open(self.egg_link) 162 | contents = [line.rstrip() for line in egg_link_file] 163 | egg_link_file.close() 164 | if contents not in ([self.egg_path], 165 | [self.egg_path, self.setup_path]): 166 | log.warn("Link points to %s: uninstall aborted", contents) 167 | return 168 | if not self.dry_run: 169 | os.unlink(self.egg_link) 170 | if not self.dry_run: 171 | self.update_pth(self.dist) # remove any .pth link to us 172 | if self.distribution.scripts: 173 | # XXX should also check for entry point scripts! 174 | log.warn("Note: you must uninstall or replace scripts manually!") 175 | 176 | def install_egg_scripts(self, dist): 177 | if dist is not self.dist: 178 | # Installing a dependency, so fall back to normal behavior 179 | return easy_install.install_egg_scripts(self, dist) 180 | 181 | # create wrapper scripts in the script dir, pointing to dist.scripts 182 | 183 | # new-style... 184 | self.install_wrapper_scripts(dist) 185 | 186 | # ...and old-style 187 | for script_name in self.distribution.scripts or []: 188 | script_path = os.path.abspath(convert_path(script_name)) 189 | script_name = os.path.basename(script_path) 190 | with io.open(script_path) as strm: 191 | script_text = strm.read() 192 | self.install_script(dist, script_name, script_text, script_path) 193 | 194 | def install_wrapper_scripts(self, dist): 195 | dist = VersionlessRequirement(dist) 196 | return easy_install.install_wrapper_scripts(self, dist) 197 | 198 | 199 | class VersionlessRequirement: 200 | """ 201 | Adapt a pkg_resources.Distribution to simply return the project 202 | name as the 'requirement' so that scripts will work across 203 | multiple versions. 204 | 205 | >>> from pkg_resources import Distribution 206 | >>> dist = Distribution(project_name='foo', version='1.0') 207 | >>> str(dist.as_requirement()) 208 | 'foo==1.0' 209 | >>> adapted_dist = VersionlessRequirement(dist) 210 | >>> str(adapted_dist.as_requirement()) 211 | 'foo' 212 | """ 213 | 214 | def __init__(self, dist): 215 | self.__dist = dist 216 | 217 | def __getattr__(self, name): 218 | return getattr(self.__dist, name) 219 | 220 | def as_requirement(self): 221 | return self.project_name 222 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/dist_info.py: -------------------------------------------------------------------------------- 1 | """ 2 | Create a dist_info directory 3 | As defined in the wheel specification 4 | """ 5 | 6 | import os 7 | 8 | from distutils.core import Command 9 | from distutils import log 10 | 11 | 12 | class dist_info(Command): 13 | 14 | description = 'create a .dist-info directory' 15 | 16 | user_options = [ 17 | ('egg-base=', 'e', "directory containing .egg-info directories" 18 | " (default: top of the source tree)"), 19 | ] 20 | 21 | def initialize_options(self): 22 | self.egg_base = None 23 | 24 | def finalize_options(self): 25 | pass 26 | 27 | def run(self): 28 | egg_info = self.get_finalized_command('egg_info') 29 | egg_info.egg_base = self.egg_base 30 | egg_info.finalize_options() 31 | egg_info.run() 32 | dist_info_dir = egg_info.egg_info[:-len('.egg-info')] + '.dist-info' 33 | log.info("creating '{}'".format(os.path.abspath(dist_info_dir))) 34 | 35 | bdist_wheel = self.get_finalized_command('bdist_wheel') 36 | bdist_wheel.egg2dist(egg_info.egg_info, dist_info_dir) 37 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/install.py: -------------------------------------------------------------------------------- 1 | from distutils.errors import DistutilsArgError 2 | import inspect 3 | import glob 4 | import warnings 5 | import platform 6 | import distutils.command.install as orig 7 | 8 | import setuptools 9 | 10 | # Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for 11 | # now. See https://github.com/pypa/setuptools/issues/199/ 12 | _install = orig.install 13 | 14 | 15 | class install(orig.install): 16 | """Use easy_install to install the package, w/dependencies""" 17 | 18 | user_options = orig.install.user_options + [ 19 | ('old-and-unmanageable', None, "Try not to use this!"), 20 | ('single-version-externally-managed', None, 21 | "used by system package builders to create 'flat' eggs"), 22 | ] 23 | boolean_options = orig.install.boolean_options + [ 24 | 'old-and-unmanageable', 'single-version-externally-managed', 25 | ] 26 | new_commands = [ 27 | ('install_egg_info', lambda self: True), 28 | ('install_scripts', lambda self: True), 29 | ] 30 | _nc = dict(new_commands) 31 | 32 | def initialize_options(self): 33 | orig.install.initialize_options(self) 34 | self.old_and_unmanageable = None 35 | self.single_version_externally_managed = None 36 | 37 | def finalize_options(self): 38 | orig.install.finalize_options(self) 39 | if self.root: 40 | self.single_version_externally_managed = True 41 | elif self.single_version_externally_managed: 42 | if not self.root and not self.record: 43 | raise DistutilsArgError( 44 | "You must specify --record or --root when building system" 45 | " packages" 46 | ) 47 | 48 | def handle_extra_path(self): 49 | if self.root or self.single_version_externally_managed: 50 | # explicit backward-compatibility mode, allow extra_path to work 51 | return orig.install.handle_extra_path(self) 52 | 53 | # Ignore extra_path when installing an egg (or being run by another 54 | # command without --root or --single-version-externally-managed 55 | self.path_file = None 56 | self.extra_dirs = '' 57 | 58 | def run(self): 59 | # Explicit request for old-style install? Just do it 60 | if self.old_and_unmanageable or self.single_version_externally_managed: 61 | return orig.install.run(self) 62 | 63 | if not self._called_from_setup(inspect.currentframe()): 64 | # Run in backward-compatibility mode to support bdist_* commands. 65 | orig.install.run(self) 66 | else: 67 | self.do_egg_install() 68 | 69 | @staticmethod 70 | def _called_from_setup(run_frame): 71 | """ 72 | Attempt to detect whether run() was called from setup() or by another 73 | command. If called by setup(), the parent caller will be the 74 | 'run_command' method in 'distutils.dist', and *its* caller will be 75 | the 'run_commands' method. If called any other way, the 76 | immediate caller *might* be 'run_command', but it won't have been 77 | called by 'run_commands'. Return True in that case or if a call stack 78 | is unavailable. Return False otherwise. 79 | """ 80 | if run_frame is None: 81 | msg = "Call stack not available. bdist_* commands may fail." 82 | warnings.warn(msg) 83 | if platform.python_implementation() == 'IronPython': 84 | msg = "For best results, pass -X:Frames to enable call stack." 85 | warnings.warn(msg) 86 | return True 87 | res = inspect.getouterframes(run_frame)[2] 88 | caller, = res[:1] 89 | info = inspect.getframeinfo(caller) 90 | caller_module = caller.f_globals.get('__name__', '') 91 | return ( 92 | caller_module == 'distutils.dist' 93 | and info.function == 'run_commands' 94 | ) 95 | 96 | def do_egg_install(self): 97 | 98 | easy_install = self.distribution.get_command_class('easy_install') 99 | 100 | cmd = easy_install( 101 | self.distribution, args="x", root=self.root, record=self.record, 102 | ) 103 | cmd.ensure_finalized() # finalize before bdist_egg munges install cmd 104 | cmd.always_copy_from = '.' # make sure local-dir eggs get installed 105 | 106 | # pick up setup-dir .egg files only: no .egg-info 107 | cmd.package_index.scan(glob.glob('*.egg')) 108 | 109 | self.run_command('bdist_egg') 110 | args = [self.distribution.get_command_obj('bdist_egg').egg_output] 111 | 112 | if setuptools.bootstrap_install_from: 113 | # Bootstrap self-installation of setuptools 114 | args.insert(0, setuptools.bootstrap_install_from) 115 | 116 | cmd.args = args 117 | cmd.run(show_deprecation=False) 118 | setuptools.bootstrap_install_from = None 119 | 120 | 121 | # XXX Python 3.1 doesn't see _nc if this is inside the class 122 | install.sub_commands = ( 123 | [cmd for cmd in orig.install.sub_commands if cmd[0] not in install._nc] + 124 | install.new_commands 125 | ) 126 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/install_egg_info.py: -------------------------------------------------------------------------------- 1 | from distutils import log, dir_util 2 | import os 3 | 4 | from setuptools import Command 5 | from setuptools import namespaces 6 | from setuptools.archive_util import unpack_archive 7 | import pkg_resources 8 | 9 | 10 | class install_egg_info(namespaces.Installer, Command): 11 | """Install an .egg-info directory for the package""" 12 | 13 | description = "Install an .egg-info directory for the package" 14 | 15 | user_options = [ 16 | ('install-dir=', 'd', "directory to install to"), 17 | ] 18 | 19 | def initialize_options(self): 20 | self.install_dir = None 21 | 22 | def finalize_options(self): 23 | self.set_undefined_options('install_lib', 24 | ('install_dir', 'install_dir')) 25 | ei_cmd = self.get_finalized_command("egg_info") 26 | basename = pkg_resources.Distribution( 27 | None, None, ei_cmd.egg_name, ei_cmd.egg_version 28 | ).egg_name() + '.egg-info' 29 | self.source = ei_cmd.egg_info 30 | self.target = os.path.join(self.install_dir, basename) 31 | self.outputs = [] 32 | 33 | def run(self): 34 | self.run_command('egg_info') 35 | if os.path.isdir(self.target) and not os.path.islink(self.target): 36 | dir_util.remove_tree(self.target, dry_run=self.dry_run) 37 | elif os.path.exists(self.target): 38 | self.execute(os.unlink, (self.target,), "Removing " + self.target) 39 | if not self.dry_run: 40 | pkg_resources.ensure_directory(self.target) 41 | self.execute( 42 | self.copytree, (), "Copying %s to %s" % (self.source, self.target) 43 | ) 44 | self.install_namespaces() 45 | 46 | def get_outputs(self): 47 | return self.outputs 48 | 49 | def copytree(self): 50 | # Copy the .egg-info tree to site-packages 51 | def skimmer(src, dst): 52 | # filter out source-control directories; note that 'src' is always 53 | # a '/'-separated path, regardless of platform. 'dst' is a 54 | # platform-specific path. 55 | for skip in '.svn/', 'CVS/': 56 | if src.startswith(skip) or '/' + skip in src: 57 | return None 58 | self.outputs.append(dst) 59 | log.debug("Copying %s to %s", src, dst) 60 | return dst 61 | 62 | unpack_archive(self.source, self.target, skimmer) 63 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/install_lib.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | from itertools import product, starmap 4 | import distutils.command.install_lib as orig 5 | 6 | 7 | class install_lib(orig.install_lib): 8 | """Don't add compiled flags to filenames of non-Python files""" 9 | 10 | def run(self): 11 | self.build() 12 | outfiles = self.install() 13 | if outfiles is not None: 14 | # always compile, in case we have any extension stubs to deal with 15 | self.byte_compile(outfiles) 16 | 17 | def get_exclusions(self): 18 | """ 19 | Return a collections.Sized collections.Container of paths to be 20 | excluded for single_version_externally_managed installations. 21 | """ 22 | all_packages = ( 23 | pkg 24 | for ns_pkg in self._get_SVEM_NSPs() 25 | for pkg in self._all_packages(ns_pkg) 26 | ) 27 | 28 | excl_specs = product(all_packages, self._gen_exclusion_paths()) 29 | return set(starmap(self._exclude_pkg_path, excl_specs)) 30 | 31 | def _exclude_pkg_path(self, pkg, exclusion_path): 32 | """ 33 | Given a package name and exclusion path within that package, 34 | compute the full exclusion path. 35 | """ 36 | parts = pkg.split('.') + [exclusion_path] 37 | return os.path.join(self.install_dir, *parts) 38 | 39 | @staticmethod 40 | def _all_packages(pkg_name): 41 | """ 42 | >>> list(install_lib._all_packages('foo.bar.baz')) 43 | ['foo.bar.baz', 'foo.bar', 'foo'] 44 | """ 45 | while pkg_name: 46 | yield pkg_name 47 | pkg_name, sep, child = pkg_name.rpartition('.') 48 | 49 | def _get_SVEM_NSPs(self): 50 | """ 51 | Get namespace packages (list) but only for 52 | single_version_externally_managed installations and empty otherwise. 53 | """ 54 | # TODO: is it necessary to short-circuit here? i.e. what's the cost 55 | # if get_finalized_command is called even when namespace_packages is 56 | # False? 57 | if not self.distribution.namespace_packages: 58 | return [] 59 | 60 | install_cmd = self.get_finalized_command('install') 61 | svem = install_cmd.single_version_externally_managed 62 | 63 | return self.distribution.namespace_packages if svem else [] 64 | 65 | @staticmethod 66 | def _gen_exclusion_paths(): 67 | """ 68 | Generate file paths to be excluded for namespace packages (bytecode 69 | cache files). 70 | """ 71 | # always exclude the package module itself 72 | yield '__init__.py' 73 | 74 | yield '__init__.pyc' 75 | yield '__init__.pyo' 76 | 77 | if not hasattr(sys, 'implementation'): 78 | return 79 | 80 | base = os.path.join( 81 | '__pycache__', '__init__.' + sys.implementation.cache_tag) 82 | yield base + '.pyc' 83 | yield base + '.pyo' 84 | yield base + '.opt-1.pyc' 85 | yield base + '.opt-2.pyc' 86 | 87 | def copy_tree( 88 | self, infile, outfile, 89 | preserve_mode=1, preserve_times=1, preserve_symlinks=0, level=1 90 | ): 91 | assert preserve_mode and preserve_times and not preserve_symlinks 92 | exclude = self.get_exclusions() 93 | 94 | if not exclude: 95 | return orig.install_lib.copy_tree(self, infile, outfile) 96 | 97 | # Exclude namespace package __init__.py* files from the output 98 | 99 | from setuptools.archive_util import unpack_directory 100 | from distutils import log 101 | 102 | outfiles = [] 103 | 104 | def pf(src, dst): 105 | if dst in exclude: 106 | log.warn("Skipping installation of %s (namespace package)", 107 | dst) 108 | return False 109 | 110 | log.info("copying %s -> %s", src, os.path.dirname(dst)) 111 | outfiles.append(dst) 112 | return dst 113 | 114 | unpack_directory(infile, outfile, pf) 115 | return outfiles 116 | 117 | def get_outputs(self): 118 | outputs = orig.install_lib.get_outputs(self) 119 | exclude = self.get_exclusions() 120 | if exclude: 121 | return [f for f in outputs if f not in exclude] 122 | return outputs 123 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/install_scripts.py: -------------------------------------------------------------------------------- 1 | from distutils import log 2 | import distutils.command.install_scripts as orig 3 | import os 4 | import sys 5 | 6 | from pkg_resources import Distribution, PathMetadata, ensure_directory 7 | 8 | 9 | class install_scripts(orig.install_scripts): 10 | """Do normal script install, plus any egg_info wrapper scripts""" 11 | 12 | def initialize_options(self): 13 | orig.install_scripts.initialize_options(self) 14 | self.no_ep = False 15 | 16 | def run(self): 17 | import setuptools.command.easy_install as ei 18 | 19 | self.run_command("egg_info") 20 | if self.distribution.scripts: 21 | orig.install_scripts.run(self) # run first to set up self.outfiles 22 | else: 23 | self.outfiles = [] 24 | if self.no_ep: 25 | # don't install entry point scripts into .egg file! 26 | return 27 | 28 | ei_cmd = self.get_finalized_command("egg_info") 29 | dist = Distribution( 30 | ei_cmd.egg_base, PathMetadata(ei_cmd.egg_base, ei_cmd.egg_info), 31 | ei_cmd.egg_name, ei_cmd.egg_version, 32 | ) 33 | bs_cmd = self.get_finalized_command('build_scripts') 34 | exec_param = getattr(bs_cmd, 'executable', None) 35 | try: 36 | bw_cmd = self.get_finalized_command("bdist_wininst") 37 | is_wininst = getattr(bw_cmd, '_is_running', False) 38 | except ImportError: 39 | is_wininst = False 40 | writer = ei.ScriptWriter 41 | if is_wininst: 42 | exec_param = "python.exe" 43 | writer = ei.WindowsScriptWriter 44 | if exec_param == sys.executable: 45 | # In case the path to the Python executable contains a space, wrap 46 | # it so it's not split up. 47 | exec_param = [exec_param] 48 | # resolve the writer to the environment 49 | writer = writer.best() 50 | cmd = writer.command_spec_class.best().from_param(exec_param) 51 | for args in writer.get_args(dist, cmd.as_header()): 52 | self.write_script(*args) 53 | 54 | def write_script(self, script_name, contents, mode="t", *ignored): 55 | """Write an executable file to the scripts directory""" 56 | from setuptools.command.easy_install import chmod, current_umask 57 | 58 | log.info("Installing %s script to %s", script_name, self.install_dir) 59 | target = os.path.join(self.install_dir, script_name) 60 | self.outfiles.append(target) 61 | 62 | mask = current_umask() 63 | if not self.dry_run: 64 | ensure_directory(target) 65 | f = open(target, "w" + mode) 66 | f.write(contents) 67 | f.close() 68 | chmod(target, 0o777 - mask) 69 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/launcher manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/py36compat.py: -------------------------------------------------------------------------------- 1 | import os 2 | from glob import glob 3 | from distutils.util import convert_path 4 | from distutils.command import sdist 5 | 6 | from setuptools.extern.six.moves import filter 7 | 8 | 9 | class sdist_add_defaults: 10 | """ 11 | Mix-in providing forward-compatibility for functionality as found in 12 | distutils on Python 3.7. 13 | 14 | Do not edit the code in this class except to update functionality 15 | as implemented in distutils. Instead, override in the subclass. 16 | """ 17 | 18 | def add_defaults(self): 19 | """Add all the default files to self.filelist: 20 | - README or README.txt 21 | - setup.py 22 | - test/test*.py 23 | - all pure Python modules mentioned in setup script 24 | - all files pointed by package_data (build_py) 25 | - all files defined in data_files. 26 | - all files defined as scripts. 27 | - all C sources listed as part of extensions or C libraries 28 | in the setup script (doesn't catch C headers!) 29 | Warns if (README or README.txt) or setup.py are missing; everything 30 | else is optional. 31 | """ 32 | self._add_defaults_standards() 33 | self._add_defaults_optional() 34 | self._add_defaults_python() 35 | self._add_defaults_data_files() 36 | self._add_defaults_ext() 37 | self._add_defaults_c_libs() 38 | self._add_defaults_scripts() 39 | 40 | @staticmethod 41 | def _cs_path_exists(fspath): 42 | """ 43 | Case-sensitive path existence check 44 | 45 | >>> sdist_add_defaults._cs_path_exists(__file__) 46 | True 47 | >>> sdist_add_defaults._cs_path_exists(__file__.upper()) 48 | False 49 | """ 50 | if not os.path.exists(fspath): 51 | return False 52 | # make absolute so we always have a directory 53 | abspath = os.path.abspath(fspath) 54 | directory, filename = os.path.split(abspath) 55 | return filename in os.listdir(directory) 56 | 57 | def _add_defaults_standards(self): 58 | standards = [self.READMES, self.distribution.script_name] 59 | for fn in standards: 60 | if isinstance(fn, tuple): 61 | alts = fn 62 | got_it = False 63 | for fn in alts: 64 | if self._cs_path_exists(fn): 65 | got_it = True 66 | self.filelist.append(fn) 67 | break 68 | 69 | if not got_it: 70 | self.warn("standard file not found: should have one of " + 71 | ', '.join(alts)) 72 | else: 73 | if self._cs_path_exists(fn): 74 | self.filelist.append(fn) 75 | else: 76 | self.warn("standard file '%s' not found" % fn) 77 | 78 | def _add_defaults_optional(self): 79 | optional = ['test/test*.py', 'setup.cfg'] 80 | for pattern in optional: 81 | files = filter(os.path.isfile, glob(pattern)) 82 | self.filelist.extend(files) 83 | 84 | def _add_defaults_python(self): 85 | # build_py is used to get: 86 | # - python modules 87 | # - files defined in package_data 88 | build_py = self.get_finalized_command('build_py') 89 | 90 | # getting python files 91 | if self.distribution.has_pure_modules(): 92 | self.filelist.extend(build_py.get_source_files()) 93 | 94 | # getting package_data files 95 | # (computed in build_py.data_files by build_py.finalize_options) 96 | for pkg, src_dir, build_dir, filenames in build_py.data_files: 97 | for filename in filenames: 98 | self.filelist.append(os.path.join(src_dir, filename)) 99 | 100 | def _add_defaults_data_files(self): 101 | # getting distribution.data_files 102 | if self.distribution.has_data_files(): 103 | for item in self.distribution.data_files: 104 | if isinstance(item, str): 105 | # plain file 106 | item = convert_path(item) 107 | if os.path.isfile(item): 108 | self.filelist.append(item) 109 | else: 110 | # a (dirname, filenames) tuple 111 | dirname, filenames = item 112 | for f in filenames: 113 | f = convert_path(f) 114 | if os.path.isfile(f): 115 | self.filelist.append(f) 116 | 117 | def _add_defaults_ext(self): 118 | if self.distribution.has_ext_modules(): 119 | build_ext = self.get_finalized_command('build_ext') 120 | self.filelist.extend(build_ext.get_source_files()) 121 | 122 | def _add_defaults_c_libs(self): 123 | if self.distribution.has_c_libraries(): 124 | build_clib = self.get_finalized_command('build_clib') 125 | self.filelist.extend(build_clib.get_source_files()) 126 | 127 | def _add_defaults_scripts(self): 128 | if self.distribution.has_scripts(): 129 | build_scripts = self.get_finalized_command('build_scripts') 130 | self.filelist.extend(build_scripts.get_source_files()) 131 | 132 | 133 | if hasattr(sdist.sdist, '_add_defaults_standards'): 134 | # disable the functionality already available upstream 135 | class sdist_add_defaults: # noqa 136 | pass 137 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/register.py: -------------------------------------------------------------------------------- 1 | from distutils import log 2 | import distutils.command.register as orig 3 | 4 | from setuptools.errors import RemovedCommandError 5 | 6 | 7 | class register(orig.register): 8 | """Formerly used to register packages on PyPI.""" 9 | 10 | def run(self): 11 | msg = ( 12 | "The register command has been removed, use twine to upload " 13 | + "instead (https://pypi.org/p/twine)" 14 | ) 15 | 16 | self.announce("ERROR: " + msg, log.ERROR) 17 | 18 | raise RemovedCommandError(msg) 19 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/rotate.py: -------------------------------------------------------------------------------- 1 | from distutils.util import convert_path 2 | from distutils import log 3 | from distutils.errors import DistutilsOptionError 4 | import os 5 | import shutil 6 | 7 | from setuptools.extern import six 8 | 9 | from setuptools import Command 10 | 11 | 12 | class rotate(Command): 13 | """Delete older distributions""" 14 | 15 | description = "delete older distributions, keeping N newest files" 16 | user_options = [ 17 | ('match=', 'm', "patterns to match (required)"), 18 | ('dist-dir=', 'd', "directory where the distributions are"), 19 | ('keep=', 'k', "number of matching distributions to keep"), 20 | ] 21 | 22 | boolean_options = [] 23 | 24 | def initialize_options(self): 25 | self.match = None 26 | self.dist_dir = None 27 | self.keep = None 28 | 29 | def finalize_options(self): 30 | if self.match is None: 31 | raise DistutilsOptionError( 32 | "Must specify one or more (comma-separated) match patterns " 33 | "(e.g. '.zip' or '.egg')" 34 | ) 35 | if self.keep is None: 36 | raise DistutilsOptionError("Must specify number of files to keep") 37 | try: 38 | self.keep = int(self.keep) 39 | except ValueError: 40 | raise DistutilsOptionError("--keep must be an integer") 41 | if isinstance(self.match, six.string_types): 42 | self.match = [ 43 | convert_path(p.strip()) for p in self.match.split(',') 44 | ] 45 | self.set_undefined_options('bdist', ('dist_dir', 'dist_dir')) 46 | 47 | def run(self): 48 | self.run_command("egg_info") 49 | from glob import glob 50 | 51 | for pattern in self.match: 52 | pattern = self.distribution.get_name() + '*' + pattern 53 | files = glob(os.path.join(self.dist_dir, pattern)) 54 | files = [(os.path.getmtime(f), f) for f in files] 55 | files.sort() 56 | files.reverse() 57 | 58 | log.info("%d file(s) matching %s", len(files), pattern) 59 | files = files[self.keep:] 60 | for (t, f) in files: 61 | log.info("Deleting %s", f) 62 | if not self.dry_run: 63 | if os.path.isdir(f): 64 | shutil.rmtree(f) 65 | else: 66 | os.unlink(f) 67 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/saveopts.py: -------------------------------------------------------------------------------- 1 | from setuptools.command.setopt import edit_config, option_base 2 | 3 | 4 | class saveopts(option_base): 5 | """Save command-line options to a file""" 6 | 7 | description = "save supplied options to setup.cfg or other config file" 8 | 9 | def run(self): 10 | dist = self.distribution 11 | settings = {} 12 | 13 | for cmd in dist.command_options: 14 | 15 | if cmd == 'saveopts': 16 | continue # don't save our own options! 17 | 18 | for opt, (src, val) in dist.get_option_dict(cmd).items(): 19 | if src == "command line": 20 | settings.setdefault(cmd, {})[opt] = val 21 | 22 | edit_config(self.filename, settings, self.dry_run) 23 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/sdist.py: -------------------------------------------------------------------------------- 1 | from distutils import log 2 | import distutils.command.sdist as orig 3 | import os 4 | import sys 5 | import io 6 | import contextlib 7 | 8 | from setuptools.extern import six, ordered_set 9 | 10 | from .py36compat import sdist_add_defaults 11 | 12 | import pkg_resources 13 | 14 | _default_revctrl = list 15 | 16 | 17 | def walk_revctrl(dirname=''): 18 | """Find all files under revision control""" 19 | for ep in pkg_resources.iter_entry_points('setuptools.file_finders'): 20 | for item in ep.load()(dirname): 21 | yield item 22 | 23 | 24 | class sdist(sdist_add_defaults, orig.sdist): 25 | """Smart sdist that finds anything supported by revision control""" 26 | 27 | user_options = [ 28 | ('formats=', None, 29 | "formats for source distribution (comma-separated list)"), 30 | ('keep-temp', 'k', 31 | "keep the distribution tree around after creating " + 32 | "archive file(s)"), 33 | ('dist-dir=', 'd', 34 | "directory to put the source distribution archive(s) in " 35 | "[default: dist]"), 36 | ] 37 | 38 | negative_opt = {} 39 | 40 | README_EXTENSIONS = ['', '.rst', '.txt', '.md'] 41 | READMES = tuple('README{0}'.format(ext) for ext in README_EXTENSIONS) 42 | 43 | def run(self): 44 | self.run_command('egg_info') 45 | ei_cmd = self.get_finalized_command('egg_info') 46 | self.filelist = ei_cmd.filelist 47 | self.filelist.append(os.path.join(ei_cmd.egg_info, 'SOURCES.txt')) 48 | self.check_readme() 49 | 50 | # Run sub commands 51 | for cmd_name in self.get_sub_commands(): 52 | self.run_command(cmd_name) 53 | 54 | self.make_distribution() 55 | 56 | dist_files = getattr(self.distribution, 'dist_files', []) 57 | for file in self.archive_files: 58 | data = ('sdist', '', file) 59 | if data not in dist_files: 60 | dist_files.append(data) 61 | 62 | def initialize_options(self): 63 | orig.sdist.initialize_options(self) 64 | 65 | self._default_to_gztar() 66 | 67 | def _default_to_gztar(self): 68 | # only needed on Python prior to 3.6. 69 | if sys.version_info >= (3, 6, 0, 'beta', 1): 70 | return 71 | self.formats = ['gztar'] 72 | 73 | def make_distribution(self): 74 | """ 75 | Workaround for #516 76 | """ 77 | with self._remove_os_link(): 78 | orig.sdist.make_distribution(self) 79 | 80 | @staticmethod 81 | @contextlib.contextmanager 82 | def _remove_os_link(): 83 | """ 84 | In a context, remove and restore os.link if it exists 85 | """ 86 | 87 | class NoValue: 88 | pass 89 | 90 | orig_val = getattr(os, 'link', NoValue) 91 | try: 92 | del os.link 93 | except Exception: 94 | pass 95 | try: 96 | yield 97 | finally: 98 | if orig_val is not NoValue: 99 | setattr(os, 'link', orig_val) 100 | 101 | def __read_template_hack(self): 102 | # This grody hack closes the template file (MANIFEST.in) if an 103 | # exception occurs during read_template. 104 | # Doing so prevents an error when easy_install attempts to delete the 105 | # file. 106 | try: 107 | orig.sdist.read_template(self) 108 | except Exception: 109 | _, _, tb = sys.exc_info() 110 | tb.tb_next.tb_frame.f_locals['template'].close() 111 | raise 112 | 113 | # Beginning with Python 2.7.2, 3.1.4, and 3.2.1, this leaky file handle 114 | # has been fixed, so only override the method if we're using an earlier 115 | # Python. 116 | has_leaky_handle = ( 117 | sys.version_info < (2, 7, 2) 118 | or (3, 0) <= sys.version_info < (3, 1, 4) 119 | or (3, 2) <= sys.version_info < (3, 2, 1) 120 | ) 121 | if has_leaky_handle: 122 | read_template = __read_template_hack 123 | 124 | def _add_defaults_optional(self): 125 | if six.PY2: 126 | sdist_add_defaults._add_defaults_optional(self) 127 | else: 128 | super()._add_defaults_optional() 129 | if os.path.isfile('pyproject.toml'): 130 | self.filelist.append('pyproject.toml') 131 | 132 | def _add_defaults_python(self): 133 | """getting python files""" 134 | if self.distribution.has_pure_modules(): 135 | build_py = self.get_finalized_command('build_py') 136 | self.filelist.extend(build_py.get_source_files()) 137 | self._add_data_files(self._safe_data_files(build_py)) 138 | 139 | def _safe_data_files(self, build_py): 140 | """ 141 | Extracting data_files from build_py is known to cause 142 | infinite recursion errors when `include_package_data` 143 | is enabled, so suppress it in that case. 144 | """ 145 | if self.distribution.include_package_data: 146 | return () 147 | return build_py.data_files 148 | 149 | def _add_data_files(self, data_files): 150 | """ 151 | Add data files as found in build_py.data_files. 152 | """ 153 | self.filelist.extend( 154 | os.path.join(src_dir, name) 155 | for _, src_dir, _, filenames in data_files 156 | for name in filenames 157 | ) 158 | 159 | def _add_defaults_data_files(self): 160 | try: 161 | if six.PY2: 162 | sdist_add_defaults._add_defaults_data_files(self) 163 | else: 164 | super()._add_defaults_data_files() 165 | except TypeError: 166 | log.warn("data_files contains unexpected objects") 167 | 168 | def check_readme(self): 169 | for f in self.READMES: 170 | if os.path.exists(f): 171 | return 172 | else: 173 | self.warn( 174 | "standard file not found: should have one of " + 175 | ', '.join(self.READMES) 176 | ) 177 | 178 | def make_release_tree(self, base_dir, files): 179 | orig.sdist.make_release_tree(self, base_dir, files) 180 | 181 | # Save any egg_info command line options used to create this sdist 182 | dest = os.path.join(base_dir, 'setup.cfg') 183 | if hasattr(os, 'link') and os.path.exists(dest): 184 | # unlink and re-copy, since it might be hard-linked, and 185 | # we don't want to change the source version 186 | os.unlink(dest) 187 | self.copy_file('setup.cfg', dest) 188 | 189 | self.get_finalized_command('egg_info').save_version_info(dest) 190 | 191 | def _manifest_is_not_generated(self): 192 | # check for special comment used in 2.7.1 and higher 193 | if not os.path.isfile(self.manifest): 194 | return False 195 | 196 | with io.open(self.manifest, 'rb') as fp: 197 | first_line = fp.readline() 198 | return (first_line != 199 | '# file GENERATED by distutils, do NOT edit\n'.encode()) 200 | 201 | def read_manifest(self): 202 | """Read the manifest file (named by 'self.manifest') and use it to 203 | fill in 'self.filelist', the list of files to include in the source 204 | distribution. 205 | """ 206 | log.info("reading manifest file '%s'", self.manifest) 207 | manifest = open(self.manifest, 'rb') 208 | for line in manifest: 209 | # The manifest must contain UTF-8. See #303. 210 | if not six.PY2: 211 | try: 212 | line = line.decode('UTF-8') 213 | except UnicodeDecodeError: 214 | log.warn("%r not UTF-8 decodable -- skipping" % line) 215 | continue 216 | # ignore comments and blank lines 217 | line = line.strip() 218 | if line.startswith('#') or not line: 219 | continue 220 | self.filelist.append(line) 221 | manifest.close() 222 | 223 | def check_license(self): 224 | """Checks if license_file' or 'license_files' is configured and adds any 225 | valid paths to 'self.filelist'. 226 | """ 227 | 228 | files = ordered_set.OrderedSet() 229 | 230 | opts = self.distribution.get_option_dict('metadata') 231 | 232 | # ignore the source of the value 233 | _, license_file = opts.get('license_file', (None, None)) 234 | 235 | if license_file is None: 236 | log.debug("'license_file' option was not specified") 237 | else: 238 | files.add(license_file) 239 | 240 | try: 241 | files.update(self.distribution.metadata.license_files) 242 | except TypeError: 243 | log.warn("warning: 'license_files' option is malformed") 244 | 245 | for f in files: 246 | if not os.path.exists(f): 247 | log.warn( 248 | "warning: Failed to find the configured license file '%s'", 249 | f) 250 | files.remove(f) 251 | 252 | self.filelist.extend(files) 253 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/setopt.py: -------------------------------------------------------------------------------- 1 | from distutils.util import convert_path 2 | from distutils import log 3 | from distutils.errors import DistutilsOptionError 4 | import distutils 5 | import os 6 | 7 | from setuptools.extern.six.moves import configparser 8 | 9 | from setuptools import Command 10 | 11 | __all__ = ['config_file', 'edit_config', 'option_base', 'setopt'] 12 | 13 | 14 | def config_file(kind="local"): 15 | """Get the filename of the distutils, local, global, or per-user config 16 | 17 | `kind` must be one of "local", "global", or "user" 18 | """ 19 | if kind == 'local': 20 | return 'setup.cfg' 21 | if kind == 'global': 22 | return os.path.join( 23 | os.path.dirname(distutils.__file__), 'distutils.cfg' 24 | ) 25 | if kind == 'user': 26 | dot = os.name == 'posix' and '.' or '' 27 | return os.path.expanduser(convert_path("~/%spydistutils.cfg" % dot)) 28 | raise ValueError( 29 | "config_file() type must be 'local', 'global', or 'user'", kind 30 | ) 31 | 32 | 33 | def edit_config(filename, settings, dry_run=False): 34 | """Edit a configuration file to include `settings` 35 | 36 | `settings` is a dictionary of dictionaries or ``None`` values, keyed by 37 | command/section name. A ``None`` value means to delete the entire section, 38 | while a dictionary lists settings to be changed or deleted in that section. 39 | A setting of ``None`` means to delete that setting. 40 | """ 41 | log.debug("Reading configuration from %s", filename) 42 | opts = configparser.RawConfigParser() 43 | opts.read([filename]) 44 | for section, options in settings.items(): 45 | if options is None: 46 | log.info("Deleting section [%s] from %s", section, filename) 47 | opts.remove_section(section) 48 | else: 49 | if not opts.has_section(section): 50 | log.debug("Adding new section [%s] to %s", section, filename) 51 | opts.add_section(section) 52 | for option, value in options.items(): 53 | if value is None: 54 | log.debug( 55 | "Deleting %s.%s from %s", 56 | section, option, filename 57 | ) 58 | opts.remove_option(section, option) 59 | if not opts.options(section): 60 | log.info("Deleting empty [%s] section from %s", 61 | section, filename) 62 | opts.remove_section(section) 63 | else: 64 | log.debug( 65 | "Setting %s.%s to %r in %s", 66 | section, option, value, filename 67 | ) 68 | opts.set(section, option, value) 69 | 70 | log.info("Writing %s", filename) 71 | if not dry_run: 72 | with open(filename, 'w') as f: 73 | opts.write(f) 74 | 75 | 76 | class option_base(Command): 77 | """Abstract base class for commands that mess with config files""" 78 | 79 | user_options = [ 80 | ('global-config', 'g', 81 | "save options to the site-wide distutils.cfg file"), 82 | ('user-config', 'u', 83 | "save options to the current user's pydistutils.cfg file"), 84 | ('filename=', 'f', 85 | "configuration file to use (default=setup.cfg)"), 86 | ] 87 | 88 | boolean_options = [ 89 | 'global-config', 'user-config', 90 | ] 91 | 92 | def initialize_options(self): 93 | self.global_config = None 94 | self.user_config = None 95 | self.filename = None 96 | 97 | def finalize_options(self): 98 | filenames = [] 99 | if self.global_config: 100 | filenames.append(config_file('global')) 101 | if self.user_config: 102 | filenames.append(config_file('user')) 103 | if self.filename is not None: 104 | filenames.append(self.filename) 105 | if not filenames: 106 | filenames.append(config_file('local')) 107 | if len(filenames) > 1: 108 | raise DistutilsOptionError( 109 | "Must specify only one configuration file option", 110 | filenames 111 | ) 112 | self.filename, = filenames 113 | 114 | 115 | class setopt(option_base): 116 | """Save command-line options to a file""" 117 | 118 | description = "set an option in setup.cfg or another config file" 119 | 120 | user_options = [ 121 | ('command=', 'c', 'command to set an option for'), 122 | ('option=', 'o', 'option to set'), 123 | ('set-value=', 's', 'value of the option'), 124 | ('remove', 'r', 'remove (unset) the value'), 125 | ] + option_base.user_options 126 | 127 | boolean_options = option_base.boolean_options + ['remove'] 128 | 129 | def initialize_options(self): 130 | option_base.initialize_options(self) 131 | self.command = None 132 | self.option = None 133 | self.set_value = None 134 | self.remove = None 135 | 136 | def finalize_options(self): 137 | option_base.finalize_options(self) 138 | if self.command is None or self.option is None: 139 | raise DistutilsOptionError("Must specify --command *and* --option") 140 | if self.set_value is None and not self.remove: 141 | raise DistutilsOptionError("Must specify --set-value or --remove") 142 | 143 | def run(self): 144 | edit_config( 145 | self.filename, { 146 | self.command: {self.option.replace('-', '_'): self.set_value} 147 | }, 148 | self.dry_run 149 | ) 150 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/upload.py: -------------------------------------------------------------------------------- 1 | from distutils import log 2 | from distutils.command import upload as orig 3 | 4 | from setuptools.errors import RemovedCommandError 5 | 6 | 7 | class upload(orig.upload): 8 | """Formerly used to upload packages to PyPI.""" 9 | 10 | def run(self): 11 | msg = ( 12 | "The upload command has been removed, use twine to upload " 13 | + "instead (https://pypi.org/p/twine)" 14 | ) 15 | 16 | self.announce("ERROR: " + msg, log.ERROR) 17 | raise RemovedCommandError(msg) 18 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/command/upload_docs.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """upload_docs 3 | 4 | Implements a Distutils 'upload_docs' subcommand (upload documentation to 5 | PyPI's pythonhosted.org). 6 | """ 7 | 8 | from base64 import standard_b64encode 9 | from distutils import log 10 | from distutils.errors import DistutilsOptionError 11 | import os 12 | import socket 13 | import zipfile 14 | import tempfile 15 | import shutil 16 | import itertools 17 | import functools 18 | 19 | from setuptools.extern import six 20 | from setuptools.extern.six.moves import http_client, urllib 21 | 22 | from pkg_resources import iter_entry_points 23 | from .upload import upload 24 | 25 | 26 | def _encode(s): 27 | errors = 'strict' if six.PY2 else 'surrogateescape' 28 | return s.encode('utf-8', errors) 29 | 30 | 31 | class upload_docs(upload): 32 | # override the default repository as upload_docs isn't 33 | # supported by Warehouse (and won't be). 34 | DEFAULT_REPOSITORY = 'https://pypi.python.org/pypi/' 35 | 36 | description = 'Upload documentation to PyPI' 37 | 38 | user_options = [ 39 | ('repository=', 'r', 40 | "url of repository [default: %s]" % upload.DEFAULT_REPOSITORY), 41 | ('show-response', None, 42 | 'display full response text from server'), 43 | ('upload-dir=', None, 'directory to upload'), 44 | ] 45 | boolean_options = upload.boolean_options 46 | 47 | def has_sphinx(self): 48 | if self.upload_dir is None: 49 | for ep in iter_entry_points('distutils.commands', 'build_sphinx'): 50 | return True 51 | 52 | sub_commands = [('build_sphinx', has_sphinx)] 53 | 54 | def initialize_options(self): 55 | upload.initialize_options(self) 56 | self.upload_dir = None 57 | self.target_dir = None 58 | 59 | def finalize_options(self): 60 | upload.finalize_options(self) 61 | if self.upload_dir is None: 62 | if self.has_sphinx(): 63 | build_sphinx = self.get_finalized_command('build_sphinx') 64 | self.target_dir = build_sphinx.builder_target_dir 65 | else: 66 | build = self.get_finalized_command('build') 67 | self.target_dir = os.path.join(build.build_base, 'docs') 68 | else: 69 | self.ensure_dirname('upload_dir') 70 | self.target_dir = self.upload_dir 71 | if 'pypi.python.org' in self.repository: 72 | log.warn("Upload_docs command is deprecated. Use RTD instead.") 73 | self.announce('Using upload directory %s' % self.target_dir) 74 | 75 | def create_zipfile(self, filename): 76 | zip_file = zipfile.ZipFile(filename, "w") 77 | try: 78 | self.mkpath(self.target_dir) # just in case 79 | for root, dirs, files in os.walk(self.target_dir): 80 | if root == self.target_dir and not files: 81 | tmpl = "no files found in upload directory '%s'" 82 | raise DistutilsOptionError(tmpl % self.target_dir) 83 | for name in files: 84 | full = os.path.join(root, name) 85 | relative = root[len(self.target_dir):].lstrip(os.path.sep) 86 | dest = os.path.join(relative, name) 87 | zip_file.write(full, dest) 88 | finally: 89 | zip_file.close() 90 | 91 | def run(self): 92 | # Run sub commands 93 | for cmd_name in self.get_sub_commands(): 94 | self.run_command(cmd_name) 95 | 96 | tmp_dir = tempfile.mkdtemp() 97 | name = self.distribution.metadata.get_name() 98 | zip_file = os.path.join(tmp_dir, "%s.zip" % name) 99 | try: 100 | self.create_zipfile(zip_file) 101 | self.upload_file(zip_file) 102 | finally: 103 | shutil.rmtree(tmp_dir) 104 | 105 | @staticmethod 106 | def _build_part(item, sep_boundary): 107 | key, values = item 108 | title = '\nContent-Disposition: form-data; name="%s"' % key 109 | # handle multiple entries for the same name 110 | if not isinstance(values, list): 111 | values = [values] 112 | for value in values: 113 | if isinstance(value, tuple): 114 | title += '; filename="%s"' % value[0] 115 | value = value[1] 116 | else: 117 | value = _encode(value) 118 | yield sep_boundary 119 | yield _encode(title) 120 | yield b"\n\n" 121 | yield value 122 | if value and value[-1:] == b'\r': 123 | yield b'\n' # write an extra newline (lurve Macs) 124 | 125 | @classmethod 126 | def _build_multipart(cls, data): 127 | """ 128 | Build up the MIME payload for the POST data 129 | """ 130 | boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254' 131 | sep_boundary = b'\n--' + boundary.encode('ascii') 132 | end_boundary = sep_boundary + b'--' 133 | end_items = end_boundary, b"\n", 134 | builder = functools.partial( 135 | cls._build_part, 136 | sep_boundary=sep_boundary, 137 | ) 138 | part_groups = map(builder, data.items()) 139 | parts = itertools.chain.from_iterable(part_groups) 140 | body_items = itertools.chain(parts, end_items) 141 | content_type = 'multipart/form-data; boundary=%s' % boundary 142 | return b''.join(body_items), content_type 143 | 144 | def upload_file(self, filename): 145 | with open(filename, 'rb') as f: 146 | content = f.read() 147 | meta = self.distribution.metadata 148 | data = { 149 | ':action': 'doc_upload', 150 | 'name': meta.get_name(), 151 | 'content': (os.path.basename(filename), content), 152 | } 153 | # set up the authentication 154 | credentials = _encode(self.username + ':' + self.password) 155 | credentials = standard_b64encode(credentials) 156 | if not six.PY2: 157 | credentials = credentials.decode('ascii') 158 | auth = "Basic " + credentials 159 | 160 | body, ct = self._build_multipart(data) 161 | 162 | msg = "Submitting documentation to %s" % (self.repository) 163 | self.announce(msg, log.INFO) 164 | 165 | # build the Request 166 | # We can't use urllib2 since we need to send the Basic 167 | # auth right with the first request 168 | schema, netloc, url, params, query, fragments = \ 169 | urllib.parse.urlparse(self.repository) 170 | assert not params and not query and not fragments 171 | if schema == 'http': 172 | conn = http_client.HTTPConnection(netloc) 173 | elif schema == 'https': 174 | conn = http_client.HTTPSConnection(netloc) 175 | else: 176 | raise AssertionError("unsupported schema " + schema) 177 | 178 | data = '' 179 | try: 180 | conn.connect() 181 | conn.putrequest("POST", url) 182 | content_type = ct 183 | conn.putheader('Content-type', content_type) 184 | conn.putheader('Content-length', str(len(body))) 185 | conn.putheader('Authorization', auth) 186 | conn.endheaders() 187 | conn.send(body) 188 | except socket.error as e: 189 | self.announce(str(e), log.ERROR) 190 | return 191 | 192 | r = conn.getresponse() 193 | if r.status == 200: 194 | msg = 'Server response (%s): %s' % (r.status, r.reason) 195 | self.announce(msg, log.INFO) 196 | elif r.status == 301: 197 | location = r.getheader('Location') 198 | if location is None: 199 | location = 'https://pythonhosted.org/%s/' % meta.get_name() 200 | msg = 'Upload successful. Visit %s' % location 201 | self.announce(msg, log.INFO) 202 | else: 203 | msg = 'Upload failed (%s): %s' % (r.status, r.reason) 204 | self.announce(msg, log.ERROR) 205 | if self.show_response: 206 | print('-' * 75, r.read(), '-' * 75) 207 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/dep_util.py: -------------------------------------------------------------------------------- 1 | from distutils.dep_util import newer_group 2 | 3 | 4 | # yes, this is was almost entirely copy-pasted from 5 | # 'newer_pairwise()', this is just another convenience 6 | # function. 7 | def newer_pairwise_group(sources_groups, targets): 8 | """Walk both arguments in parallel, testing if each source group is newer 9 | than its corresponding target. Returns a pair of lists (sources_groups, 10 | targets) where sources is newer than target, according to the semantics 11 | of 'newer_group()'. 12 | """ 13 | if len(sources_groups) != len(targets): 14 | raise ValueError( 15 | "'sources_group' and 'targets' must be the same length") 16 | 17 | # build a pair of lists (sources_groups, targets) where source is newer 18 | n_sources = [] 19 | n_targets = [] 20 | for i in range(len(sources_groups)): 21 | if newer_group(sources_groups[i], targets[i]): 22 | n_sources.append(sources_groups[i]) 23 | n_targets.append(targets[i]) 24 | 25 | return n_sources, n_targets 26 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/depends.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import marshal 3 | import contextlib 4 | from distutils.version import StrictVersion 5 | 6 | from .py33compat import Bytecode 7 | 8 | from .py27compat import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE 9 | from . import py27compat 10 | 11 | 12 | __all__ = [ 13 | 'Require', 'find_module', 'get_module_constant', 'extract_constant' 14 | ] 15 | 16 | 17 | class Require: 18 | """A prerequisite to building or installing a distribution""" 19 | 20 | def __init__( 21 | self, name, requested_version, module, homepage='', 22 | attribute=None, format=None): 23 | 24 | if format is None and requested_version is not None: 25 | format = StrictVersion 26 | 27 | if format is not None: 28 | requested_version = format(requested_version) 29 | if attribute is None: 30 | attribute = '__version__' 31 | 32 | self.__dict__.update(locals()) 33 | del self.self 34 | 35 | def full_name(self): 36 | """Return full package/distribution name, w/version""" 37 | if self.requested_version is not None: 38 | return '%s-%s' % (self.name, self.requested_version) 39 | return self.name 40 | 41 | def version_ok(self, version): 42 | """Is 'version' sufficiently up-to-date?""" 43 | return self.attribute is None or self.format is None or \ 44 | str(version) != "unknown" and version >= self.requested_version 45 | 46 | def get_version(self, paths=None, default="unknown"): 47 | """Get version number of installed module, 'None', or 'default' 48 | 49 | Search 'paths' for module. If not found, return 'None'. If found, 50 | return the extracted version attribute, or 'default' if no version 51 | attribute was specified, or the value cannot be determined without 52 | importing the module. The version is formatted according to the 53 | requirement's version format (if any), unless it is 'None' or the 54 | supplied 'default'. 55 | """ 56 | 57 | if self.attribute is None: 58 | try: 59 | f, p, i = find_module(self.module, paths) 60 | if f: 61 | f.close() 62 | return default 63 | except ImportError: 64 | return None 65 | 66 | v = get_module_constant(self.module, self.attribute, default, paths) 67 | 68 | if v is not None and v is not default and self.format is not None: 69 | return self.format(v) 70 | 71 | return v 72 | 73 | def is_present(self, paths=None): 74 | """Return true if dependency is present on 'paths'""" 75 | return self.get_version(paths) is not None 76 | 77 | def is_current(self, paths=None): 78 | """Return true if dependency is present and up-to-date on 'paths'""" 79 | version = self.get_version(paths) 80 | if version is None: 81 | return False 82 | return self.version_ok(version) 83 | 84 | 85 | def maybe_close(f): 86 | @contextlib.contextmanager 87 | def empty(): 88 | yield 89 | return 90 | if not f: 91 | return empty() 92 | 93 | return contextlib.closing(f) 94 | 95 | 96 | def get_module_constant(module, symbol, default=-1, paths=None): 97 | """Find 'module' by searching 'paths', and extract 'symbol' 98 | 99 | Return 'None' if 'module' does not exist on 'paths', or it does not define 100 | 'symbol'. If the module defines 'symbol' as a constant, return the 101 | constant. Otherwise, return 'default'.""" 102 | 103 | try: 104 | f, path, (suffix, mode, kind) = info = find_module(module, paths) 105 | except ImportError: 106 | # Module doesn't exist 107 | return None 108 | 109 | with maybe_close(f): 110 | if kind == PY_COMPILED: 111 | f.read(8) # skip magic & date 112 | code = marshal.load(f) 113 | elif kind == PY_FROZEN: 114 | code = py27compat.get_frozen_object(module, paths) 115 | elif kind == PY_SOURCE: 116 | code = compile(f.read(), path, 'exec') 117 | else: 118 | # Not something we can parse; we'll have to import it. :( 119 | imported = py27compat.get_module(module, paths, info) 120 | return getattr(imported, symbol, None) 121 | 122 | return extract_constant(code, symbol, default) 123 | 124 | 125 | def extract_constant(code, symbol, default=-1): 126 | """Extract the constant value of 'symbol' from 'code' 127 | 128 | If the name 'symbol' is bound to a constant value by the Python code 129 | object 'code', return that value. If 'symbol' is bound to an expression, 130 | return 'default'. Otherwise, return 'None'. 131 | 132 | Return value is based on the first assignment to 'symbol'. 'symbol' must 133 | be a global, or at least a non-"fast" local in the code block. That is, 134 | only 'STORE_NAME' and 'STORE_GLOBAL' opcodes are checked, and 'symbol' 135 | must be present in 'code.co_names'. 136 | """ 137 | if symbol not in code.co_names: 138 | # name's not there, can't possibly be an assignment 139 | return None 140 | 141 | name_idx = list(code.co_names).index(symbol) 142 | 143 | STORE_NAME = 90 144 | STORE_GLOBAL = 97 145 | LOAD_CONST = 100 146 | 147 | const = default 148 | 149 | for byte_code in Bytecode(code): 150 | op = byte_code.opcode 151 | arg = byte_code.arg 152 | 153 | if op == LOAD_CONST: 154 | const = code.co_consts[arg] 155 | elif arg == name_idx and (op == STORE_NAME or op == STORE_GLOBAL): 156 | return const 157 | else: 158 | const = default 159 | 160 | 161 | def _update_globals(): 162 | """ 163 | Patch the globals to remove the objects not available on some platforms. 164 | 165 | XXX it'd be better to test assertions about bytecode instead. 166 | """ 167 | 168 | if not sys.platform.startswith('java') and sys.platform != 'cli': 169 | return 170 | incompatible = 'extract_constant', 'get_module_constant' 171 | for name in incompatible: 172 | del globals()[name] 173 | __all__.remove(name) 174 | 175 | 176 | _update_globals() 177 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/errors.py: -------------------------------------------------------------------------------- 1 | """setuptools.errors 2 | 3 | Provides exceptions used by setuptools modules. 4 | """ 5 | 6 | from distutils.errors import DistutilsError 7 | 8 | 9 | class RemovedCommandError(DistutilsError, RuntimeError): 10 | """Error used for commands that have been removed in setuptools. 11 | 12 | Since ``setuptools`` is built on ``distutils``, simply removing a command 13 | from ``setuptools`` will make the behavior fall back to ``distutils``; this 14 | error is raised if a command exists in ``distutils`` but has been actively 15 | removed in ``setuptools``. 16 | """ 17 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/extension.py: -------------------------------------------------------------------------------- 1 | import re 2 | import functools 3 | import distutils.core 4 | import distutils.errors 5 | import distutils.extension 6 | 7 | from setuptools.extern.six.moves import map 8 | 9 | from .monkey import get_unpatched 10 | 11 | 12 | def _have_cython(): 13 | """ 14 | Return True if Cython can be imported. 15 | """ 16 | cython_impl = 'Cython.Distutils.build_ext' 17 | try: 18 | # from (cython_impl) import build_ext 19 | __import__(cython_impl, fromlist=['build_ext']).build_ext 20 | return True 21 | except Exception: 22 | pass 23 | return False 24 | 25 | 26 | # for compatibility 27 | have_pyrex = _have_cython 28 | 29 | _Extension = get_unpatched(distutils.core.Extension) 30 | 31 | 32 | class Extension(_Extension): 33 | """Extension that uses '.c' files in place of '.pyx' files""" 34 | 35 | def __init__(self, name, sources, *args, **kw): 36 | # The *args is needed for compatibility as calls may use positional 37 | # arguments. py_limited_api may be set only via keyword. 38 | self.py_limited_api = kw.pop("py_limited_api", False) 39 | _Extension.__init__(self, name, sources, *args, **kw) 40 | 41 | def _convert_pyx_sources_to_lang(self): 42 | """ 43 | Replace sources with .pyx extensions to sources with the target 44 | language extension. This mechanism allows language authors to supply 45 | pre-converted sources but to prefer the .pyx sources. 46 | """ 47 | if _have_cython(): 48 | # the build has Cython, so allow it to compile the .pyx files 49 | return 50 | lang = self.language or '' 51 | target_ext = '.cpp' if lang.lower() == 'c++' else '.c' 52 | sub = functools.partial(re.sub, '.pyx$', target_ext) 53 | self.sources = list(map(sub, self.sources)) 54 | 55 | 56 | class Library(Extension): 57 | """Just like a regular Extension, but built as a library instead""" 58 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/extern/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | class VendorImporter: 5 | """ 6 | A PEP 302 meta path importer for finding optionally-vendored 7 | or otherwise naturally-installed packages from root_name. 8 | """ 9 | 10 | def __init__(self, root_name, vendored_names=(), vendor_pkg=None): 11 | self.root_name = root_name 12 | self.vendored_names = set(vendored_names) 13 | self.vendor_pkg = vendor_pkg or root_name.replace('extern', '_vendor') 14 | 15 | @property 16 | def search_path(self): 17 | """ 18 | Search first the vendor package then as a natural package. 19 | """ 20 | yield self.vendor_pkg + '.' 21 | yield '' 22 | 23 | def find_module(self, fullname, path=None): 24 | """ 25 | Return self when fullname starts with root_name and the 26 | target module is one vendored through this importer. 27 | """ 28 | root, base, target = fullname.partition(self.root_name + '.') 29 | if root: 30 | return 31 | if not any(map(target.startswith, self.vendored_names)): 32 | return 33 | return self 34 | 35 | def load_module(self, fullname): 36 | """ 37 | Iterate over the search path to locate and load fullname. 38 | """ 39 | root, base, target = fullname.partition(self.root_name + '.') 40 | for prefix in self.search_path: 41 | try: 42 | extant = prefix + target 43 | __import__(extant) 44 | mod = sys.modules[extant] 45 | sys.modules[fullname] = mod 46 | return mod 47 | except ImportError: 48 | pass 49 | else: 50 | raise ImportError( 51 | "The '{target}' package is required; " 52 | "normally this is bundled with this package so if you get " 53 | "this warning, consult the packager of your " 54 | "distribution.".format(**locals()) 55 | ) 56 | 57 | def install(self): 58 | """ 59 | Install this importer into sys.meta_path if not already present. 60 | """ 61 | if self not in sys.meta_path: 62 | sys.meta_path.append(self) 63 | 64 | 65 | names = 'six', 'packaging', 'pyparsing', 'ordered_set', 66 | VendorImporter(__name__, names, 'setuptools._vendor').install() 67 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/glob.py: -------------------------------------------------------------------------------- 1 | """ 2 | Filename globbing utility. Mostly a copy of `glob` from Python 3.5. 3 | 4 | Changes include: 5 | * `yield from` and PEP3102 `*` removed. 6 | * Hidden files are not ignored. 7 | """ 8 | 9 | import os 10 | import re 11 | import fnmatch 12 | 13 | __all__ = ["glob", "iglob", "escape"] 14 | 15 | 16 | def glob(pathname, recursive=False): 17 | """Return a list of paths matching a pathname pattern. 18 | 19 | The pattern may contain simple shell-style wildcards a la 20 | fnmatch. However, unlike fnmatch, filenames starting with a 21 | dot are special cases that are not matched by '*' and '?' 22 | patterns. 23 | 24 | If recursive is true, the pattern '**' will match any files and 25 | zero or more directories and subdirectories. 26 | """ 27 | return list(iglob(pathname, recursive=recursive)) 28 | 29 | 30 | def iglob(pathname, recursive=False): 31 | """Return an iterator which yields the paths matching a pathname pattern. 32 | 33 | The pattern may contain simple shell-style wildcards a la 34 | fnmatch. However, unlike fnmatch, filenames starting with a 35 | dot are special cases that are not matched by '*' and '?' 36 | patterns. 37 | 38 | If recursive is true, the pattern '**' will match any files and 39 | zero or more directories and subdirectories. 40 | """ 41 | it = _iglob(pathname, recursive) 42 | if recursive and _isrecursive(pathname): 43 | s = next(it) # skip empty string 44 | assert not s 45 | return it 46 | 47 | 48 | def _iglob(pathname, recursive): 49 | dirname, basename = os.path.split(pathname) 50 | if not has_magic(pathname): 51 | if basename: 52 | if os.path.lexists(pathname): 53 | yield pathname 54 | else: 55 | # Patterns ending with a slash should match only directories 56 | if os.path.isdir(dirname): 57 | yield pathname 58 | return 59 | if not dirname: 60 | if recursive and _isrecursive(basename): 61 | for x in glob2(dirname, basename): 62 | yield x 63 | else: 64 | for x in glob1(dirname, basename): 65 | yield x 66 | return 67 | # `os.path.split()` returns the argument itself as a dirname if it is a 68 | # drive or UNC path. Prevent an infinite recursion if a drive or UNC path 69 | # contains magic characters (i.e. r'\\?\C:'). 70 | if dirname != pathname and has_magic(dirname): 71 | dirs = _iglob(dirname, recursive) 72 | else: 73 | dirs = [dirname] 74 | if has_magic(basename): 75 | if recursive and _isrecursive(basename): 76 | glob_in_dir = glob2 77 | else: 78 | glob_in_dir = glob1 79 | else: 80 | glob_in_dir = glob0 81 | for dirname in dirs: 82 | for name in glob_in_dir(dirname, basename): 83 | yield os.path.join(dirname, name) 84 | 85 | 86 | # These 2 helper functions non-recursively glob inside a literal directory. 87 | # They return a list of basenames. `glob1` accepts a pattern while `glob0` 88 | # takes a literal basename (so it only has to check for its existence). 89 | 90 | 91 | def glob1(dirname, pattern): 92 | if not dirname: 93 | if isinstance(pattern, bytes): 94 | dirname = os.curdir.encode('ASCII') 95 | else: 96 | dirname = os.curdir 97 | try: 98 | names = os.listdir(dirname) 99 | except OSError: 100 | return [] 101 | return fnmatch.filter(names, pattern) 102 | 103 | 104 | def glob0(dirname, basename): 105 | if not basename: 106 | # `os.path.split()` returns an empty basename for paths ending with a 107 | # directory separator. 'q*x/' should match only directories. 108 | if os.path.isdir(dirname): 109 | return [basename] 110 | else: 111 | if os.path.lexists(os.path.join(dirname, basename)): 112 | return [basename] 113 | return [] 114 | 115 | 116 | # This helper function recursively yields relative pathnames inside a literal 117 | # directory. 118 | 119 | 120 | def glob2(dirname, pattern): 121 | assert _isrecursive(pattern) 122 | yield pattern[:0] 123 | for x in _rlistdir(dirname): 124 | yield x 125 | 126 | 127 | # Recursively yields relative pathnames inside a literal directory. 128 | def _rlistdir(dirname): 129 | if not dirname: 130 | if isinstance(dirname, bytes): 131 | dirname = os.curdir.encode('ASCII') 132 | else: 133 | dirname = os.curdir 134 | try: 135 | names = os.listdir(dirname) 136 | except os.error: 137 | return 138 | for x in names: 139 | yield x 140 | path = os.path.join(dirname, x) if dirname else x 141 | for y in _rlistdir(path): 142 | yield os.path.join(x, y) 143 | 144 | 145 | magic_check = re.compile('([*?[])') 146 | magic_check_bytes = re.compile(b'([*?[])') 147 | 148 | 149 | def has_magic(s): 150 | if isinstance(s, bytes): 151 | match = magic_check_bytes.search(s) 152 | else: 153 | match = magic_check.search(s) 154 | return match is not None 155 | 156 | 157 | def _isrecursive(pattern): 158 | if isinstance(pattern, bytes): 159 | return pattern == b'**' 160 | else: 161 | return pattern == '**' 162 | 163 | 164 | def escape(pathname): 165 | """Escape all special characters. 166 | """ 167 | # Escaping is done by wrapping any of "*?[" between square brackets. 168 | # Metacharacters do not work in the drive part and shouldn't be escaped. 169 | drive, pathname = os.path.splitdrive(pathname) 170 | if isinstance(pathname, bytes): 171 | pathname = magic_check_bytes.sub(br'[\1]', pathname) 172 | else: 173 | pathname = magic_check.sub(r'[\1]', pathname) 174 | return drive + pathname 175 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/gui-32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/.eggs/setuptools-46.0.0-py3.6.egg/setuptools/gui-32.exe -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/gui-64.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/.eggs/setuptools-46.0.0-py3.6.egg/setuptools/gui-64.exe -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/gui.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/.eggs/setuptools-46.0.0-py3.6.egg/setuptools/gui.exe -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/installer.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import subprocess 4 | import sys 5 | from distutils import log 6 | from distutils.errors import DistutilsError 7 | 8 | import pkg_resources 9 | from setuptools.command.easy_install import easy_install 10 | from setuptools.extern import six 11 | from setuptools.wheel import Wheel 12 | 13 | from .py31compat import TemporaryDirectory 14 | 15 | 16 | def _fixup_find_links(find_links): 17 | """Ensure find-links option end-up being a list of strings.""" 18 | if isinstance(find_links, six.string_types): 19 | return find_links.split() 20 | assert isinstance(find_links, (tuple, list)) 21 | return find_links 22 | 23 | 24 | def _legacy_fetch_build_egg(dist, req): 25 | """Fetch an egg needed for building. 26 | 27 | Legacy path using EasyInstall. 28 | """ 29 | tmp_dist = dist.__class__({'script_args': ['easy_install']}) 30 | opts = tmp_dist.get_option_dict('easy_install') 31 | opts.clear() 32 | opts.update( 33 | (k, v) 34 | for k, v in dist.get_option_dict('easy_install').items() 35 | if k in ( 36 | # don't use any other settings 37 | 'find_links', 'site_dirs', 'index_url', 38 | 'optimize', 'site_dirs', 'allow_hosts', 39 | )) 40 | if dist.dependency_links: 41 | links = dist.dependency_links[:] 42 | if 'find_links' in opts: 43 | links = _fixup_find_links(opts['find_links'][1]) + links 44 | opts['find_links'] = ('setup', links) 45 | install_dir = dist.get_egg_cache_dir() 46 | cmd = easy_install( 47 | tmp_dist, args=["x"], install_dir=install_dir, 48 | exclude_scripts=True, 49 | always_copy=False, build_directory=None, editable=False, 50 | upgrade=False, multi_version=True, no_report=True, user=False 51 | ) 52 | cmd.ensure_finalized() 53 | return cmd.easy_install(req) 54 | 55 | 56 | def fetch_build_egg(dist, req): 57 | """Fetch an egg needed for building. 58 | 59 | Use pip/wheel to fetch/build a wheel.""" 60 | # Check pip is available. 61 | try: 62 | pkg_resources.get_distribution('pip') 63 | except pkg_resources.DistributionNotFound: 64 | dist.announce( 65 | 'WARNING: The pip package is not available, falling back ' 66 | 'to EasyInstall for handling setup_requires/test_requires; ' 67 | 'this is deprecated and will be removed in a future version.', 68 | log.WARN 69 | ) 70 | return _legacy_fetch_build_egg(dist, req) 71 | # Warn if wheel is not. 72 | try: 73 | pkg_resources.get_distribution('wheel') 74 | except pkg_resources.DistributionNotFound: 75 | dist.announce('WARNING: The wheel package is not available.', log.WARN) 76 | # Ignore environment markers; if supplied, it is required. 77 | req = strip_marker(req) 78 | # Take easy_install options into account, but do not override relevant 79 | # pip environment variables (like PIP_INDEX_URL or PIP_QUIET); they'll 80 | # take precedence. 81 | opts = dist.get_option_dict('easy_install') 82 | if 'allow_hosts' in opts: 83 | raise DistutilsError('the `allow-hosts` option is not supported ' 84 | 'when using pip to install requirements.') 85 | if 'PIP_QUIET' in os.environ or 'PIP_VERBOSE' in os.environ: 86 | quiet = False 87 | else: 88 | quiet = True 89 | if 'PIP_INDEX_URL' in os.environ: 90 | index_url = None 91 | elif 'index_url' in opts: 92 | index_url = opts['index_url'][1] 93 | else: 94 | index_url = None 95 | if 'find_links' in opts: 96 | find_links = _fixup_find_links(opts['find_links'][1])[:] 97 | else: 98 | find_links = [] 99 | if dist.dependency_links: 100 | find_links.extend(dist.dependency_links) 101 | eggs_dir = os.path.realpath(dist.get_egg_cache_dir()) 102 | environment = pkg_resources.Environment() 103 | for egg_dist in pkg_resources.find_distributions(eggs_dir): 104 | if egg_dist in req and environment.can_add(egg_dist): 105 | return egg_dist 106 | with TemporaryDirectory() as tmpdir: 107 | cmd = [ 108 | sys.executable, '-m', 'pip', 109 | '--disable-pip-version-check', 110 | 'wheel', '--no-deps', 111 | '-w', tmpdir, 112 | ] 113 | if quiet: 114 | cmd.append('--quiet') 115 | if index_url is not None: 116 | cmd.extend(('--index-url', index_url)) 117 | if find_links is not None: 118 | for link in find_links: 119 | cmd.extend(('--find-links', link)) 120 | # If requirement is a PEP 508 direct URL, directly pass 121 | # the URL to pip, as `req @ url` does not work on the 122 | # command line. 123 | if req.url: 124 | cmd.append(req.url) 125 | else: 126 | cmd.append(str(req)) 127 | try: 128 | subprocess.check_call(cmd) 129 | except subprocess.CalledProcessError as e: 130 | raise DistutilsError(str(e)) 131 | wheel = Wheel(glob.glob(os.path.join(tmpdir, '*.whl'))[0]) 132 | dist_location = os.path.join(eggs_dir, wheel.egg_name()) 133 | wheel.install_as_egg(dist_location) 134 | dist_metadata = pkg_resources.PathMetadata( 135 | dist_location, os.path.join(dist_location, 'EGG-INFO')) 136 | dist = pkg_resources.Distribution.from_filename( 137 | dist_location, metadata=dist_metadata) 138 | return dist 139 | 140 | 141 | def strip_marker(req): 142 | """ 143 | Return a new requirement without the environment marker to avoid 144 | calling pip with something like `babel; extra == "i18n"`, which 145 | would always be ignored. 146 | """ 147 | # create a copy to avoid mutating the input 148 | req = pkg_resources.Requirement.parse(str(req)) 149 | req.marker = None 150 | return req 151 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/launch.py: -------------------------------------------------------------------------------- 1 | """ 2 | Launch the Python script on the command line after 3 | setuptools is bootstrapped via import. 4 | """ 5 | 6 | # Note that setuptools gets imported implicitly by the 7 | # invocation of this script using python -m setuptools.launch 8 | 9 | import tokenize 10 | import sys 11 | 12 | 13 | def run(): 14 | """ 15 | Run the script in sys.argv[1] as if it had 16 | been invoked naturally. 17 | """ 18 | __builtins__ 19 | script_name = sys.argv[1] 20 | namespace = dict( 21 | __file__=script_name, 22 | __name__='__main__', 23 | __doc__=None, 24 | ) 25 | sys.argv[:] = sys.argv[1:] 26 | 27 | open_ = getattr(tokenize, 'open', open) 28 | script = open_(script_name).read() 29 | norm_script = script.replace('\\r\\n', '\\n') 30 | code = compile(norm_script, script_name, 'exec') 31 | exec(code, namespace) 32 | 33 | 34 | if __name__ == '__main__': 35 | run() 36 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/lib2to3_ex.py: -------------------------------------------------------------------------------- 1 | """ 2 | Customized Mixin2to3 support: 3 | 4 | - adds support for converting doctests 5 | 6 | 7 | This module raises an ImportError on Python 2. 8 | """ 9 | 10 | from distutils.util import Mixin2to3 as _Mixin2to3 11 | from distutils import log 12 | from lib2to3.refactor import RefactoringTool, get_fixers_from_package 13 | 14 | import setuptools 15 | 16 | 17 | class DistutilsRefactoringTool(RefactoringTool): 18 | def log_error(self, msg, *args, **kw): 19 | log.error(msg, *args) 20 | 21 | def log_message(self, msg, *args): 22 | log.info(msg, *args) 23 | 24 | def log_debug(self, msg, *args): 25 | log.debug(msg, *args) 26 | 27 | 28 | class Mixin2to3(_Mixin2to3): 29 | def run_2to3(self, files, doctests=False): 30 | # See of the distribution option has been set, otherwise check the 31 | # setuptools default. 32 | if self.distribution.use_2to3 is not True: 33 | return 34 | if not files: 35 | return 36 | log.info("Fixing " + " ".join(files)) 37 | self.__build_fixer_names() 38 | self.__exclude_fixers() 39 | if doctests: 40 | if setuptools.run_2to3_on_doctests: 41 | r = DistutilsRefactoringTool(self.fixer_names) 42 | r.refactor(files, write=True, doctests_only=True) 43 | else: 44 | _Mixin2to3.run_2to3(self, files) 45 | 46 | def __build_fixer_names(self): 47 | if self.fixer_names: 48 | return 49 | self.fixer_names = [] 50 | for p in setuptools.lib2to3_fixer_packages: 51 | self.fixer_names.extend(get_fixers_from_package(p)) 52 | if self.distribution.use_2to3_fixers is not None: 53 | for p in self.distribution.use_2to3_fixers: 54 | self.fixer_names.extend(get_fixers_from_package(p)) 55 | 56 | def __exclude_fixers(self): 57 | excluded_fixers = getattr(self, 'exclude_fixers', []) 58 | if self.distribution.use_2to3_exclude_fixers is not None: 59 | excluded_fixers.extend(self.distribution.use_2to3_exclude_fixers) 60 | for fixer_name in excluded_fixers: 61 | if fixer_name in self.fixer_names: 62 | self.fixer_names.remove(fixer_name) 63 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/monkey.py: -------------------------------------------------------------------------------- 1 | """ 2 | Monkey patching of distutils. 3 | """ 4 | 5 | import sys 6 | import distutils.filelist 7 | import platform 8 | import types 9 | import functools 10 | from importlib import import_module 11 | import inspect 12 | 13 | from setuptools.extern import six 14 | 15 | import setuptools 16 | 17 | __all__ = [] 18 | """ 19 | Everything is private. Contact the project team 20 | if you think you need this functionality. 21 | """ 22 | 23 | 24 | def _get_mro(cls): 25 | """ 26 | Returns the bases classes for cls sorted by the MRO. 27 | 28 | Works around an issue on Jython where inspect.getmro will not return all 29 | base classes if multiple classes share the same name. Instead, this 30 | function will return a tuple containing the class itself, and the contents 31 | of cls.__bases__. See https://github.com/pypa/setuptools/issues/1024. 32 | """ 33 | if platform.python_implementation() == "Jython": 34 | return (cls,) + cls.__bases__ 35 | return inspect.getmro(cls) 36 | 37 | 38 | def get_unpatched(item): 39 | lookup = ( 40 | get_unpatched_class if isinstance(item, six.class_types) else 41 | get_unpatched_function if isinstance(item, types.FunctionType) else 42 | lambda item: None 43 | ) 44 | return lookup(item) 45 | 46 | 47 | def get_unpatched_class(cls): 48 | """Protect against re-patching the distutils if reloaded 49 | 50 | Also ensures that no other distutils extension monkeypatched the distutils 51 | first. 52 | """ 53 | external_bases = ( 54 | cls 55 | for cls in _get_mro(cls) 56 | if not cls.__module__.startswith('setuptools') 57 | ) 58 | base = next(external_bases) 59 | if not base.__module__.startswith('distutils'): 60 | msg = "distutils has already been patched by %r" % cls 61 | raise AssertionError(msg) 62 | return base 63 | 64 | 65 | def patch_all(): 66 | # we can't patch distutils.cmd, alas 67 | distutils.core.Command = setuptools.Command 68 | 69 | has_issue_12885 = sys.version_info <= (3, 5, 3) 70 | 71 | if has_issue_12885: 72 | # fix findall bug in distutils (http://bugs.python.org/issue12885) 73 | distutils.filelist.findall = setuptools.findall 74 | 75 | needs_warehouse = ( 76 | sys.version_info < (2, 7, 13) 77 | or 78 | (3, 4) < sys.version_info < (3, 4, 6) 79 | or 80 | (3, 5) < sys.version_info <= (3, 5, 3) 81 | ) 82 | 83 | if needs_warehouse: 84 | warehouse = 'https://upload.pypi.org/legacy/' 85 | distutils.config.PyPIRCCommand.DEFAULT_REPOSITORY = warehouse 86 | 87 | _patch_distribution_metadata() 88 | 89 | # Install Distribution throughout the distutils 90 | for module in distutils.dist, distutils.core, distutils.cmd: 91 | module.Distribution = setuptools.dist.Distribution 92 | 93 | # Install the patched Extension 94 | distutils.core.Extension = setuptools.extension.Extension 95 | distutils.extension.Extension = setuptools.extension.Extension 96 | if 'distutils.command.build_ext' in sys.modules: 97 | sys.modules['distutils.command.build_ext'].Extension = ( 98 | setuptools.extension.Extension 99 | ) 100 | 101 | patch_for_msvc_specialized_compiler() 102 | 103 | 104 | def _patch_distribution_metadata(): 105 | """Patch write_pkg_file and read_pkg_file for higher metadata standards""" 106 | for attr in ('write_pkg_file', 'read_pkg_file', 'get_metadata_version'): 107 | new_val = getattr(setuptools.dist, attr) 108 | setattr(distutils.dist.DistributionMetadata, attr, new_val) 109 | 110 | 111 | def patch_func(replacement, target_mod, func_name): 112 | """ 113 | Patch func_name in target_mod with replacement 114 | 115 | Important - original must be resolved by name to avoid 116 | patching an already patched function. 117 | """ 118 | original = getattr(target_mod, func_name) 119 | 120 | # set the 'unpatched' attribute on the replacement to 121 | # point to the original. 122 | vars(replacement).setdefault('unpatched', original) 123 | 124 | # replace the function in the original module 125 | setattr(target_mod, func_name, replacement) 126 | 127 | 128 | def get_unpatched_function(candidate): 129 | return getattr(candidate, 'unpatched') 130 | 131 | 132 | def patch_for_msvc_specialized_compiler(): 133 | """ 134 | Patch functions in distutils to use standalone Microsoft Visual C++ 135 | compilers. 136 | """ 137 | # import late to avoid circular imports on Python < 3.5 138 | msvc = import_module('setuptools.msvc') 139 | 140 | if platform.system() != 'Windows': 141 | # Compilers only availables on Microsoft Windows 142 | return 143 | 144 | def patch_params(mod_name, func_name): 145 | """ 146 | Prepare the parameters for patch_func to patch indicated function. 147 | """ 148 | repl_prefix = 'msvc9_' if 'msvc9' in mod_name else 'msvc14_' 149 | repl_name = repl_prefix + func_name.lstrip('_') 150 | repl = getattr(msvc, repl_name) 151 | mod = import_module(mod_name) 152 | if not hasattr(mod, func_name): 153 | raise ImportError(func_name) 154 | return repl, mod, func_name 155 | 156 | # Python 2.7 to 3.4 157 | msvc9 = functools.partial(patch_params, 'distutils.msvc9compiler') 158 | 159 | # Python 3.5+ 160 | msvc14 = functools.partial(patch_params, 'distutils._msvccompiler') 161 | 162 | try: 163 | # Patch distutils.msvc9compiler 164 | patch_func(*msvc9('find_vcvarsall')) 165 | patch_func(*msvc9('query_vcvarsall')) 166 | except ImportError: 167 | pass 168 | 169 | try: 170 | # Patch distutils._msvccompiler._get_vc_env 171 | patch_func(*msvc14('_get_vc_env')) 172 | except ImportError: 173 | pass 174 | 175 | try: 176 | # Patch distutils._msvccompiler.gen_lib_options for Numpy 177 | patch_func(*msvc14('gen_lib_options')) 178 | except ImportError: 179 | pass 180 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/namespaces.py: -------------------------------------------------------------------------------- 1 | import os 2 | from distutils import log 3 | import itertools 4 | 5 | from setuptools.extern.six.moves import map 6 | 7 | 8 | flatten = itertools.chain.from_iterable 9 | 10 | 11 | class Installer: 12 | 13 | nspkg_ext = '-nspkg.pth' 14 | 15 | def install_namespaces(self): 16 | nsp = self._get_all_ns_packages() 17 | if not nsp: 18 | return 19 | filename, ext = os.path.splitext(self._get_target()) 20 | filename += self.nspkg_ext 21 | self.outputs.append(filename) 22 | log.info("Installing %s", filename) 23 | lines = map(self._gen_nspkg_line, nsp) 24 | 25 | if self.dry_run: 26 | # always generate the lines, even in dry run 27 | list(lines) 28 | return 29 | 30 | with open(filename, 'wt') as f: 31 | f.writelines(lines) 32 | 33 | def uninstall_namespaces(self): 34 | filename, ext = os.path.splitext(self._get_target()) 35 | filename += self.nspkg_ext 36 | if not os.path.exists(filename): 37 | return 38 | log.info("Removing %s", filename) 39 | os.remove(filename) 40 | 41 | def _get_target(self): 42 | return self.target 43 | 44 | _nspkg_tmpl = ( 45 | "import sys, types, os", 46 | "has_mfs = sys.version_info > (3, 5)", 47 | "p = os.path.join(%(root)s, *%(pth)r)", 48 | "importlib = has_mfs and __import__('importlib.util')", 49 | "has_mfs and __import__('importlib.machinery')", 50 | ( 51 | "m = has_mfs and " 52 | "sys.modules.setdefault(%(pkg)r, " 53 | "importlib.util.module_from_spec(" 54 | "importlib.machinery.PathFinder.find_spec(%(pkg)r, " 55 | "[os.path.dirname(p)])))" 56 | ), 57 | ( 58 | "m = m or " 59 | "sys.modules.setdefault(%(pkg)r, types.ModuleType(%(pkg)r))" 60 | ), 61 | "mp = (m or []) and m.__dict__.setdefault('__path__',[])", 62 | "(p not in mp) and mp.append(p)", 63 | ) 64 | "lines for the namespace installer" 65 | 66 | _nspkg_tmpl_multi = ( 67 | 'm and setattr(sys.modules[%(parent)r], %(child)r, m)', 68 | ) 69 | "additional line(s) when a parent package is indicated" 70 | 71 | def _get_root(self): 72 | return "sys._getframe(1).f_locals['sitedir']" 73 | 74 | def _gen_nspkg_line(self, pkg): 75 | # ensure pkg is not a unicode string under Python 2.7 76 | pkg = str(pkg) 77 | pth = tuple(pkg.split('.')) 78 | root = self._get_root() 79 | tmpl_lines = self._nspkg_tmpl 80 | parent, sep, child = pkg.rpartition('.') 81 | if parent: 82 | tmpl_lines += self._nspkg_tmpl_multi 83 | return ';'.join(tmpl_lines) % locals() + '\n' 84 | 85 | def _get_all_ns_packages(self): 86 | """Return sorted list of all package namespaces""" 87 | pkgs = self.distribution.namespace_packages or [] 88 | return sorted(flatten(map(self._pkg_names, pkgs))) 89 | 90 | @staticmethod 91 | def _pkg_names(pkg): 92 | """ 93 | Given a namespace package, yield the components of that 94 | package. 95 | 96 | >>> names = Installer._pkg_names('a.b.c') 97 | >>> set(names) == set(['a', 'a.b', 'a.b.c']) 98 | True 99 | """ 100 | parts = pkg.split('.') 101 | while parts: 102 | yield '.'.join(parts) 103 | parts.pop() 104 | 105 | 106 | class DevelopInstaller(Installer): 107 | def _get_root(self): 108 | return repr(str(self.egg_path)) 109 | 110 | def _get_target(self): 111 | return self.egg_link 112 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/py27compat.py: -------------------------------------------------------------------------------- 1 | """ 2 | Compatibility Support for Python 2.7 and earlier 3 | """ 4 | 5 | import sys 6 | import platform 7 | 8 | from setuptools.extern import six 9 | 10 | 11 | def get_all_headers(message, key): 12 | """ 13 | Given an HTTPMessage, return all headers matching a given key. 14 | """ 15 | return message.get_all(key) 16 | 17 | 18 | if six.PY2: 19 | def get_all_headers(message, key): # noqa 20 | return message.getheaders(key) 21 | 22 | 23 | linux_py2_ascii = ( 24 | platform.system() == 'Linux' and 25 | six.PY2 26 | ) 27 | 28 | rmtree_safe = str if linux_py2_ascii else lambda x: x 29 | """Workaround for http://bugs.python.org/issue24672""" 30 | 31 | 32 | try: 33 | from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE 34 | from ._imp import get_frozen_object, get_module 35 | except ImportError: 36 | import imp 37 | from imp import PY_COMPILED, PY_FROZEN, PY_SOURCE # noqa 38 | 39 | def find_module(module, paths=None): 40 | """Just like 'imp.find_module()', but with package support""" 41 | parts = module.split('.') 42 | while parts: 43 | part = parts.pop(0) 44 | f, path, (suffix, mode, kind) = info = imp.find_module(part, paths) 45 | 46 | if kind == imp.PKG_DIRECTORY: 47 | parts = parts or ['__init__'] 48 | paths = [path] 49 | 50 | elif parts: 51 | raise ImportError("Can't find %r in %s" % (parts, module)) 52 | 53 | return info 54 | 55 | def get_frozen_object(module, paths): 56 | return imp.get_frozen_object(module) 57 | 58 | def get_module(module, paths, info): 59 | imp.load_module(module, *info) 60 | return sys.modules[module] 61 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/py31compat.py: -------------------------------------------------------------------------------- 1 | __all__ = [] 2 | 3 | __metaclass__ = type 4 | 5 | 6 | try: 7 | # Python >=3.2 8 | from tempfile import TemporaryDirectory 9 | except ImportError: 10 | import shutil 11 | import tempfile 12 | 13 | class TemporaryDirectory: 14 | """ 15 | Very simple temporary directory context manager. 16 | Will try to delete afterward, but will also ignore OS and similar 17 | errors on deletion. 18 | """ 19 | 20 | def __init__(self, **kwargs): 21 | self.name = None # Handle mkdtemp raising an exception 22 | self.name = tempfile.mkdtemp(**kwargs) 23 | 24 | def __enter__(self): 25 | return self.name 26 | 27 | def __exit__(self, exctype, excvalue, exctrace): 28 | try: 29 | shutil.rmtree(self.name, True) 30 | except OSError: # removal errors are not the only possible 31 | pass 32 | self.name = None 33 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/py33compat.py: -------------------------------------------------------------------------------- 1 | import dis 2 | import array 3 | import collections 4 | 5 | try: 6 | import html 7 | except ImportError: 8 | html = None 9 | 10 | from setuptools.extern import six 11 | from setuptools.extern.six.moves import html_parser 12 | 13 | __metaclass__ = type 14 | 15 | OpArg = collections.namedtuple('OpArg', 'opcode arg') 16 | 17 | 18 | class Bytecode_compat: 19 | def __init__(self, code): 20 | self.code = code 21 | 22 | def __iter__(self): 23 | """Yield '(op,arg)' pair for each operation in code object 'code'""" 24 | 25 | bytes = array.array('b', self.code.co_code) 26 | eof = len(self.code.co_code) 27 | 28 | ptr = 0 29 | extended_arg = 0 30 | 31 | while ptr < eof: 32 | 33 | op = bytes[ptr] 34 | 35 | if op >= dis.HAVE_ARGUMENT: 36 | 37 | arg = bytes[ptr + 1] + bytes[ptr + 2] * 256 + extended_arg 38 | ptr += 3 39 | 40 | if op == dis.EXTENDED_ARG: 41 | long_type = six.integer_types[-1] 42 | extended_arg = arg * long_type(65536) 43 | continue 44 | 45 | else: 46 | arg = None 47 | ptr += 1 48 | 49 | yield OpArg(op, arg) 50 | 51 | 52 | Bytecode = getattr(dis, 'Bytecode', Bytecode_compat) 53 | 54 | 55 | unescape = getattr(html, 'unescape', None) 56 | if unescape is None: 57 | # HTMLParser.unescape is deprecated since Python 3.4, and will be removed 58 | # from 3.9. 59 | unescape = html_parser.HTMLParser().unescape 60 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/py34compat.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | 3 | try: 4 | import importlib.util 5 | except ImportError: 6 | pass 7 | 8 | 9 | try: 10 | module_from_spec = importlib.util.module_from_spec 11 | except AttributeError: 12 | def module_from_spec(spec): 13 | return spec.loader.load_module(spec.name) 14 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/script (dev).tmpl: -------------------------------------------------------------------------------- 1 | # EASY-INSTALL-DEV-SCRIPT: %(spec)r,%(script_name)r 2 | __requires__ = %(spec)r 3 | __import__('pkg_resources').require(%(spec)r) 4 | __file__ = %(dev_path)r 5 | with open(__file__) as f: 6 | exec(compile(f.read(), __file__, 'exec')) 7 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/script.tmpl: -------------------------------------------------------------------------------- 1 | # EASY-INSTALL-SCRIPT: %(spec)r,%(script_name)r 2 | __requires__ = %(spec)r 3 | __import__('pkg_resources').run_script(%(spec)r, %(script_name)r) 4 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/site-patch.py: -------------------------------------------------------------------------------- 1 | def __boot(): 2 | import sys 3 | import os 4 | PYTHONPATH = os.environ.get('PYTHONPATH') 5 | if PYTHONPATH is None or (sys.platform == 'win32' and not PYTHONPATH): 6 | PYTHONPATH = [] 7 | else: 8 | PYTHONPATH = PYTHONPATH.split(os.pathsep) 9 | 10 | pic = getattr(sys, 'path_importer_cache', {}) 11 | stdpath = sys.path[len(PYTHONPATH):] 12 | mydir = os.path.dirname(__file__) 13 | 14 | for item in stdpath: 15 | if item == mydir or not item: 16 | continue # skip if current dir. on Windows, or my own directory 17 | importer = pic.get(item) 18 | if importer is not None: 19 | loader = importer.find_module('site') 20 | if loader is not None: 21 | # This should actually reload the current module 22 | loader.load_module('site') 23 | break 24 | else: 25 | try: 26 | import imp # Avoid import loop in Python 3 27 | stream, path, descr = imp.find_module('site', [item]) 28 | except ImportError: 29 | continue 30 | if stream is None: 31 | continue 32 | try: 33 | # This should actually reload the current module 34 | imp.load_module('site', stream, path, descr) 35 | finally: 36 | stream.close() 37 | break 38 | else: 39 | raise ImportError("Couldn't find the real 'site' module") 40 | 41 | # 2.2 comp 42 | known_paths = dict([( 43 | makepath(item)[1], 1) for item in sys.path]) # noqa 44 | 45 | oldpos = getattr(sys, '__egginsert', 0) # save old insertion position 46 | sys.__egginsert = 0 # and reset the current one 47 | 48 | for item in PYTHONPATH: 49 | addsitedir(item) # noqa 50 | 51 | sys.__egginsert += oldpos # restore effective old position 52 | 53 | d, nd = makepath(stdpath[0]) # noqa 54 | insert_at = None 55 | new_path = [] 56 | 57 | for item in sys.path: 58 | p, np = makepath(item) # noqa 59 | 60 | if np == nd and insert_at is None: 61 | # We've hit the first 'system' path entry, so added entries go here 62 | insert_at = len(new_path) 63 | 64 | if np in known_paths or insert_at is None: 65 | new_path.append(item) 66 | else: 67 | # new path after the insert point, back-insert it 68 | new_path.insert(insert_at, item) 69 | insert_at += 1 70 | 71 | sys.path[:] = new_path 72 | 73 | 74 | if __name__ == 'site': 75 | __boot() 76 | del __boot 77 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/unicode_utils.py: -------------------------------------------------------------------------------- 1 | import unicodedata 2 | import sys 3 | 4 | from setuptools.extern import six 5 | 6 | 7 | # HFS Plus uses decomposed UTF-8 8 | def decompose(path): 9 | if isinstance(path, six.text_type): 10 | return unicodedata.normalize('NFD', path) 11 | try: 12 | path = path.decode('utf-8') 13 | path = unicodedata.normalize('NFD', path) 14 | path = path.encode('utf-8') 15 | except UnicodeError: 16 | pass # Not UTF-8 17 | return path 18 | 19 | 20 | def filesys_decode(path): 21 | """ 22 | Ensure that the given path is decoded, 23 | NONE when no expected encoding works 24 | """ 25 | 26 | if isinstance(path, six.text_type): 27 | return path 28 | 29 | fs_enc = sys.getfilesystemencoding() or 'utf-8' 30 | candidates = fs_enc, 'utf-8' 31 | 32 | for enc in candidates: 33 | try: 34 | return path.decode(enc) 35 | except UnicodeDecodeError: 36 | continue 37 | 38 | 39 | def try_encode(string, enc): 40 | "turn unicode encoding into a functional routine" 41 | try: 42 | return string.encode(enc) 43 | except UnicodeEncodeError: 44 | return None 45 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/version.py: -------------------------------------------------------------------------------- 1 | import pkg_resources 2 | 3 | try: 4 | __version__ = pkg_resources.get_distribution('setuptools').version 5 | except Exception: 6 | __version__ = 'unknown' 7 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/wheel.py: -------------------------------------------------------------------------------- 1 | """Wheels support.""" 2 | 3 | from distutils.util import get_platform 4 | from distutils import log 5 | import email 6 | import itertools 7 | import os 8 | import posixpath 9 | import re 10 | import zipfile 11 | 12 | import pkg_resources 13 | import setuptools 14 | from pkg_resources import parse_version 15 | from setuptools.extern.packaging.tags import sys_tags 16 | from setuptools.extern.packaging.utils import canonicalize_name 17 | from setuptools.extern.six import PY3 18 | from setuptools.command.egg_info import write_requirements 19 | 20 | 21 | __metaclass__ = type 22 | 23 | 24 | WHEEL_NAME = re.compile( 25 | r"""^(?P.+?)-(?P\d.*?) 26 | ((-(?P\d.*?))?-(?P.+?)-(?P.+?)-(?P.+?) 27 | )\.whl$""", 28 | re.VERBOSE).match 29 | 30 | NAMESPACE_PACKAGE_INIT = '''\ 31 | try: 32 | __import__('pkg_resources').declare_namespace(__name__) 33 | except ImportError: 34 | __path__ = __import__('pkgutil').extend_path(__path__, __name__) 35 | ''' 36 | 37 | 38 | def unpack(src_dir, dst_dir): 39 | '''Move everything under `src_dir` to `dst_dir`, and delete the former.''' 40 | for dirpath, dirnames, filenames in os.walk(src_dir): 41 | subdir = os.path.relpath(dirpath, src_dir) 42 | for f in filenames: 43 | src = os.path.join(dirpath, f) 44 | dst = os.path.join(dst_dir, subdir, f) 45 | os.renames(src, dst) 46 | for n, d in reversed(list(enumerate(dirnames))): 47 | src = os.path.join(dirpath, d) 48 | dst = os.path.join(dst_dir, subdir, d) 49 | if not os.path.exists(dst): 50 | # Directory does not exist in destination, 51 | # rename it and prune it from os.walk list. 52 | os.renames(src, dst) 53 | del dirnames[n] 54 | # Cleanup. 55 | for dirpath, dirnames, filenames in os.walk(src_dir, topdown=True): 56 | assert not filenames 57 | os.rmdir(dirpath) 58 | 59 | 60 | class Wheel: 61 | 62 | def __init__(self, filename): 63 | match = WHEEL_NAME(os.path.basename(filename)) 64 | if match is None: 65 | raise ValueError('invalid wheel name: %r' % filename) 66 | self.filename = filename 67 | for k, v in match.groupdict().items(): 68 | setattr(self, k, v) 69 | 70 | def tags(self): 71 | '''List tags (py_version, abi, platform) supported by this wheel.''' 72 | return itertools.product( 73 | self.py_version.split('.'), 74 | self.abi.split('.'), 75 | self.platform.split('.'), 76 | ) 77 | 78 | def is_compatible(self): 79 | '''Is the wheel is compatible with the current platform?''' 80 | supported_tags = set( 81 | (t.interpreter, t.abi, t.platform) for t in sys_tags()) 82 | return next((True for t in self.tags() if t in supported_tags), False) 83 | 84 | def egg_name(self): 85 | return pkg_resources.Distribution( 86 | project_name=self.project_name, version=self.version, 87 | platform=(None if self.platform == 'any' else get_platform()), 88 | ).egg_name() + '.egg' 89 | 90 | def get_dist_info(self, zf): 91 | # find the correct name of the .dist-info dir in the wheel file 92 | for member in zf.namelist(): 93 | dirname = posixpath.dirname(member) 94 | if (dirname.endswith('.dist-info') and 95 | canonicalize_name(dirname).startswith( 96 | canonicalize_name(self.project_name))): 97 | return dirname 98 | raise ValueError("unsupported wheel format. .dist-info not found") 99 | 100 | def install_as_egg(self, destination_eggdir): 101 | '''Install wheel as an egg directory.''' 102 | with zipfile.ZipFile(self.filename) as zf: 103 | self._install_as_egg(destination_eggdir, zf) 104 | 105 | def _install_as_egg(self, destination_eggdir, zf): 106 | dist_basename = '%s-%s' % (self.project_name, self.version) 107 | dist_info = self.get_dist_info(zf) 108 | dist_data = '%s.data' % dist_basename 109 | egg_info = os.path.join(destination_eggdir, 'EGG-INFO') 110 | 111 | self._convert_metadata(zf, destination_eggdir, dist_info, egg_info) 112 | self._move_data_entries(destination_eggdir, dist_data) 113 | self._fix_namespace_packages(egg_info, destination_eggdir) 114 | 115 | @staticmethod 116 | def _convert_metadata(zf, destination_eggdir, dist_info, egg_info): 117 | def get_metadata(name): 118 | with zf.open(posixpath.join(dist_info, name)) as fp: 119 | value = fp.read().decode('utf-8') if PY3 else fp.read() 120 | return email.parser.Parser().parsestr(value) 121 | 122 | wheel_metadata = get_metadata('WHEEL') 123 | # Check wheel format version is supported. 124 | wheel_version = parse_version(wheel_metadata.get('Wheel-Version')) 125 | wheel_v1 = ( 126 | parse_version('1.0') <= wheel_version < parse_version('2.0dev0') 127 | ) 128 | if not wheel_v1: 129 | raise ValueError( 130 | 'unsupported wheel format version: %s' % wheel_version) 131 | # Extract to target directory. 132 | os.mkdir(destination_eggdir) 133 | zf.extractall(destination_eggdir) 134 | # Convert metadata. 135 | dist_info = os.path.join(destination_eggdir, dist_info) 136 | dist = pkg_resources.Distribution.from_location( 137 | destination_eggdir, dist_info, 138 | metadata=pkg_resources.PathMetadata(destination_eggdir, dist_info), 139 | ) 140 | 141 | # Note: Evaluate and strip markers now, 142 | # as it's difficult to convert back from the syntax: 143 | # foobar; "linux" in sys_platform and extra == 'test' 144 | def raw_req(req): 145 | req.marker = None 146 | return str(req) 147 | install_requires = list(sorted(map(raw_req, dist.requires()))) 148 | extras_require = { 149 | extra: sorted( 150 | req 151 | for req in map(raw_req, dist.requires((extra,))) 152 | if req not in install_requires 153 | ) 154 | for extra in dist.extras 155 | } 156 | os.rename(dist_info, egg_info) 157 | os.rename( 158 | os.path.join(egg_info, 'METADATA'), 159 | os.path.join(egg_info, 'PKG-INFO'), 160 | ) 161 | setup_dist = setuptools.Distribution( 162 | attrs=dict( 163 | install_requires=install_requires, 164 | extras_require=extras_require, 165 | ), 166 | ) 167 | # Temporarily disable info traces. 168 | log_threshold = log._global_log.threshold 169 | log.set_threshold(log.WARN) 170 | try: 171 | write_requirements( 172 | setup_dist.get_command_obj('egg_info'), 173 | None, 174 | os.path.join(egg_info, 'requires.txt'), 175 | ) 176 | finally: 177 | log.set_threshold(log_threshold) 178 | 179 | @staticmethod 180 | def _move_data_entries(destination_eggdir, dist_data): 181 | """Move data entries to their correct location.""" 182 | dist_data = os.path.join(destination_eggdir, dist_data) 183 | dist_data_scripts = os.path.join(dist_data, 'scripts') 184 | if os.path.exists(dist_data_scripts): 185 | egg_info_scripts = os.path.join( 186 | destination_eggdir, 'EGG-INFO', 'scripts') 187 | os.mkdir(egg_info_scripts) 188 | for entry in os.listdir(dist_data_scripts): 189 | # Remove bytecode, as it's not properly handled 190 | # during easy_install scripts install phase. 191 | if entry.endswith('.pyc'): 192 | os.unlink(os.path.join(dist_data_scripts, entry)) 193 | else: 194 | os.rename( 195 | os.path.join(dist_data_scripts, entry), 196 | os.path.join(egg_info_scripts, entry), 197 | ) 198 | os.rmdir(dist_data_scripts) 199 | for subdir in filter(os.path.exists, ( 200 | os.path.join(dist_data, d) 201 | for d in ('data', 'headers', 'purelib', 'platlib') 202 | )): 203 | unpack(subdir, destination_eggdir) 204 | if os.path.exists(dist_data): 205 | os.rmdir(dist_data) 206 | 207 | @staticmethod 208 | def _fix_namespace_packages(egg_info, destination_eggdir): 209 | namespace_packages = os.path.join( 210 | egg_info, 'namespace_packages.txt') 211 | if os.path.exists(namespace_packages): 212 | with open(namespace_packages) as fp: 213 | namespace_packages = fp.read().split() 214 | for mod in namespace_packages: 215 | mod_dir = os.path.join(destination_eggdir, *mod.split('.')) 216 | mod_init = os.path.join(mod_dir, '__init__.py') 217 | if not os.path.exists(mod_dir): 218 | os.mkdir(mod_dir) 219 | if not os.path.exists(mod_init): 220 | with open(mod_init, 'w') as fp: 221 | fp.write(NAMESPACE_PACKAGE_INIT) 222 | -------------------------------------------------------------------------------- /.eggs/setuptools-46.0.0-py3.6.egg/setuptools/windows_support.py: -------------------------------------------------------------------------------- 1 | import platform 2 | import ctypes 3 | 4 | 5 | def windows_only(func): 6 | if platform.system() != 'Windows': 7 | return lambda *args, **kwargs: None 8 | return func 9 | 10 | 11 | @windows_only 12 | def hide_file(path): 13 | """ 14 | Set the hidden attribute on a file or directory. 15 | 16 | From http://stackoverflow.com/questions/19622133/ 17 | 18 | `path` must be text. 19 | """ 20 | __import__('ctypes.wintypes') 21 | SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW 22 | SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD 23 | SetFileAttributes.restype = ctypes.wintypes.BOOL 24 | 25 | FILE_ATTRIBUTE_HIDDEN = 0x02 26 | 27 | ret = SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN) 28 | if not ret: 29 | raise ctypes.WinError() 30 | -------------------------------------------------------------------------------- /.github/workflows/pythonpackage.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions 3 | 4 | name: Python package 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | python-version: [3.5, 3.6, 3.7, 3.8] 19 | 20 | steps: 21 | - uses: actions/checkout@v2 22 | - name: Set up Python ${{ matrix.python-version }} 23 | uses: actions/setup-python@v1 24 | with: 25 | python-version: ${{ matrix.python-version }} 26 | - name: Install dependencies 27 | run: | 28 | python -m pip install --upgrade pip 29 | pip install flake8 pytest 30 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 31 | - name: Lint with flake8 32 | run: | 33 | # stop the build if there are Python syntax errors or undefined names 34 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 35 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 36 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 37 | - name: Test with pytest 38 | run: | 39 | pytest 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | .idea 3 | simpledorff.egg-info -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 LightTag 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SimpleDorff - Calculate Krippendorff's Alpha on a DataFrame 2 | 3 | Krippendorff's Alpha is a commonly used inter-annotator reliability metric, but it's hard to calculate on a Dataframe. This package makes it easy. 4 | 5 | Made with ❤️ by [LightTag - The Text Annotation Tool For Teams](https://lighttag.io). We use this in production to give our customers a single number to understand the quality of their labeled data. Read the [blog post here](https://lighttag.io/blog/krippendorffs-alpha/) 6 | 7 | ## Problem It Solves 8 | 9 | Calculating Krippendorff's Alpha assumes data is formatted in a way that just doesn't appear in the wild. We wanted a package that could read a Dataframe in the formats we see in real life and give us the Alpha in one line. 10 | 11 | ## Installing 12 | ```bash 13 | pip install simpledorff 14 | ``` 15 | 16 | ## Usage 17 | 18 | 19 | ```python 20 | 21 | ``` 22 | 23 | 24 | ```python 25 | import simpledorff 26 | import pandas as pd 27 | Data = pd.read_csv('./examples/from_paper.csv') #Load Your Dataframe 28 | Data.head() 29 | ``` 30 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
Unnamed: 0document_idannotator_idannotation
001A1.0
111B1.0
221D1.0
331CNaN
442A2.0
83 |
84 | 85 | 86 | 87 | 88 | ```python 89 | simpledorff.calculate_krippendorffs_alpha_for_df(Data,experiment_col='document_id', 90 | annotator_col='annotator_id', 91 | class_col='annotation') 92 | ``` 93 | 94 | 95 | 96 | 97 | 0.743421052631579 98 | 99 | 100 | -------------------------------------------------------------------------------- /build/lib/simpledorff/__init__.py: -------------------------------------------------------------------------------- 1 | from .simpledorff import calculate_krippendorffs_alpha_for_df, calculate_krippendorffs_alpha 2 | 3 | -------------------------------------------------------------------------------- /build/lib/simpledorff/data_transforms.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | from collections import Counter 3 | 4 | 5 | def df_to_experiment_annotator_table(df, experiment_col, annotator_col, class_col): 6 | """ 7 | 8 | :param df: A Dataframe we wish to transform with that contains the response of an annotator to an experiment 9 | | | document_id | annotator_id | annotation | 10 | |---:|--------------:|:---------------|-------------:| 11 | | 0 | 1 | A | 1 | 12 | | 1 | 1 | B | 1 | 13 | | 2 | 1 | D | 1 | 14 | | 4 | 2 | A | 2 | 15 | | 5 | 2 | B | 2 | 16 | 17 | :param experiment_col: The column name that contains the experiment (unit) 18 | :param annotator_col: The column name that identifies an annotator 19 | :param class_col: The column name that identifies the annotators response (class) 20 | :return: A dataframe indexed by annotators, with experiments as columns and the responses in the cells 21 | | annotator_id | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 22 | |:---------------|----:|----:|----:|----:|----:|----:|----:|----:|----:|-----:|-----:|-----:| 23 | | A | 1 | 2 | 3 | 3 | 2 | 1 | 4 | 1 | 2 | nan | nan | nan | 24 | | B | 1 | 2 | 3 | 3 | 2 | 2 | 4 | 1 | 2 | 5 | nan | 3 | 25 | | C | nan | 3 | 3 | 3 | 2 | 3 | 4 | 2 | 2 | 5 | 1 | nan | 26 | | D | 1 | 2 | 3 | 3 | 2 | 4 | 4 | 1 | 2 | 5 | 1 | nan | 27 | 28 | """ 29 | return df.pivot_table( 30 | index=annotator_col, columns=experiment_col, values=class_col, aggfunc="first" 31 | ) 32 | 33 | 34 | def make_value_by_unit_table_dict(experiment_annotator_df): 35 | """ 36 | 37 | :param experiment_annotator_df: A dataframe that came out of df_to_experiment_annotator_table 38 | :return: A dictionary of dictionaries (e.g. a table) whose rows (first level) are experiments and columns are responses 39 | {1: Counter({1.0: 1}), 40 | 2: Counter(), 41 | 3: Counter({2.0: 2}), 42 | 4: Counter({1.0: 2}), 43 | 5: Counter({3.0: 2}), 44 | """ 45 | data_by_exp = experiment_annotator_df.T.sort_index(axis=1).sort_index() 46 | table_dict = {} 47 | for exp, row in data_by_exp.iterrows(): 48 | vals = row.dropna().values 49 | table_dict[exp] = Counter() 50 | for val in vals: 51 | table_dict[exp][val] += 1 52 | return table_dict 53 | 54 | 55 | def calculate_frequency_dicts(vbu_table_dict): 56 | """ 57 | 58 | :param vbu_table_dict: A value by unit table dictionary, the output of make_value_by_unit_table_dict 59 | :return: A dictionary of dictonaries 60 | { 61 | unit_freqs:{ 1:2..}, 62 | class_freqs:{ 3:4..}, 63 | total:7 64 | } 65 | """ 66 | vbu_df = ( 67 | pd.DataFrame.from_dict(vbu_table_dict, orient="index") 68 | .T.sort_index(axis=0) 69 | .sort_index(axis=1) 70 | .fillna(0) 71 | ) 72 | ubv_df = vbu_df.T 73 | vbu_df_masked = ubv_df.mask(ubv_df.sum(1) == 1, other=0).T 74 | return dict( 75 | unit_freqs=vbu_df_masked.sum().to_dict(), 76 | class_freqs=vbu_df_masked.sum(1).to_dict(), 77 | total=vbu_df_masked.sum().sum(), 78 | ) 79 | -------------------------------------------------------------------------------- /build/lib/simpledorff/metrics.py: -------------------------------------------------------------------------------- 1 | def nominal_metric(x, y): 2 | return 1 if x != y else 0 3 | def interval_metric(x,y): 4 | return (x-y)**2 -------------------------------------------------------------------------------- /build/lib/simpledorff/simpledorff.py: -------------------------------------------------------------------------------- 1 | from simpledorff import data_transforms 2 | from simpledorff.metrics import nominal_metric 3 | 4 | 5 | def calculate_de(frequency_dicts, metric_fn): 6 | """ 7 | Calculates the expected disagreement by chance 8 | :param frequency_dicts: The output of data_transforms.calculate_frequency_dicts e.g.: 9 | { 10 | unit_freqs:{ 1:2..}, 11 | class_freqs:{ 3:4..}, 12 | total:7 13 | } 14 | :param metric_fn metric function such as nominal_metric 15 | :return: De a float 16 | """ 17 | De = 0 18 | class_freqs = frequency_dicts["class_freqs"] 19 | class_names = list(class_freqs.keys()) 20 | for i, c in enumerate(class_names): 21 | for k in class_names: 22 | De += class_freqs[c] * class_freqs[k] * metric_fn(c, k) 23 | return De 24 | 25 | 26 | def calculate_do(vbu_table_dict, frequency_dicts, metric_fn): 27 | """ 28 | 29 | :param vbu_table_dict: Output of data_transforms.make_value_by_unit_table_dict 30 | :param frequency_dicts: The output of data_transforms.calculate_frequency_dicts e.g.: 31 | { 32 | unit_freqs:{ 1:2..}, 33 | class_freqs:{ 3:4..}, 34 | total:7 35 | } 36 | :param metric_fn: metric_fn metric function such as nominal_metric 37 | :return: Do a float 38 | """ 39 | Do = 0 40 | unit_freqs = frequency_dicts["unit_freqs"] 41 | unit_ids = list(unit_freqs.keys()) 42 | for unit_id in unit_ids: 43 | unit_classes = list(vbu_table_dict[unit_id].keys()) 44 | if unit_freqs[unit_id] < 2: 45 | pass 46 | else: 47 | weight = 1 / (unit_freqs[unit_id] - 1) 48 | for i, c in enumerate(unit_classes): 49 | for k in unit_classes: 50 | Do += ( 51 | vbu_table_dict[unit_id][c] 52 | * vbu_table_dict[unit_id][k] 53 | * weight 54 | * metric_fn(c, k) 55 | ) 56 | return Do 57 | 58 | 59 | def calculate_krippendorffs_alpha(ea_table_df, metric_fn=nominal_metric): 60 | """ 61 | 62 | :param ea_table_df: The Experiment/Annotator table, output from data_transforms.df_to_experiment_annotator_table 63 | :param metric_fn: The metric function. Defaults to nominal 64 | :return: Alpha, a float 65 | """ 66 | vbu_table_dict = data_transforms.make_value_by_unit_table_dict(ea_table_df) 67 | frequency_dict = data_transforms.calculate_frequency_dicts(vbu_table_dict) 68 | observed_disagreement = calculate_do( 69 | vbu_table_dict=vbu_table_dict, 70 | frequency_dicts=frequency_dict, 71 | metric_fn=metric_fn, 72 | ) 73 | expected_disagreement = calculate_de( 74 | frequency_dicts=frequency_dict, metric_fn=metric_fn 75 | ) 76 | N = frequency_dict['total'] 77 | alpha = 1 - (observed_disagreement / expected_disagreement)*(N-1) 78 | return alpha 79 | 80 | 81 | def calculate_krippendorffs_alpha_for_df( 82 | df, experiment_col, annotator_col, class_col, metric_fn=nominal_metric 83 | ): 84 | """ 85 | 86 | :param df: A Dataframe we wish to transform with that contains the response of an annotator to an experiment 87 | | | document_id | annotator_id | annotation | 88 | |---:|--------------:|:---------------|-------------:| 89 | | 0 | 1 | A | 1 | 90 | | 1 | 1 | B | 1 | 91 | | 2 | 1 | D | 1 | 92 | | 4 | 2 | A | 2 | 93 | | 5 | 2 | B | 2 | 94 | 95 | :param experiment_col: The column name that contains the experiment (unit) 96 | :param annotator_col: The column name that identifies an annotator 97 | :param class_col: The column name that identifies the annotators response (class) 98 | :return: Alpha, a float 99 | 100 | """ 101 | ea_table_df = data_transforms.df_to_experiment_annotator_table( 102 | df, 103 | experiment_col=experiment_col, 104 | annotator_col=annotator_col, 105 | class_col=class_col, 106 | ) 107 | return calculate_krippendorffs_alpha(ea_table_df=ea_table_df, metric_fn=metric_fn) 108 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("README.md", "r") as fh: 4 | long_description = fh.read() 5 | 6 | setuptools.setup( 7 | name="simpledorff", # Replace with your own username 8 | version="0.0.2", 9 | author="Tal Perry", 10 | author_email="tal@lighttag.io", 11 | description="Calculate Krippendorff's Alpha on any DataFrame", 12 | long_description=long_description, 13 | long_description_content_type="text/markdown", 14 | url="https://github.com/lighttag/simpledorff", 15 | packages=setuptools.find_packages(), 16 | classifiers=[ 17 | "Programming Language :: Python :: 3", 18 | "License :: OSI Approved :: MIT License", 19 | "Operating System :: OS Independent", 20 | ], 21 | # python_requires='>=3.6', 22 | # setup_requires=["setuptools~=46.0.0"] 23 | ) 24 | -------------------------------------------------------------------------------- /simpledorff/__init__.py: -------------------------------------------------------------------------------- 1 | from .simpledorff import calculate_krippendorffs_alpha_for_df, calculate_krippendorffs_alpha 2 | 3 | -------------------------------------------------------------------------------- /simpledorff/data_transforms.py: -------------------------------------------------------------------------------- 1 | import pandas as pd 2 | from collections import Counter 3 | 4 | 5 | def df_to_experiment_annotator_table(df, experiment_col, annotator_col, class_col): 6 | """ 7 | 8 | :param df: A Dataframe we wish to transform with that contains the response of an annotator to an experiment 9 | | | document_id | annotator_id | annotation | 10 | |---:|--------------:|:---------------|-------------:| 11 | | 0 | 1 | A | 1 | 12 | | 1 | 1 | B | 1 | 13 | | 2 | 1 | D | 1 | 14 | | 4 | 2 | A | 2 | 15 | | 5 | 2 | B | 2 | 16 | 17 | :param experiment_col: The column name that contains the experiment (unit) 18 | :param annotator_col: The column name that identifies an annotator 19 | :param class_col: The column name that identifies the annotators response (class) 20 | :return: A dataframe indexed by annotators, with experiments as columns and the responses in the cells 21 | | annotator_id | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 22 | |:---------------|----:|----:|----:|----:|----:|----:|----:|----:|----:|-----:|-----:|-----:| 23 | | A | 1 | 2 | 3 | 3 | 2 | 1 | 4 | 1 | 2 | nan | nan | nan | 24 | | B | 1 | 2 | 3 | 3 | 2 | 2 | 4 | 1 | 2 | 5 | nan | 3 | 25 | | C | nan | 3 | 3 | 3 | 2 | 3 | 4 | 2 | 2 | 5 | 1 | nan | 26 | | D | 1 | 2 | 3 | 3 | 2 | 4 | 4 | 1 | 2 | 5 | 1 | nan | 27 | 28 | """ 29 | return df.pivot_table( 30 | index=annotator_col, columns=experiment_col, values=class_col, aggfunc="first" 31 | ) 32 | 33 | 34 | def make_value_by_unit_table_dict(experiment_annotator_df): 35 | """ 36 | 37 | :param experiment_annotator_df: A dataframe that came out of df_to_experiment_annotator_table 38 | :return: A dictionary of dictionaries (e.g. a table) whose rows (first level) are experiments and columns are responses 39 | {1: Counter({1.0: 1}), 40 | 2: Counter(), 41 | 3: Counter({2.0: 2}), 42 | 4: Counter({1.0: 2}), 43 | 5: Counter({3.0: 2}), 44 | """ 45 | data_by_exp = experiment_annotator_df.T.sort_index(axis=1).sort_index() 46 | table_dict = {} 47 | for exp, row in data_by_exp.iterrows(): 48 | vals = row.dropna().values 49 | table_dict[exp] = Counter() 50 | for val in vals: 51 | table_dict[exp][val] += 1 52 | return table_dict 53 | 54 | 55 | def calculate_frequency_dicts(vbu_table_dict): 56 | """ 57 | 58 | :param vbu_table_dict: A value by unit table dictionary, the output of make_value_by_unit_table_dict 59 | :return: A dictionary of dictonaries 60 | { 61 | unit_freqs:{ 1:2..}, 62 | class_freqs:{ 3:4..}, 63 | total:7 64 | } 65 | """ 66 | vbu_df = ( 67 | pd.DataFrame.from_dict(vbu_table_dict, orient="index") 68 | .T.sort_index(axis=0) 69 | .sort_index(axis=1) 70 | .fillna(0) 71 | ) 72 | ubv_df = vbu_df.T 73 | vbu_df_masked = ubv_df.mask(ubv_df.sum(1) == 1, other=0).T 74 | return dict( 75 | unit_freqs=vbu_df_masked.sum().to_dict(), 76 | class_freqs=vbu_df_masked.sum(1).to_dict(), 77 | total=vbu_df_masked.sum().sum(), 78 | ) 79 | -------------------------------------------------------------------------------- /simpledorff/metrics.py: -------------------------------------------------------------------------------- 1 | def nominal_metric(x, y): 2 | return 1 if x != y else 0 3 | def interval_metric(x,y): 4 | return (x-y)**2 -------------------------------------------------------------------------------- /simpledorff/simpledorff.py: -------------------------------------------------------------------------------- 1 | from simpledorff import data_transforms 2 | from simpledorff.metrics import nominal_metric 3 | 4 | 5 | def calculate_de(frequency_dicts, metric_fn): 6 | """ 7 | Calculates the expected disagreement by chance 8 | :param frequency_dicts: The output of data_transforms.calculate_frequency_dicts e.g.: 9 | { 10 | unit_freqs:{ 1:2..}, 11 | class_freqs:{ 3:4..}, 12 | total:7 13 | } 14 | :param metric_fn metric function such as nominal_metric 15 | :return: De a float 16 | """ 17 | De = 0 18 | class_freqs = frequency_dicts["class_freqs"] 19 | class_names = list(class_freqs.keys()) 20 | for i, c in enumerate(class_names): 21 | for k in class_names: 22 | De += class_freqs[c] * class_freqs[k] * metric_fn(c, k) 23 | return De 24 | 25 | 26 | def calculate_do(vbu_table_dict, frequency_dicts, metric_fn): 27 | """ 28 | 29 | :param vbu_table_dict: Output of data_transforms.make_value_by_unit_table_dict 30 | :param frequency_dicts: The output of data_transforms.calculate_frequency_dicts e.g.: 31 | { 32 | unit_freqs:{ 1:2..}, 33 | class_freqs:{ 3:4..}, 34 | total:7 35 | } 36 | :param metric_fn: metric_fn metric function such as nominal_metric 37 | :return: Do a float 38 | """ 39 | Do = 0 40 | unit_freqs = frequency_dicts["unit_freqs"] 41 | unit_ids = list(unit_freqs.keys()) 42 | for unit_id in unit_ids: 43 | unit_classes = list(vbu_table_dict[unit_id].keys()) 44 | if unit_freqs[unit_id] < 2: 45 | pass 46 | else: 47 | weight = 1 / (unit_freqs[unit_id] - 1) 48 | for i, c in enumerate(unit_classes): 49 | for k in unit_classes: 50 | Do += ( 51 | vbu_table_dict[unit_id][c] 52 | * vbu_table_dict[unit_id][k] 53 | * weight 54 | * metric_fn(c, k) 55 | ) 56 | return Do 57 | 58 | 59 | def calculate_krippendorffs_alpha(ea_table_df, metric_fn=nominal_metric): 60 | """ 61 | 62 | :param ea_table_df: The Experiment/Annotator table, output from data_transforms.df_to_experiment_annotator_table 63 | :param metric_fn: The metric function. Defaults to nominal 64 | :return: Alpha, a float 65 | """ 66 | vbu_table_dict = data_transforms.make_value_by_unit_table_dict(ea_table_df) 67 | frequency_dict = data_transforms.calculate_frequency_dicts(vbu_table_dict) 68 | observed_disagreement = calculate_do( 69 | vbu_table_dict=vbu_table_dict, 70 | frequency_dicts=frequency_dict, 71 | metric_fn=metric_fn, 72 | ) 73 | expected_disagreement = calculate_de( 74 | frequency_dicts=frequency_dict, metric_fn=metric_fn 75 | ) 76 | N = frequency_dict['total'] 77 | alpha = 1 - (observed_disagreement / expected_disagreement)*(N-1) 78 | return alpha 79 | 80 | 81 | def calculate_krippendorffs_alpha_for_df( 82 | df, experiment_col, annotator_col, class_col, metric_fn=nominal_metric 83 | ): 84 | """ 85 | 86 | :param df: A Dataframe we wish to transform with that contains the response of an annotator to an experiment 87 | | | document_id | annotator_id | annotation | 88 | |---:|--------------:|:---------------|-------------:| 89 | | 0 | 1 | A | 1 | 90 | | 1 | 1 | B | 1 | 91 | | 2 | 1 | D | 1 | 92 | | 4 | 2 | A | 2 | 93 | | 5 | 2 | B | 2 | 94 | 95 | :param experiment_col: The column name that contains the experiment (unit) 96 | :param annotator_col: The column name that identifies an annotator 97 | :param class_col: The column name that identifies the annotators response (class) 98 | :return: Alpha, a float 99 | 100 | """ 101 | ea_table_df = data_transforms.df_to_experiment_annotator_table( 102 | df, 103 | experiment_col=experiment_col, 104 | annotator_col=annotator_col, 105 | class_col=class_col, 106 | ) 107 | return calculate_krippendorffs_alpha(ea_table_df=ea_table_df, metric_fn=metric_fn) 108 | -------------------------------------------------------------------------------- /tests/_trial_temp/_trial_marker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LightTag/simpledorff/395c2dc0cac30ab29c02fb95086a1ed478bdbb14/tests/_trial_temp/_trial_marker -------------------------------------------------------------------------------- /tests/_trial_temp/test.log: -------------------------------------------------------------------------------- 1 | 2020-05-04 10:30:03+0200 [-] Log opened. 2 | -------------------------------------------------------------------------------- /tests/test_simpledorff.py: -------------------------------------------------------------------------------- 1 | from unittest import TestCase 2 | import pandas as pd 3 | import simpledorff 4 | from simpledorff import data_transforms, metrics 5 | from collections import Counter 6 | 7 | 8 | class TestWikiediaExample(TestCase): 9 | def setUp(self) -> None: 10 | # Setup test data based on https://en.wikipedia.org/wiki/Krippendorff%27s_alpha#A_computational_example 11 | columns = list(range(1, 16)) 12 | values = { 13 | "A": {6: 3, 7: 4, 8: 1, 9: 2, 10: 1, 11: 1, 12: 3, 13: 3, 15: 3}, 14 | "B": {1: 1, 3: 2, 4: 1, 5: 3, 6: 3, 7: 4, 8: 3}, 15 | "C": { 16 | 3: 2, 17 | 4: 1, 18 | 5: 3, 19 | 6: 4, 20 | 7: 4, 21 | 9: 2, 22 | 10: 1, 23 | 11: 1, 24 | 12: 3, 25 | 13: 3, 26 | 15: 4, 27 | }, 28 | } 29 | self.ea_table_df = pd.DataFrame.from_dict( 30 | values, columns=columns, orient="index" 31 | ) 32 | 33 | def test_calculate_krippendorffs_alpha_wikipedia_example_nominal(self): 34 | 35 | alpha = simpledorff.calculate_krippendorffs_alpha( 36 | self.ea_table_df, metric_fn=metrics.nominal_metric 37 | ) 38 | self.assertAlmostEqual(0.691, alpha, 3) 39 | 40 | def test_calculate_krippendorffs_alpha_wikipedia_example_interval(self): 41 | 42 | alpha = simpledorff.calculate_krippendorffs_alpha( 43 | self.ea_table_df, metric_fn=metrics.interval_metric 44 | ) 45 | self.assertAlmostEqual(0.811, alpha, 3) 46 | 47 | def test_make_vbu_table(self): 48 | vbu_table = data_transforms.make_value_by_unit_table_dict(self.ea_table_df) 49 | expected = { 50 | 1: Counter({1.0: 1}), 51 | 2: Counter(), 52 | 3: Counter({2.0: 2}), 53 | 4: Counter({1.0: 2}), 54 | 5: Counter({3.0: 2}), 55 | 6: Counter({3: 2, 4: 1}), 56 | 7: Counter({4: 3}), 57 | 8: Counter({1.0: 1, 3.0: 1}), 58 | 9: Counter({2.0: 2}), 59 | 10: Counter({1.0: 2}), 60 | 11: Counter({1.0: 2}), 61 | 12: Counter({3.0: 2}), 62 | 13: Counter({3.0: 2}), 63 | 14: Counter(), 64 | 15: Counter({3.0: 1, 4.0: 1}), 65 | } 66 | self.assertEqual(vbu_table, expected) 67 | 68 | def test_make_value_by_unit_table_dict(self): 69 | vbu_table = data_transforms.make_value_by_unit_table_dict(self.ea_table_df) 70 | result = data_transforms.calculate_frequency_dicts(vbu_table) 71 | expected = { 72 | "unit_freqs": { 73 | 1: 0.0, 74 | 3: 2.0, 75 | 4: 2.0, 76 | 5: 2.0, 77 | 6: 3.0, 78 | 7: 3.0, 79 | 8: 2.0, 80 | 9: 2.0, 81 | 10: 2.0, 82 | 11: 2.0, 83 | 12: 2.0, 84 | 13: 2.0, 85 | 15: 2.0, 86 | }, 87 | "class_freqs": {1.0: 7.0, 2.0: 4.0, 3.0: 10.0, 4.0: 5.0}, 88 | "total": 26.0, 89 | } 90 | for key in expected: 91 | self.assertEqual(expected[key], result[key], key) 92 | 93 | 94 | class TestPaperExample(TestCase): 95 | def setUp(self) -> None: 96 | # Setup test data based on section 3 https://a8h2w5y7.rocketcdn.me/wp-content/uploads/2016/07/fulltext.pdf 97 | columns = list(range(1, 13)) 98 | values = { 99 | "A": {1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 1, 7: 4, 8: 1, 9: 2}, 100 | "B": {1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 2, 7: 4, 8: 1, 9: 2, 10: 5, 12: 3}, 101 | "C": {2: 3, 3: 3, 4: 3, 5: 3, 5: 2, 6: 3, 7: 4, 8: 2, 9: 2, 10: 5, 11: 1}, 102 | "D": {1: 1, 2: 2, 3: 3, 4: 3, 5: 2, 6: 4, 7: 4, 8: 1, 9: 2, 10: 5, 11: 1}, 103 | } 104 | self.ea_table_df = pd.DataFrame.from_dict( 105 | values, columns=columns, orient="index" 106 | ) 107 | 108 | def test_calculate_krippendorffs_alpha_wikipedia_example_nominal(self): 109 | 110 | alpha = simpledorff.calculate_krippendorffs_alpha( 111 | self.ea_table_df, metric_fn=metrics.nominal_metric 112 | ) 113 | self.assertAlmostEqual(0.743, alpha, 3) 114 | 115 | def test_make_vbu_table(self): 116 | vbu_table = data_transforms.make_value_by_unit_table_dict(self.ea_table_df) 117 | expected = { 118 | 1: Counter({1.0: 3}), 119 | 2: Counter({2.0: 3, 3.0: 1}), 120 | 3: Counter({3.0: 4}), 121 | 4: Counter({3.0: 4}), 122 | 5: Counter({2.0: 4}), 123 | 6: Counter({1.0: 1, 2.0: 1, 3.0: 1, 4.0: 1}), 124 | 7: Counter({4.0: 4}), 125 | 8: Counter({1.0: 3, 2.0: 1}), 126 | 9: Counter({2.0: 4}), 127 | 10: Counter({5.0: 3}), 128 | 11: Counter({1.0: 2}), 129 | 12: Counter({3.0: 1}), 130 | } 131 | self.assertEqual(vbu_table, expected) 132 | 133 | def test_make_value_by_unit_table_dict(self): 134 | vbu_table = data_transforms.make_value_by_unit_table_dict(self.ea_table_df) 135 | result = data_transforms.calculate_frequency_dicts(vbu_table) 136 | expected = { 137 | "unit_freqs": { 138 | 1: 3.0, 139 | 2: 4.0, 140 | 3: 4.0, 141 | 4: 4.0, 142 | 5: 4.0, 143 | 6: 4.0, 144 | 7: 4.0, 145 | 8: 4.0, 146 | 9: 4.0, 147 | 10: 3.0, 148 | 11: 2.0, 149 | 12: 0.0, 150 | }, 151 | "class_freqs": {1.0: 9.0, 2.0: 13.0, 3.0: 10.0, 4.0: 5.0, 5.0: 3.0}, 152 | "total": 40.0, 153 | } 154 | for key in expected: 155 | self.assertEqual(expected[key], result[key], key) 156 | --------------------------------------------------------------------------------